Skip to content

Commit

Permalink
Add passthrough mode for mem_to_banks with NumBanks==1
Browse files Browse the repository at this point in the history
  • Loading branch information
micprog committed Aug 20, 2024
1 parent c27bce3 commit c439813
Showing 1 changed file with 129 additions and 108 deletions.
237 changes: 129 additions & 108 deletions src/mem_to_banks_detailed.sv
Original file line number Diff line number Diff line change
Expand Up @@ -104,118 +104,139 @@ module mem_to_banks_detailed #(
logic we;
} req_t;

logic req_valid;
logic [NumBanks-1:0] req_ready,
resp_valid, resp_ready;
req_t [NumBanks-1:0] bank_req,
bank_oup;
logic [NumBanks-1:0] bank_req_internal,
bank_gnt_internal,
zero_strobe,
dead_response,
dead_response_unmasked;
logic dead_write_fifo_full,
dead_write_fifo_empty;

function automatic addr_t align_addr(input addr_t addr);
return (addr >> $clog2(DataBytes)) << $clog2(DataBytes);
endfunction

// Handle requests.
assign req_valid = req_i & gnt_o;
for (genvar i = 0; unsigned'(i) < NumBanks; i++) begin : gen_reqs
assign bank_req[i].addr = align_addr(addr_i) + i * BytesPerBank;
assign bank_req[i].wdata = wdata_i[i*BitsPerBank+:BitsPerBank];
assign bank_req[i].strb = strb_i[i*BytesPerBank+:BytesPerBank];
assign bank_req[i].wuser = wuser_i;
assign bank_req[i].we = we_i;
stream_fifo #(
.FALL_THROUGH ( 1'b1 ),
.DATA_WIDTH ( $bits(req_t) ),
.DEPTH ( FifoDepth ),
.T ( req_t )
) i_ft_reg (
.clk_i,
.rst_ni,
.flush_i ( 1'b0 ),
.testmode_i ( 1'b0 ),
.usage_o (),
.data_i ( bank_req[i] ),
.valid_i ( req_valid ),
.ready_o ( req_ready[i] ),
.data_o ( bank_oup[i] ),
.valid_o ( bank_req_internal[i] ),
.ready_i ( bank_gnt_internal[i] )
);
assign bank_addr_o[i] = bank_oup[i].addr;
assign bank_wdata_o[i] = bank_oup[i].wdata;
assign bank_strb_o[i] = bank_oup[i].strb;
assign bank_wuser_o[i] = bank_oup[i].wuser;
assign bank_we_o[i] = bank_oup[i].we;

assign zero_strobe[i] = (bank_req[i].strb == '0);

if (HideStrb) begin : gen_hide_strb
assign bank_req_o[i] = (bank_oup[i].we && (bank_oup[i].strb == '0)) ?
1'b0 : bank_req_internal[i];
assign bank_gnt_internal[i] = (bank_oup[i].we && (bank_oup[i].strb == '0)) ?
1'b1 : bank_gnt_i[i];
end else begin : gen_legacy_strb
assign bank_req_o[i] = bank_req_internal[i];
assign bank_gnt_internal[i] = bank_gnt_i[i];
if (NumBanks == 1) begin : gen_passthrough

// Simply connects passthrough.
// Does not provide HideStrb functionality.
// Removes unnecessary buffers in the design.

assign bank_req_o [0] = req_i;
assign gnt_o = bank_gnt_i [0];
assign bank_addr_o [0] = addr_i;
assign bank_wdata_o[0] = wdata_i;
assign bank_strb_o [0] = strb_i;
assign bank_wuser_o[0] = wuser_i;
assign bank_we_o [0] = we_i;
assign rvalid_o = bank_rvalid_i[0];
assign rdata_o = bank_rdata_i [0];
assign ruser_o [0] = bank_ruser_i [0];

end else begin : gen_banking

logic req_valid;
logic [NumBanks-1:0] req_ready,
resp_valid, resp_ready;
req_t [NumBanks-1:0] bank_req,
bank_oup;
logic [NumBanks-1:0] bank_req_internal,
bank_gnt_internal,
zero_strobe,
dead_response,
dead_response_unmasked;
logic dead_write_fifo_full,
dead_write_fifo_empty;

function automatic addr_t align_addr(input addr_t addr);
return (addr >> $clog2(DataBytes)) << $clog2(DataBytes);
endfunction

// Handle requests.
assign req_valid = req_i & gnt_o;
for (genvar i = 0; unsigned'(i) < NumBanks; i++) begin : gen_reqs
assign bank_req[i].addr = align_addr(addr_i) + i * BytesPerBank;
assign bank_req[i].wdata = wdata_i[i*BitsPerBank+:BitsPerBank];
assign bank_req[i].strb = strb_i[i*BytesPerBank+:BytesPerBank];
assign bank_req[i].wuser = wuser_i;
assign bank_req[i].we = we_i;
stream_fifo #(
.FALL_THROUGH ( 1'b1 ),
.DATA_WIDTH ( $bits(req_t) ),
.DEPTH ( FifoDepth ),
.T ( req_t )
) i_ft_reg (
.clk_i,
.rst_ni,
.flush_i ( 1'b0 ),
.testmode_i ( 1'b0 ),
.usage_o (),
.data_i ( bank_req[i] ),
.valid_i ( req_valid ),
.ready_o ( req_ready[i] ),
.data_o ( bank_oup[i] ),
.valid_o ( bank_req_internal[i] ),
.ready_i ( bank_gnt_internal[i] )
);
assign bank_addr_o[i] = bank_oup[i].addr;
assign bank_wdata_o[i] = bank_oup[i].wdata;
assign bank_strb_o[i] = bank_oup[i].strb;
assign bank_wuser_o[i] = bank_oup[i].wuser;
assign bank_we_o[i] = bank_oup[i].we;

assign zero_strobe[i] = (bank_req[i].strb == '0);

if (HideStrb) begin : gen_hide_strb
assign bank_req_o[i] = (bank_oup[i].we && (bank_oup[i].strb == '0)) ?
1'b0 : bank_req_internal[i];
assign bank_gnt_internal[i] = (bank_oup[i].we && (bank_oup[i].strb == '0)) ?
1'b1 : bank_gnt_i[i];
end else begin : gen_legacy_strb
assign bank_req_o[i] = bank_req_internal[i];
assign bank_gnt_internal[i] = bank_gnt_i[i];
end
end
end

// Grant output if all our requests have been granted.
assign gnt_o = (&req_ready) & (&resp_ready) & !dead_write_fifo_full;

if (HideStrb) begin : gen_dead_write_fifo
fifo_v3 #(
.FALL_THROUGH ( 1'b0 ),
.DEPTH ( MaxTrans+1 ),
.DATA_WIDTH ( NumBanks )
) i_dead_write_fifo (
.clk_i,
.rst_ni,
.flush_i ( 1'b0 ),
.testmode_i ( 1'b0 ),
.full_o ( dead_write_fifo_full ),
.empty_o ( dead_write_fifo_empty ),
.usage_o (),
.data_i ( {NumBanks{we_i}} & zero_strobe ),
.push_i ( req_i & gnt_o ),
.data_o ( dead_response_unmasked ),
.pop_i ( rvalid_o )
);
assign dead_response = dead_response_unmasked & {NumBanks{~dead_write_fifo_empty}};
end else begin : gen_no_dead_write_fifo
assign dead_response_unmasked = '0;
assign dead_response = '0;
assign dead_write_fifo_full = 1'b0;
assign dead_write_fifo_empty = 1'b1;
end
// Grant output if all our requests have been granted.
assign gnt_o = (&req_ready) & (&resp_ready) & !dead_write_fifo_full;

if (HideStrb) begin : gen_dead_write_fifo
fifo_v3 #(
.FALL_THROUGH ( 1'b0 ),
.DEPTH ( MaxTrans+1 ),
.DATA_WIDTH ( NumBanks )
) i_dead_write_fifo (
.clk_i,
.rst_ni,
.flush_i ( 1'b0 ),
.testmode_i ( 1'b0 ),
.full_o ( dead_write_fifo_full ),
.empty_o ( dead_write_fifo_empty ),
.usage_o (),
.data_i ( {NumBanks{we_i}} & zero_strobe ),
.push_i ( req_i & gnt_o ),
.data_o ( dead_response_unmasked ),
.pop_i ( rvalid_o )
);
assign dead_response = dead_response_unmasked & {NumBanks{~dead_write_fifo_empty}};
end else begin : gen_no_dead_write_fifo
assign dead_response_unmasked = '0;
assign dead_response = '0;
assign dead_write_fifo_full = 1'b0;
assign dead_write_fifo_empty = 1'b1;
end

// Handle responses.
for (genvar i = 0; unsigned'(i) < NumBanks; i++) begin : gen_resp_regs
stream_fifo #(
.FALL_THROUGH ( 1'b1 ),
.DATA_WIDTH ( $bits(oup_data_t) + $bits(oup_ruser_t) ),
.DEPTH ( FifoDepth )
) i_ft_reg (
.clk_i,
.rst_ni,
.flush_i ( 1'b0 ),
.testmode_i ( 1'b0 ),
.usage_o (),
.data_i ( {bank_rdata_i[i], bank_ruser_i[i]} ),
.valid_i ( bank_rvalid_i[i] ),
.ready_o ( resp_ready[i] ),
.data_o ( {rdata_o[i*BitsPerBank+:BitsPerBank], ruser_o[i]} ),
.valid_o ( resp_valid[i] ),
.ready_i ( rvalid_o & !dead_response[i] )
);
end
assign rvalid_o = &(resp_valid | dead_response);

// Handle responses.
for (genvar i = 0; unsigned'(i) < NumBanks; i++) begin : gen_resp_regs
stream_fifo #(
.FALL_THROUGH ( 1'b1 ),
.DATA_WIDTH ( $bits(oup_data_t) + $bits(oup_ruser_t) ),
.DEPTH ( FifoDepth )
) i_ft_reg (
.clk_i,
.rst_ni,
.flush_i ( 1'b0 ),
.testmode_i ( 1'b0 ),
.usage_o (),
.data_i ( {bank_rdata_i[i], bank_ruser_i[i]} ),
.valid_i ( bank_rvalid_i[i] ),
.ready_o ( resp_ready[i] ),
.data_o ( {rdata_o[i*BitsPerBank+:BitsPerBank], ruser_o[i]} ),
.valid_o ( resp_valid[i] ),
.ready_i ( rvalid_o & !dead_response[i] )
);
end
assign rvalid_o = &(resp_valid | dead_response);

// Assertions
`ifndef SYNTHESIS
Expand Down

0 comments on commit c439813

Please sign in to comment.