106 lines
3.6 KiB
Systemverilog
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
|
|
*/ |