1
0
mirror of https://github.com/corundum/corundum.git synced 2025-01-30 08:32:52 +08:00

Add write done tracking to DMA IF mux

This commit is contained in:
Alex Forencich 2021-02-24 13:51:50 -08:00
parent 6fb2eb6b4e
commit ed29997a59
2 changed files with 92 additions and 5 deletions

View File

@ -143,6 +143,7 @@ module dma_if_mux #
input wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] if_ram_wr_cmd_data, input wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] if_ram_wr_cmd_data,
input wire [SEG_COUNT-1:0] if_ram_wr_cmd_valid, input wire [SEG_COUNT-1:0] if_ram_wr_cmd_valid,
output wire [SEG_COUNT-1:0] if_ram_wr_cmd_ready, output wire [SEG_COUNT-1:0] if_ram_wr_cmd_ready,
output wire [SEG_COUNT-1:0] if_ram_wr_done,
input wire [SEG_COUNT*M_RAM_SEL_WIDTH-1:0] if_ram_rd_cmd_sel, input wire [SEG_COUNT*M_RAM_SEL_WIDTH-1:0] if_ram_rd_cmd_sel,
input wire [SEG_COUNT*SEG_ADDR_WIDTH-1:0] if_ram_rd_cmd_addr, input wire [SEG_COUNT*SEG_ADDR_WIDTH-1:0] if_ram_rd_cmd_addr,
input wire [SEG_COUNT-1:0] if_ram_rd_cmd_valid, input wire [SEG_COUNT-1:0] if_ram_rd_cmd_valid,
@ -160,6 +161,7 @@ module dma_if_mux #
output wire [PORTS*SEG_COUNT*SEG_DATA_WIDTH-1:0] ram_wr_cmd_data, output wire [PORTS*SEG_COUNT*SEG_DATA_WIDTH-1:0] ram_wr_cmd_data,
output wire [PORTS*SEG_COUNT-1:0] ram_wr_cmd_valid, output wire [PORTS*SEG_COUNT-1:0] ram_wr_cmd_valid,
input wire [PORTS*SEG_COUNT-1:0] ram_wr_cmd_ready, input wire [PORTS*SEG_COUNT-1:0] ram_wr_cmd_ready,
input wire [PORTS*SEG_COUNT-1:0] ram_wr_done,
output wire [PORTS*SEG_COUNT*S_RAM_SEL_WIDTH-1:0] ram_rd_cmd_sel, output wire [PORTS*SEG_COUNT*S_RAM_SEL_WIDTH-1:0] ram_rd_cmd_sel,
output wire [PORTS*SEG_COUNT*SEG_ADDR_WIDTH-1:0] ram_rd_cmd_addr, output wire [PORTS*SEG_COUNT*SEG_ADDR_WIDTH-1:0] ram_rd_cmd_addr,
output wire [PORTS*SEG_COUNT-1:0] ram_rd_cmd_valid, output wire [PORTS*SEG_COUNT-1:0] ram_rd_cmd_valid,
@ -232,6 +234,7 @@ dma_if_mux_rd_inst (
.if_ram_wr_cmd_data(if_ram_wr_cmd_data), .if_ram_wr_cmd_data(if_ram_wr_cmd_data),
.if_ram_wr_cmd_valid(if_ram_wr_cmd_valid), .if_ram_wr_cmd_valid(if_ram_wr_cmd_valid),
.if_ram_wr_cmd_ready(if_ram_wr_cmd_ready), .if_ram_wr_cmd_ready(if_ram_wr_cmd_ready),
.if_ram_wr_done(if_ram_wr_done),
/* /*
* RAM interface * RAM interface
@ -241,7 +244,8 @@ dma_if_mux_rd_inst (
.ram_wr_cmd_addr(ram_wr_cmd_addr), .ram_wr_cmd_addr(ram_wr_cmd_addr),
.ram_wr_cmd_data(ram_wr_cmd_data), .ram_wr_cmd_data(ram_wr_cmd_data),
.ram_wr_cmd_valid(ram_wr_cmd_valid), .ram_wr_cmd_valid(ram_wr_cmd_valid),
.ram_wr_cmd_ready(ram_wr_cmd_ready) .ram_wr_cmd_ready(ram_wr_cmd_ready),
.ram_wr_done(ram_wr_done)
); );
dma_if_mux_wr #( dma_if_mux_wr #(

View File

@ -109,6 +109,7 @@ module dma_if_mux_rd #
input wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] if_ram_wr_cmd_data, input wire [SEG_COUNT*SEG_DATA_WIDTH-1:0] if_ram_wr_cmd_data,
input wire [SEG_COUNT-1:0] if_ram_wr_cmd_valid, input wire [SEG_COUNT-1:0] if_ram_wr_cmd_valid,
output wire [SEG_COUNT-1:0] if_ram_wr_cmd_ready, output wire [SEG_COUNT-1:0] if_ram_wr_cmd_ready,
output wire [SEG_COUNT-1:0] if_ram_wr_done,
/* /*
* RAM interface * RAM interface
@ -118,13 +119,16 @@ module dma_if_mux_rd #
output wire [PORTS*SEG_COUNT*SEG_ADDR_WIDTH-1:0] ram_wr_cmd_addr, output wire [PORTS*SEG_COUNT*SEG_ADDR_WIDTH-1:0] ram_wr_cmd_addr,
output wire [PORTS*SEG_COUNT*SEG_DATA_WIDTH-1:0] ram_wr_cmd_data, output wire [PORTS*SEG_COUNT*SEG_DATA_WIDTH-1:0] ram_wr_cmd_data,
output wire [PORTS*SEG_COUNT-1:0] ram_wr_cmd_valid, output wire [PORTS*SEG_COUNT-1:0] ram_wr_cmd_valid,
input wire [PORTS*SEG_COUNT-1:0] ram_wr_cmd_ready input wire [PORTS*SEG_COUNT-1:0] ram_wr_cmd_ready,
input wire [PORTS*SEG_COUNT-1:0] ram_wr_done
); );
parameter CL_PORTS = $clog2(PORTS); parameter CL_PORTS = $clog2(PORTS);
parameter S_RAM_SEL_WIDTH_INT = S_RAM_SEL_WIDTH > 0 ? S_RAM_SEL_WIDTH : 1; parameter S_RAM_SEL_WIDTH_INT = S_RAM_SEL_WIDTH > 0 ? S_RAM_SEL_WIDTH : 1;
parameter FIFO_ADDR_WIDTH = 5;
// check configuration // check configuration
initial begin initial begin
if (M_TAG_WIDTH < S_TAG_WIDTH+$clog2(PORTS)) begin if (M_TAG_WIDTH < S_TAG_WIDTH+$clog2(PORTS)) begin
@ -321,6 +325,22 @@ genvar n, p;
for (n = 0; n < SEG_COUNT; n = n + 1) begin for (n = 0; n < SEG_COUNT; n = n + 1) begin
// FIFO to maintain response ordering
reg [FIFO_ADDR_WIDTH+1-1:0] fifo_wr_ptr_reg = 0;
reg [FIFO_ADDR_WIDTH+1-1:0] fifo_rd_ptr_reg = 0;
reg [CL_PORTS-1:0] fifo_sel[(2**FIFO_ADDR_WIDTH)-1:0];
wire fifo_empty = fifo_wr_ptr_reg == fifo_rd_ptr_reg;
wire fifo_full = fifo_wr_ptr_reg == (fifo_rd_ptr_reg ^ (1 << FIFO_ADDR_WIDTH));
integer i;
initial begin
for (i = 0; i < 2**FIFO_ADDR_WIDTH; i = i + 1) begin
fifo_sel[i] = 0;
end
end
// RAM write command demux // RAM write command demux
wire [M_RAM_SEL_WIDTH-1:0] seg_if_ram_wr_cmd_sel = if_ram_wr_cmd_sel[M_RAM_SEL_WIDTH*n +: M_RAM_SEL_WIDTH]; wire [M_RAM_SEL_WIDTH-1:0] seg_if_ram_wr_cmd_sel = if_ram_wr_cmd_sel[M_RAM_SEL_WIDTH*n +: M_RAM_SEL_WIDTH];
@ -357,16 +377,27 @@ for (n = 0; n < SEG_COUNT; n = n + 1) begin
reg seg_ram_wr_cmd_ready_int_reg = 1'b0; reg seg_ram_wr_cmd_ready_int_reg = 1'b0;
wire seg_ram_wr_cmd_ready_int_early; wire seg_ram_wr_cmd_ready_int_early;
assign seg_if_ram_wr_cmd_ready = seg_ram_wr_cmd_ready_int_reg; assign seg_if_ram_wr_cmd_ready = seg_ram_wr_cmd_ready_int_reg && !fifo_full;
wire [CL_PORTS-1:0] select = PORTS > 1 ? (seg_if_ram_wr_cmd_sel >> (M_RAM_SEL_WIDTH - CL_PORTS)) : 0; wire [CL_PORTS-1:0] select_cmd = PORTS > 1 ? (seg_if_ram_wr_cmd_sel >> (M_RAM_SEL_WIDTH - CL_PORTS)) : 0;
always @* begin always @* begin
seg_ram_wr_cmd_sel_int = seg_if_ram_wr_cmd_sel; seg_ram_wr_cmd_sel_int = seg_if_ram_wr_cmd_sel;
seg_ram_wr_cmd_be_int = seg_if_ram_wr_cmd_be; seg_ram_wr_cmd_be_int = seg_if_ram_wr_cmd_be;
seg_ram_wr_cmd_addr_int = seg_if_ram_wr_cmd_addr; seg_ram_wr_cmd_addr_int = seg_if_ram_wr_cmd_addr;
seg_ram_wr_cmd_data_int = seg_if_ram_wr_cmd_data; seg_ram_wr_cmd_data_int = seg_if_ram_wr_cmd_data;
seg_ram_wr_cmd_valid_int = (seg_if_ram_wr_cmd_valid && seg_if_ram_wr_cmd_ready) << select; seg_ram_wr_cmd_valid_int = (seg_if_ram_wr_cmd_valid && seg_if_ram_wr_cmd_ready) << select_cmd;
end
always @(posedge clk) begin
if (seg_if_ram_wr_cmd_valid && seg_if_ram_wr_cmd_ready) begin
fifo_sel[fifo_wr_ptr_reg[FIFO_ADDR_WIDTH-1:0]] <= select_cmd;
fifo_wr_ptr_reg <= fifo_wr_ptr_reg + 1;
end
if (rst) begin
fifo_wr_ptr_reg <= 0;
end
end end
// output datapath logic // output datapath logic
@ -456,6 +487,58 @@ for (n = 0; n < SEG_COUNT; n = n + 1) begin
end end
end end
// RAM write done mux
wire [PORTS-1:0] seg_ram_wr_done;
wire [PORTS-1:0] seg_ram_wr_done_sel;
wire seg_if_ram_wr_done;
for (p = 0; p < PORTS; p = p + 1) begin
assign seg_ram_wr_done[p] = ram_wr_done[p*SEG_COUNT+n];
end
assign if_ram_wr_done[n] = seg_if_ram_wr_done;
wire [CL_PORTS-1:0] select_resp = fifo_sel[fifo_rd_ptr_reg[FIFO_ADDR_WIDTH-1:0]];
for (p = 0; p < PORTS; p = p + 1) begin
reg [FIFO_ADDR_WIDTH+1-1:0] done_count_reg = 0;
reg done_reg = 1'b0;
assign seg_ram_wr_done_sel[p] = done_reg;
always @(posedge clk) begin
if (select_resp == p && (done_count_reg != 0 || seg_ram_wr_done[p])) begin
done_reg <= 1'b1;
if (!seg_ram_wr_done[p]) begin
done_count_reg <= done_count_reg - 1;
end
end else begin
done_reg <= 1'b0;
if (seg_ram_wr_done[p]) begin
done_count_reg <= done_count_reg + 1;
end
end
if (rst) begin
done_count_reg <= 0;
done_reg <= 1'b0;
end
end
end
assign seg_if_ram_wr_done = seg_ram_wr_done_sel != 0;
always @(posedge clk) begin
if (seg_if_ram_wr_done && !fifo_empty) begin
fifo_rd_ptr_reg <= fifo_rd_ptr_reg + 1;
end
if (rst) begin
fifo_rd_ptr_reg <= 0;
end
end
end end
endgenerate endgenerate