SPI_Test/rtl/memory/sram_dmux.sv

106 lines
3.6 KiB
Systemverilog

/*
// module dmux
module sram_dmux_m #(
parameter ADDR_WIDTH_I = 11, // input port addr width
parameter ADDR_WIDTH_O = 10, // output port addr width
parameter DATA_WIDTH = 64 // in/output port data width
)(
input logic clk,
input logic rst_n,
sram_if.slave port_in,
sram_if.master port_out[2**(ADDR_WIDTH_I-ADDR_WIDTH_O)-1:0]
);
localparam ASEL_WIDTH = ADDR_WIDTH_I-ADDR_WIDTH_O;
logic [ASEL_WIDTH-1:0] data_sel, data_out_sel;
assign data_sel = port_in.addr[ADDR_WIDTH_I-1 : ADDR_WIDTH_O];
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
data_out_sel <= 0;
end else begin
data_out_sel <= data_sel;
end
end
logic [DATA_WIDTH-1:0] dout_data[2**(ASEL_WIDTH)-1:0];
genvar i;
generate
for (i = 0; i < 2**ASEL_WIDTH; i++) begin
assign port_out[i].addr = (i == data_sel) ? port_in.addr[ADDR_WIDTH_O-1:0] : 0;
assign port_out[i].wren = (i == data_sel) ? port_in.wren : 0;
assign port_out[i].rden = (i == data_sel) ? port_in.rden : 0;
assign port_out[i].din = (i == data_sel) ? port_in.din : 0;
assign port_out[i].wben = (i == data_sel) ? port_in.wben : 0;
assign dout_data[i]= port_out[i].dout;
end
endgenerate
assign port_in.dout = dout_data[data_out_sel];
endmodule
*/
// word dmux
module sram_dmux_w #(
parameter ADDR_WIDTH = 11, // input port addr width
parameter DATA_WIDTH_I = 32, // input port data width
parameter DATA_WIDTH_O = 64 // output port data width
)(
input logic clk,
input logic rst_n,
sram_if.slave port_in,
sram_if.master port_out
);
// calculate and buffer word select bit
localparam DL = $clog2(DATA_WIDTH_I/8);
localparam DH = $clog2(DATA_WIDTH_O/8);
localparam WSEL_WIDTH = DH - DL;
logic [WSEL_WIDTH-1:0] data_sel, data_out_sel;
assign data_sel = port_in.addr[DH-1:DL];
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
data_out_sel <= 0;
end else begin
data_out_sel <= data_sel;
end
end
//
assign port_out.addr = port_in.addr;
assign port_out.wren = port_in.wren;
assign port_out.rden = port_in.rden;
genvar i;
generate
for (i = 0; i < 2**(WSEL_WIDTH); i++) begin
assign port_out.din[DATA_WIDTH_I*i +: DATA_WIDTH_I] = (i == data_sel) ? port_in.din : 0;
assign port_out.wben[DATA_WIDTH_I/8*i +: DATA_WIDTH_I/8] = (i == data_sel) ? port_in.wben : 0;
end
endgenerate
assign port_in.dout = port_out.dout[DATA_WIDTH_I*data_out_sel +: DATA_WIDTH_I];
endmodule
/*
// data split
module sram_split #(
parameter ADDR_WIDTH = 11, // input port addr width
parameter DATA_WIDTH_I = 64, // input port data width
parameter DATA_WIDTH_O = 32 // output port data width
)(
sram_if.slave port_in,
sram_if.master port_out[DATA_WIDTH_I/DATA_WIDTH_O-1:0]
);
localparam DH = $clog2(DATA_WIDTH_I/8);
localparam DL = $clog2(DATA_WIDTH_O/8);
genvar i;
generate
for (i = 0; i < DATA_WIDTH_I/DATA_WIDTH_O; i++) begin
assign port_out[i].addr = {port_in.addr[ADDR_WIDTH-1:DH], {DL{1'b0}}};
assign port_out[i].rden = port_in.rden;
assign port_out[i].wren = port_in.wren;
assign port_out[i].din = port_in.din[i*DATA_WIDTH_O +: DATA_WIDTH_O];
assign port_out[i].wben = port_in.wben[i*DATA_WIDTH_O/8 +: DATA_WIDTH_O/8];
assign port_in.dout[i*DATA_WIDTH_O +: DATA_WIDTH_O] = port_out[i].dout;
end
endgenerate
endmodule
*/