SPI_Test/rtl/spi/spi_bus_decoder.sv

92 lines
3.5 KiB
Systemverilog

//+FHDR--------------------------------------------------------------------------------------------------------
// Company:
//-----------------------------------------------------------------------------------------------------------------
// File Name : spi_bus_decoder.v
// Department :
// Author : PWY
// Author's Tel :
//-----------------------------------------------------------------------------------------------------------------
// Relese History
// Version Date Author Description
// 0.1 2024-03-13 PWY Serial Peripheral Interface BUS Decoder
// 0.2 2024-06-15 PWY The slave interface address will be reduced from 25 bits to 20 bits.
//-----------------------------------------------------------------------------------------------------------------
// Keywords :
//
//-----------------------------------------------------------------------------------------------------------------
// Parameter
//
//-----------------------------------------------------------------------------------------------------------------
// Purpose :
//
//-----------------------------------------------------------------------------------------------------------------
// Target Device:
// Tool versions:
//-----------------------------------------------------------------------------------------------------------------
// Reuse Issues
// Reset Strategy:
// Clock Domains:
// Critical Timing:
// Asynchronous I/F:
// Synthesizable (y/n):
// Other:
//-FHDR--------------------------------------------------------------------------------------------------------
module spi_bus_decoder #(
parameter SLVNUM = 32
,parameter SPIBUS_CMD_REG = 1
,parameter SPIBUS_OUT_REG = 1
)(
input clk
,input rst_n
,sram_if.slave mst
,sram_if.master slv [SLVNUM-1:0] //s and m exchange
);
generate
genvar i;
logic [SLVNUM-1:0] cs_slv;
logic [31 :0] dtemp[SLVNUM-1:0];
for(i=0;i<SLVNUM;i=i+1) begin: MAIN
//generating device chip select signal
//the largest 5bit addr is used to select among 32 SRAM
assign cs_slv[i] = (mst.addr[24:20] == i );
//generating device read/write signal
if(SPIBUS_CMD_REG == 1) begin :CMD_REG
sirv_gnrl_dffr #(20) rwaddr_dffr ({20{cs_slv[i]}} & mst.addr[19:0] ,slv[i].addr, clk, rst_n);
sirv_gnrl_dffr #(32) wrdata_dffr ({32{cs_slv[i]}} & mst.din ,slv[i].din, clk, rst_n);
sirv_gnrl_dffr #(1) wren_dffr (cs_slv[i] & mst.wren ,slv[i].wren, clk, rst_n);
sirv_gnrl_dffr #(1) reen_dffr (cs_slv[i] & mst.rden ,slv[i].rden, clk, rst_n);
end
else begin :CMD_DONT_REG
assign slv[i].addr = {20{cs_slv[i]}} & mst.addr[19:0];
assign slv[i].wren = cs_slv[i] & mst.wren;
assign slv[i].rden = cs_slv[i] & mst.rden;
assign slv[i].din = {32{cs_slv[i]}} & mst.din;
end
assign slv[i].wben = {4{cs_slv[i]}} & mst.wben;
if(i==0) begin: DETMP0
assign dtemp[i] = (cs_slv[i]) ? slv[i].dout : 32'b0;
end
else begin: DETMP1_32
assign dtemp[i] = (cs_slv[i]) ? slv[i].dout : dtemp[i-1];
end
end
//read data from register
if(SPIBUS_OUT_REG == 1) begin :OUT_REG
wire [3:0] rden_dly;
sirv_gnrl_dffr #(4) rddata_dffr ({rden_dly[2:0],mst.rden}, rden_dly[3:0], clk, rst_n);
sirv_gnrl_dfflr #(32) rddata_dfflr (rden_dly[3],dtemp[SLVNUM-1], mst.dout, clk, rst_n);
end
else begin : OUT_DONT_REG
assign mst.dout = dtemp[SLVNUM-1];
end
endgenerate
endmodule