// SPDX-License-Identifier: Apache-2.0 // Copyright 2019 Western Digital Corporation or its affiliates. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // module ahb_sif ( input logic [63:0] HWDATA, input logic HCLK, input logic HSEL, input logic [3:0] HPROT, input logic HWRITE, input logic [1:0] HTRANS, input logic [2:0] HSIZE, input logic HREADY, input logic HRESETn, input logic [31:0] HADDR, input logic [2:0] HBURST, output logic HREADYOUT, output logic HRESP, output logic [63:0] HRDATA ); localparam MEM_SIZE_DW = 8192; localparam MAILBOX_ADDR = 32'hD0580000; logic Last_HSEL; logic NextLast_HSEL; logic Last_HWRITE; logic [1:0] Last_HTRANS; logic [1:0] NextLast_HTRANS; logic [31:0] Last_HADDR; logic [63:0] Next_HRDATA; logic [63:0] WriteReadData; logic [63:0] WriteMask; bit [7:0] mem [0:MEM_SIZE_DW-1]; // Wires wire [63:0] Next_WriteMask = HSIZE == 3'b000 ? (64'hff << {HADDR[2:0], 3'b000}) : (HSIZE == 3'b001 ? (64'hffff << {HADDR[2], 4'h0}) : (HSIZE == 3'b010 ? (64'hffff_ffff << {HADDR[3],5'h0}) : 64'hffff_ffff_ffff_ffff)); wire [63:0] MaskedWriteData = HWDATA & WriteMask; wire [63:0] MaskedWriteReadData = WriteReadData & ~WriteMask; wire [63:0] WriteData = (MaskedWriteData | MaskedWriteReadData ); wire Write = &{Last_HSEL, Last_HWRITE, Last_HTRANS[1]}; wire Read = &{ HSEL, ~HWRITE, HTRANS[1]}; wire mailbox_write = &{Write, Last_HADDR==MAILBOX_ADDR, HRESETn==1}; wire Next_HWRITE = |{HTRANS} ? HWRITE : Last_HWRITE; wire [63:0] mem_dout = {mem[{Last_HADDR[12:3],3'b0}+7],mem[{Last_HADDR[12:3],3'b0}+6],mem[{Last_HADDR[12:3],3'b0}+5],mem[{Last_HADDR[12:3],3'b0}+4],mem[{Last_HADDR[12:3],3'b0}+3],mem[{Last_HADDR[12:3],3'b0}+2],mem[{Last_HADDR[12:3],3'b0}+1],mem[{Last_HADDR[12:3],3'b0}]}; always @ (posedge HCLK or negedge HRESETn) begin if (Write && Last_HADDR == 32'h0) begin mem[{Last_HADDR[12:3],3'b0}+7] <= #1 { WriteData[63:56] }; mem[{Last_HADDR[12:3],3'b0}+6] <= #1 { WriteData[55:48] }; mem[{Last_HADDR[12:3],3'b0}+5] <= #1 { WriteData[47:40] }; mem[{Last_HADDR[12:3],3'b0}+4] <= #1 { WriteData[39:32] }; mem[{Last_HADDR[12:3],3'b0}+3] <= #1 { WriteData[31:24] }; mem[{Last_HADDR[12:3],3'b0}+2] <= #1 { WriteData[23:16] }; mem[{Last_HADDR[12:3],3'b0}+1] <= #1 { WriteData[15:08] }; mem[{Last_HADDR[12:3],3'b0}+0] <= #1 { WriteData[07:00] }; end end always @(posedge HCLK or negedge HRESETn) begin if(~HRESETn) begin HREADYOUT <= #1 1'b0 ; HRESP <= #1 1'b0; end else begin HREADYOUT <= #1 |HTRANS; HRESP <= #1 1'b0; WriteMask <= #1 Next_WriteMask; end end `ifdef VERILATOR always @(posedge HCLK or negedge HRESETn) begin `else always @(negedge HCLK or negedge HRESETn) begin `endif if(~HRESETn) begin Last_HADDR <= #1 32'b0; end else begin Last_HADDR <= #1 |{HTRANS} ? {HADDR[31:2], 2'b00} : Last_HADDR; end end always @(posedge HCLK or negedge HRESETn) begin if(~HRESETn) begin Last_HWRITE <= #1 1'b0; end else begin Last_HWRITE <= #1 Next_HWRITE; end end always @(posedge HCLK or negedge HRESETn) begin if(~HRESETn) begin Last_HTRANS <= #1 2'b0; end else begin Last_HTRANS <= #1 HTRANS; end end always @(posedge HCLK or negedge HRESETn) begin if(~HRESETn) begin Last_HSEL <= #1 1'b0; end else begin Last_HSEL <= #1 HSEL; end end `ifndef VERILATOR always @(posedge HCLK or negedge HRESETn) begin if(~HRESETn) begin HRDATA <= #1 Next_HRDATA ; end else begin HRDATA <= #1 Next_HRDATA ; end end always @* begin Next_HRDATA = mem_dout; end `else always @(posedge HCLK) begin Next_HRDATA <= mem_dout; end assign HRDATA = mem_dout; `endif always @* begin if(Last_HSEL) begin WriteReadData[07:00] = mem[{Last_HADDR[12:3],3'b0}]; WriteReadData[15:08] = mem[{Last_HADDR[12:3],3'b0}+1]; WriteReadData[23:16] = mem[{Last_HADDR[12:3],3'b0}+2]; WriteReadData[31:24] = mem[{Last_HADDR[12:3],3'b0}+3]; WriteReadData[39:32] = mem[{Last_HADDR[12:3],3'b0}+4]; WriteReadData[47:40] = mem[{Last_HADDR[12:3],3'b0}+5]; WriteReadData[55:48] = mem[{Last_HADDR[12:3],3'b0}+6]; WriteReadData[63:56] = mem[{Last_HADDR[12:3],3'b0}+7]; end end endmodule