diff --git a/umi/rtl/umi_fifo_flex.v b/umi/rtl/umi_fifo_flex.v index 1fb975e..c16f95f 100644 --- a/umi/rtl/umi_fifo_flex.v +++ b/umi/rtl/umi_fifo_flex.v @@ -17,14 +17,14 @@ * * Documentation: * - Converts UMI transactions between different width options. - * - Currently does not support merge small -> large * * Future enhancements: - * 1. merge small->large transactions (adds latency) - * 2. do not split large->small transactions in case they carry no data + * 1. do not split large->small transactions in case they carry no data * * Known limitation/bugs: * - Does not handle cases where SIZE>ODW (does not manipulate SIZE) + * - When ODW>IDW, incoming transaction is merged only if merged transaction + * does not cross ODW boundary (num_merged_bits + IDW)<=ODW * ******************************************************************************/ @@ -69,33 +69,40 @@ module umi_fifo_flex // Local FIFO wire [ODW+AW+AW+CW-1:0] fifo_dout; wire [ODW+AW+AW+CW-1:0] fifo_din; + wire fifo_full_raw; + wire fifo_empty_raw; + wire fifo_read; + wire fifo_write; + + // Split/merge packet latch reg packet_latch_valid; wire packet_latch_en; reg [CW-1:0] packet_cmd_latch; reg [AW-1:0] packet_dstaddr_latch; reg [AW-1:0] packet_srcaddr_latch; - reg [IDW-1:0] packet_data_latch; wire [CW-1:0] packet_cmd; wire [AW-1:0] latch_dstaddr; - wire [AW-1:0] fifo_dstaddr; wire [AW-1:0] latch_srcaddr; - wire [AW-1:0] fifo_srcaddr; wire [IDW-1:0] latch_data; - wire [IDW-1:0] fifo_data; - wire fifo_full_raw; - wire fifo_empty_raw; + + localparam MAX_DW = (ODW > IDW) ? ODW : IDW; + + // Split/merge to fifo + wire [AW-1:0] latch2fifo_dstaddr; + wire [AW-1:0] latch2fifo_srcaddr; + wire [MAX_DW-1:0] latch2fifo_data; + wire [7:0] latch2fifo_len; + wire latch2fifo_eom; + wire latch2fifo_valid; + wire latch2fifo_ready; + wire latch2in_ready; // local wires wire umi_out_beat; - wire fifo_read; - wire fifo_write; wire fifo_in_ready; - wire [7:0] fifo_len; wire [7:0] latch_len; - reg last_sent; wire [8:0] cmd_len_plus_one; - reg [1:0] fifo_ready; - wire fifo_eom; + wire fifo_out_of_reset; wire [AW-1:0] addr_mask; wire [AW-1:0] dstaddr_masked; @@ -114,15 +121,122 @@ module umi_fifo_flex wire [2:0] cmd_size; wire [1:0] cmd_user; wire [23:0] cmd_user_extended; - wire [CW-1:0] fifo_cmd; + wire [CW-1:0] latch2fifo_cmd; wire [CW-1:0] latch_cmd; // End of automatics + //################################# + // Input decoding + //################################# + wire [4:0] umi_in_cmd_opcode; + wire [2:0] umi_in_cmd_size; + wire [7:0] umi_in_cmd_len; + wire [7:0] umi_in_cmd_atype; + wire [3:0] umi_in_cmd_qos; + wire [1:0] umi_in_cmd_prot; + wire umi_in_cmd_eom; + wire umi_in_cmd_eof; + wire umi_in_cmd_ex; + wire [1:0] umi_in_cmd_user; + wire [23:0] umi_in_cmd_user_extended; + wire [1:0] umi_in_cmd_err; + wire [4:0] umi_in_cmd_hostid; + + umi_unpack #(.CW(CW)) + umi_unpack_i( + // Outputs + .cmd_opcode (umi_in_cmd_opcode[4:0]), + .cmd_size (umi_in_cmd_size[2:0]), + .cmd_len (umi_in_cmd_len[7:0]), + .cmd_atype (umi_in_cmd_atype[7:0]), + .cmd_qos (umi_in_cmd_qos[3:0]), + .cmd_prot (umi_in_cmd_prot[1:0]), + .cmd_eom (umi_in_cmd_eom), + .cmd_eof (umi_in_cmd_eof), + .cmd_ex (umi_in_cmd_ex), + .cmd_user (umi_in_cmd_user[1:0]), + .cmd_user_extended (umi_in_cmd_user_extended[23:0]), + .cmd_err (umi_in_cmd_err[1:0]), + .cmd_hostid (umi_in_cmd_hostid[4:0]), + // Inputs + .packet_cmd (umi_in_cmd[CW-1:0])); + + wire umi_in_cmd_invalid; + + wire umi_in_cmd_request; + wire umi_in_cmd_response; + + wire umi_in_cmd_read; + wire umi_in_cmd_write; + + wire umi_in_cmd_write_posted; + wire umi_in_cmd_rdma; + wire umi_in_cmd_atomic; + wire umi_in_cmd_user0; + wire umi_in_cmd_future0; + wire umi_in_cmd_error; + wire umi_in_cmd_link; + + wire umi_in_cmd_read_resp; + wire umi_in_cmd_write_resp; + wire umi_in_cmd_user0_resp; + wire umi_in_cmd_user1_resp; + wire umi_in_cmd_future0_resp; + wire umi_in_cmd_future1_resp; + wire umi_in_cmd_link_resp; + + wire umi_in_cmd_atomic_add; + wire umi_in_cmd_atomic_and; + wire umi_in_cmd_atomic_or; + wire umi_in_cmd_atomic_xor; + wire umi_in_cmd_atomic_max; + wire umi_in_cmd_atomic_min; + wire umi_in_cmd_atomic_maxu; + wire umi_in_cmd_atomic_minu; + wire umi_in_cmd_atomic_swap; + + umi_decode #(.CW(CW)) + umi_decode_i( + // Packet Command + .command (umi_in_cmd[CW-1:0]), + .cmd_invalid (umi_in_cmd_invalid), + // request/response/link + .cmd_request (umi_in_cmd_request), + .cmd_response (umi_in_cmd_response), + // requests + .cmd_read (umi_in_cmd_read), + .cmd_write (umi_in_cmd_write), + .cmd_write_posted (umi_in_cmd_write_posted), + .cmd_rdma (umi_in_cmd_rdma), + .cmd_atomic (umi_in_cmd_atomic), + .cmd_user0 (umi_in_cmd_user0), + .cmd_future0 (umi_in_cmd_future0), + .cmd_error (umi_in_cmd_error), + .cmd_link (umi_in_cmd_link), + // Response (device -> host) + .cmd_read_resp (umi_in_cmd_read_resp), + .cmd_write_resp (umi_in_cmd_write_resp), + .cmd_user0_resp (umi_in_cmd_user0_resp), + .cmd_user1_resp (umi_in_cmd_user1_resp), + .cmd_future0_resp (umi_in_cmd_future0_resp), + .cmd_future1_resp (umi_in_cmd_future1_resp), + .cmd_link_resp (umi_in_cmd_link_resp), + // Atomic operations + .cmd_atomic_add (umi_in_cmd_atomic_add), + .cmd_atomic_and (umi_in_cmd_atomic_and), + .cmd_atomic_or (umi_in_cmd_atomic_or), + .cmd_atomic_xor (umi_in_cmd_atomic_xor), + .cmd_atomic_max (umi_in_cmd_atomic_max), + .cmd_atomic_min (umi_in_cmd_atomic_min), + .cmd_atomic_maxu (umi_in_cmd_atomic_maxu), + .cmd_atomic_minu (umi_in_cmd_atomic_minu), + .cmd_atomic_swap (umi_in_cmd_atomic_swap)); + //################################# // Packet manipulation //################################# umi_unpack #(.CW(CW)) - umi_unpack_i(/*AUTOINST*/ + umi_unpack_packet(/*AUTOINST*/ // Outputs .cmd_opcode (cmd_opcode[4:0]), .cmd_size (cmd_size[2:0]), @@ -146,10 +260,159 @@ module umi_fifo_flex // cmd manipulation - at each cycle need to remove the bytes sent out // SPLIT will also split based on crossing DW boundary and not only size - generate if (SPLIT == 1) + generate if (ODW > IDW) + begin + + reg [ODW-1:0] packet_data_latch; + + //################################# + // Merged byte counter + //################################# + reg [8:0] latch_bytes; + wire [8:0] latch_in_bytes; + wire [8:0] latch_out_bytes; + + wire [ODW-1:0] umi_in_data_shifted; + + assign latch_in_bytes = ((umi_in_cmd_len + 8'h01) << umi_in_cmd_size); + + always @(posedge umi_in_clk or negedge umi_in_nreset) + if (~umi_in_nreset) + latch_bytes <= 'b0; + else if (umi_in_valid & umi_in_ready & fifo_write) + latch_bytes <= latch_in_bytes; + else if (umi_in_valid & umi_in_ready) + latch_bytes <= latch_bytes + latch_in_bytes; + else if (fifo_write) + latch_bytes <= 'b0; + + //################################# + // Check Mergeability + //################################# + wire opcode_mergeable; + wire misc_mergeable; + wire dstaddr_mergeable; + wire srcaddr_mergeable; + wire len_mergeable; + wire tx_mergeable; + + // Check opcode type and ensure opcode match across cycles + assign opcode_mergeable = (umi_in_cmd_read | umi_in_cmd_write | + umi_in_cmd_write_posted | umi_in_cmd_rdma | + umi_in_cmd_read_resp | umi_in_cmd_write_resp) & + !umi_in_cmd_ex & (umi_in_cmd_opcode == cmd_opcode); + + assign misc_mergeable = (umi_in_cmd_size == cmd_size) & + (umi_in_cmd_qos == cmd_qos) & + (umi_in_cmd_prot == cmd_prot) & + (umi_in_cmd_eof == cmd_eof) & + (umi_in_cmd_user == cmd_user) & + (umi_in_cmd_err == cmd_err) & + (umi_in_cmd_hostid == cmd_hostid); + + assign dstaddr_mergeable = (umi_in_dstaddr == (packet_dstaddr_latch + {{(AW-9){1'b0}}, latch_bytes})); + assign srcaddr_mergeable = (umi_in_srcaddr == (packet_srcaddr_latch + {{(AW-9){1'b0}}, latch_bytes})) | + umi_in_cmd_response; + assign len_mergeable = (latch_bytes + latch_in_bytes) <= (ODW >> 3); + + assign tx_mergeable = opcode_mergeable & misc_mergeable & + dstaddr_mergeable & srcaddr_mergeable & + len_mergeable; + + reg packet_latch_eom; + wire packet_boundary; + reg packet_boundary_latch; + + assign packet_cmd[CW-1:0] = packet_latch_valid ? + packet_cmd_latch[CW-1:0] : + umi_in_cmd[CW-1:0] & {CW{umi_in_valid}}; + + // Fifo signal - current command going out + assign latch2fifo_dstaddr = packet_dstaddr_latch; + assign latch2fifo_srcaddr = packet_srcaddr_latch; + assign latch2fifo_data = packet_data_latch; + // cmd manipulation - at each cycle need to remove the bytes sent out + assign latch2fifo_eom = packet_latch_eom; + /* verilator lint_off WIDTHTRUNC */ + assign latch2fifo_len = (latch_bytes >> cmd_size) - 8'h1; + /* verilator lint_on WIDTHTRUNC */ + assign latch2fifo_valid = (packet_boundary | packet_boundary_latch) & (latch_bytes > 0); + assign latch2fifo_ready = (tx_mergeable & !packet_latch_eom) | + (tx_mergeable & packet_latch_eom & (latch_bytes == 0)) | + (!tx_mergeable & (latch_bytes == 0)); + assign latch2in_ready = latch2fifo_ready; + + // Latched command for next split + // Unused for merge + assign latch_dstaddr = 'b0; + assign latch_srcaddr = 'b0; + assign latch_data = 'b0; + assign latch_len = 'b0; + + assign packet_boundary = packet_latch_eom | !tx_mergeable | !umi_in_valid; + always @(posedge umi_in_clk or negedge umi_in_nreset) + if (~umi_in_nreset) + packet_boundary_latch <= 1'b1; + else if (umi_in_valid & umi_in_ready) + packet_boundary_latch <= 1'b0; + else if (packet_boundary) + packet_boundary_latch <= 1'b1; + + // Packet latch + always @(posedge umi_in_clk or negedge umi_in_nreset) + if (~umi_in_nreset) + begin + packet_latch_valid <= 1'b0; + packet_dstaddr_latch <= {AW{1'b0}}; + packet_srcaddr_latch <= {AW{1'b0}}; + end + else if ((umi_in_ready & umi_in_valid) & (packet_boundary | fifo_write)) + begin + packet_latch_valid <= 1'b1; + packet_dstaddr_latch <= umi_in_dstaddr; + packet_srcaddr_latch <= umi_in_srcaddr; + end + else if (fifo_write) + begin + packet_latch_valid <= 1'b0; + end + + always @(posedge umi_in_clk or negedge umi_in_nreset) + if (~umi_in_nreset) + packet_cmd_latch <= {CW{1'b0}}; + else if (umi_in_ready & umi_in_valid) + packet_cmd_latch <= latch_cmd; + + always @(posedge umi_in_clk or negedge umi_in_nreset) + if (~umi_in_nreset) + packet_latch_eom <= 1'b0; + else if (umi_in_ready & umi_in_valid) + packet_latch_eom <= umi_in_cmd_eom; + + // NOTE: Here, the correct shift would be + // (latch_bytes - latch_out_bytes) << 3 + // However, if latch_out_bytes is non zero then the first 'else if' + // in the always block will be hit and umi_in_data_shifted will not + // be used. So to simplify we can use (latch_bytes << 3). + /* verilator lint_off WIDTHEXPAND */ + assign umi_in_data_shifted = umi_in_data << (latch_bytes << 3); + /* verilator lint_on WIDTHEXPAND */ + + always @(posedge umi_in_clk or negedge umi_in_nreset) + if (~umi_in_nreset) + packet_data_latch <= {ODW{1'b0}}; + else if ((umi_in_ready & umi_in_valid) & (packet_boundary | fifo_write)) + packet_data_latch <= {{ODW-IDW{1'b0}}, umi_in_data}; + else if (umi_in_ready & umi_in_valid) + packet_data_latch <= packet_data_latch | umi_in_data_shifted; + + end + else if (SPLIT == 1) begin + reg [IDW-1:0] packet_data_latch; + assign addr_mask[AW-1:0] = {{AW-$clog2(ODW/8){1'b0}},{$clog2(ODW/8){1'b1}}}; - assign dstaddr_masked[AW-1:0] = fifo_dstaddr[AW-1:0] & addr_mask[AW-1:0]; + assign dstaddr_masked[AW-1:0] = latch2fifo_dstaddr[AW-1:0] & addr_mask[AW-1:0]; assign packet_latch_en = (cmd_len_plus_one + (dstaddr_masked[9:0] >> cmd_size)) > (ODW >> cmd_size >> 3); @@ -158,19 +421,22 @@ module umi_fifo_flex umi_in_cmd[CW-1:0] & {CW{umi_in_valid}}; // Fifo signal - current command going out - assign fifo_dstaddr = packet_latch_valid ? packet_dstaddr_latch : umi_in_dstaddr; - assign fifo_srcaddr = packet_latch_valid ? packet_srcaddr_latch : umi_in_srcaddr; - assign fifo_data = packet_latch_valid ? packet_data_latch : umi_in_data; + assign latch2fifo_dstaddr = packet_latch_valid ? packet_dstaddr_latch : umi_in_dstaddr; + assign latch2fifo_srcaddr = packet_latch_valid ? packet_srcaddr_latch : umi_in_srcaddr; + assign latch2fifo_data = packet_latch_valid ? packet_data_latch : umi_in_data; // cmd manipulation - at each cycle need to remove the bytes sent out - assign fifo_eom = packet_latch_en ? 1'b0 : cmd_eom; - assign fifo_len = packet_latch_en ? + assign latch2fifo_eom = packet_latch_en ? 1'b0 : cmd_eom; + assign latch2fifo_len = packet_latch_en ? (((ODW[10:3]) - dstaddr_masked[7:0]) >> cmd_size) - 1'b1 : cmd_len[7:0]; + assign latch2fifo_valid = umi_in_valid | packet_latch_valid; + assign latch2fifo_ready = ~packet_latch_valid; + assign latch2in_ready = ~packet_latch_valid & umi_out_ready; // Latched command for next split - assign latch_dstaddr = fifo_dstaddr + ((ODW/8) - dstaddr_masked[AW-1:0]); - assign latch_srcaddr = fifo_srcaddr + ((ODW/8) - dstaddr_masked[AW-1:0]); - assign latch_data = fifo_data >> (ODW - (dstaddr_masked[9:0] << 3)); + assign latch_dstaddr = latch2fifo_dstaddr + ((ODW/8) - dstaddr_masked[AW-1:0]); + assign latch_srcaddr = latch2fifo_srcaddr + ((ODW/8) - dstaddr_masked[AW-1:0]); + assign latch_data = latch2fifo_data >> (ODW - (dstaddr_masked[9:0] << 3)); assign latch_len = cmd_len - ((ODW[10:3] - dstaddr_masked[7:0]) >> cmd_size); @@ -195,6 +461,8 @@ module umi_fifo_flex end else begin // split only based on (LEN-1)*(2^SIZE) > DW + reg [IDW-1:0] packet_data_latch; + assign packet_latch_en = cmd_len_plus_one > (ODW[11:3] >> cmd_size); assign packet_cmd[CW-1:0] = packet_latch_valid ? @@ -202,17 +470,20 @@ module umi_fifo_flex umi_in_cmd[CW-1:0] & {CW{umi_in_valid}}; // Fifo signal - current command going out - assign fifo_dstaddr = packet_latch_valid ? packet_dstaddr_latch : umi_in_dstaddr; - assign fifo_srcaddr = packet_latch_valid ? packet_srcaddr_latch : umi_in_srcaddr; - assign fifo_data = packet_latch_valid ? packet_data_latch : umi_in_data; + assign latch2fifo_dstaddr = packet_latch_valid ? packet_dstaddr_latch : umi_in_dstaddr; + assign latch2fifo_srcaddr = packet_latch_valid ? packet_srcaddr_latch : umi_in_srcaddr; + assign latch2fifo_data = packet_latch_valid ? packet_data_latch : umi_in_data; // cmd manipulation - at each cycle need to remove the bytes sent out - assign fifo_eom = packet_latch_en ? 1'b0 : cmd_eom; - assign fifo_len = packet_latch_en ? ((ODW[10:3] >> cmd_size) - 1'b1) : cmd_len; + assign latch2fifo_eom = packet_latch_en ? 1'b0 : cmd_eom; + assign latch2fifo_len = packet_latch_en ? ((ODW[10:3] >> cmd_size) - 1'b1) : cmd_len; + assign latch2fifo_valid = umi_in_valid | packet_latch_valid; + assign latch2fifo_ready = ~packet_latch_valid; + assign latch2in_ready = ~packet_latch_valid & umi_out_ready; // Latched command for next split - assign latch_dstaddr = fifo_dstaddr + (ODW/8); - assign latch_srcaddr = fifo_srcaddr + (ODW/8); - assign latch_data = fifo_data >> ODW; + assign latch_dstaddr = latch2fifo_dstaddr + (ODW/8); + assign latch_srcaddr = latch2fifo_srcaddr + (ODW/8); + assign latch_data = latch2fifo_data >> ODW; assign latch_len = cmd_len - (ODW[10:3] >> cmd_size); // Packet latch @@ -261,23 +532,23 @@ module umi_fifo_flex .cmd_user_extended (cmd_user_extended[23:0])); /* umi_pack AUTO_TEMPLATE( - .packet_cmd (fifo_cmd[]), - .cmd_len (fifo_len), - .cmd_eom (fifo_eom), + .packet_cmd (latch2fifo_cmd[]), + .cmd_len (latch2fifo_len), + .cmd_eom (latch2fifo_eom), );*/ umi_pack #(.CW(CW)) umi_pack_fifo(/*AUTOINST*/ // Outputs - .packet_cmd (fifo_cmd[CW-1:0]), // Templated + .packet_cmd (latch2fifo_cmd[CW-1:0]), // Templated // Inputs .cmd_opcode (cmd_opcode[4:0]), .cmd_size (cmd_size[2:0]), - .cmd_len (fifo_len), // Templated + .cmd_len (latch2fifo_len), // Templated .cmd_atype (cmd_atype[7:0]), .cmd_prot (cmd_prot[1:0]), .cmd_qos (cmd_qos[3:0]), - .cmd_eom (fifo_eom), // Templated + .cmd_eom (latch2fifo_eom), // Templated .cmd_eof (cmd_eof), .cmd_user (cmd_user[1:0]), .cmd_err (cmd_err[1:0]), @@ -289,21 +560,16 @@ module umi_fifo_flex assign fifo_read = ~fifo_empty & umi_out_ready; // Write fifo when high (blocked inside fifo when full) - assign fifo_write = ~fifo_full & fifo_ready[1] & (umi_in_valid | packet_latch_valid); + assign fifo_write = ~fifo_full & fifo_out_of_reset & latch2fifo_valid; // FIFO pushback - assign fifo_in_ready = ~fifo_full & ~packet_latch_valid; + assign fifo_in_ready = ~fifo_full & latch2fifo_ready; - generate - if (ODW>IDW) //TODO - expand transactions - assign fifo_din[AW+AW+CW+:ODW] = {{ODW-IDW{1'b0}},fifo_data[IDW-1:0]}; - else - assign fifo_din[AW+AW+CW+:ODW] = fifo_data[ODW-1:0]; - endgenerate + assign fifo_din[AW+AW+CW+:ODW] = latch2fifo_data[ODW-1:0]; - assign fifo_din[AW+CW+:AW] = fifo_srcaddr[AW-1:0]; - assign fifo_din[CW+:AW] = fifo_dstaddr[AW-1:0]; - assign fifo_din[0+:CW] = fifo_cmd[CW-1:0]; + assign fifo_din[AW+CW+:AW] = latch2fifo_srcaddr[AW-1:0]; + assign fifo_din[CW+:AW] = latch2fifo_dstaddr[AW-1:0]; + assign fifo_din[0+:CW] = latch2fifo_cmd[CW-1:0]; //################################# // Standard Dual Clock FIFO @@ -320,7 +586,7 @@ module umi_fifo_flex .wr_clk (umi_in_clk), .wr_nreset (umi_in_nreset), .wr_din (fifo_din[ODW+AW+AW+CW-1:0]), - .wr_en (fifo_ready[1] & (umi_in_valid | packet_latch_valid)), + .wr_en (fifo_write), .wr_chaosmode (chaosmode), .rd_clk (umi_out_clk), .rd_nreset (umi_out_nreset), @@ -342,7 +608,7 @@ module umi_fifo_flex .clk (umi_in_clk), .nreset (umi_in_nreset), .wr_din (fifo_din[ODW+AW+AW+CW-1:0]), - .wr_en (fifo_ready[1] & (umi_in_valid | packet_latch_valid)), + .wr_en (fifo_write), .chaosmode (chaosmode), .rd_en (fifo_read), .vss (vss), @@ -358,11 +624,12 @@ module umi_fifo_flex end endgenerate - always @(posedge umi_in_clk or negedge umi_in_nreset) - if (~umi_in_nreset) - fifo_ready[1:0] <= 2'b00; - else - fifo_ready[1:0] <= {fifo_ready[0],1'b1}; + la_drsync la_drsync_i ( + .clk (umi_in_clk), + .nreset (umi_in_nreset), + .in (1'b1), + .out (fifo_out_of_reset) + ); //################################# // FIFO Bypass @@ -371,21 +638,15 @@ module umi_fifo_flex assign fifo_full = (bypass | ~(|DEPTH)) ? ~umi_out_ready : fifo_full_raw; assign fifo_empty = (bypass | ~(|DEPTH)) ? 1'b1 : fifo_empty_raw; - assign umi_out_cmd[CW-1:0] = (bypass | ~(|DEPTH)) ? fifo_cmd[CW-1:0] : fifo_dout[CW-1:0]; - assign umi_out_dstaddr[AW-1:0] = (bypass | ~(|DEPTH)) ? fifo_dstaddr[AW-1:0] : fifo_dout[CW+:AW] & 64'hFFFF_FFFF_FFFF_FFFF; - assign umi_out_srcaddr[AW-1:0] = (bypass | ~(|DEPTH)) ? fifo_srcaddr[AW-1:0] : fifo_dout[CW+AW+:AW]; - - generate - if (ODW>IDW) //TODO - expand transactions - assign umi_out_data[ODW-1:0] = (bypass | ~(|DEPTH)) ? {{ODW-IDW{1'b0}},fifo_data[IDW-1:0]} : fifo_dout[CW+AW+AW+:ODW]; - else - assign umi_out_data[ODW-1:0] = (bypass | ~(|DEPTH)) ? fifo_data[ODW-1:0] : fifo_dout[CW+AW+AW+:ODW]; - endgenerate + assign umi_out_cmd[CW-1:0] = (bypass | ~(|DEPTH)) ? latch2fifo_cmd[CW-1:0] : fifo_dout[CW-1:0]; + assign umi_out_dstaddr[AW-1:0] = (bypass | ~(|DEPTH)) ? latch2fifo_dstaddr[AW-1:0] : fifo_dout[CW+:AW] & 64'hFFFF_FFFF_FFFF_FFFF; + assign umi_out_srcaddr[AW-1:0] = (bypass | ~(|DEPTH)) ? latch2fifo_srcaddr[AW-1:0] : fifo_dout[CW+AW+:AW]; + assign umi_out_data[ODW-1:0] = (bypass | ~(|DEPTH)) ? latch2fifo_data[ODW-1:0] : fifo_dout[CW+AW+AW+:ODW]; - assign umi_out_valid = ~fifo_ready[1] ? 1'b0 : - (bypass | ~(|DEPTH)) ? (umi_in_valid | packet_latch_valid) : ~fifo_empty; - assign umi_in_ready = ~fifo_ready[1] ? 1'b0 : - (bypass | ~(|DEPTH)) ? ~packet_latch_valid & umi_out_ready : fifo_in_ready; + assign umi_out_valid = ~fifo_out_of_reset ? 1'b0 : + (bypass | ~(|DEPTH)) ? latch2fifo_valid : ~fifo_empty; + assign umi_in_ready = ~fifo_out_of_reset ? 1'b0 : + (bypass | ~(|DEPTH)) ? latch2in_ready : fifo_in_ready; // debug signals assign umi_out_beat = umi_out_valid & umi_out_ready; diff --git a/umi/testbench/test_fifo_flex.py b/umi/testbench/test_fifo_flex.py index 0040277..2d80575 100755 --- a/umi/testbench/test_fifo_flex.py +++ b/umi/testbench/test_fifo_flex.py @@ -65,16 +65,16 @@ def main(vldmode="2", rdymode="2", host2dut="host2dut_0.q", dut2host="dut2host_0 print("### Statring test ###") - for count in range (100): + for count in range (1000): # length should not cross the DW boundary - umi_mem_agent limitation - length = np.random.randint(0,15) + length = np.random.randint(0,255) dst_addr = 32*random.randrange(2**(10-5)-1) # sb limitation - should align to bus width src_addr = 32*random.randrange(2**(10-5)-1) data8 = np.random.randint(0,255,size=length,dtype=np.uint8) - print(f"umi writing {length+1} bytes to addr 0x{dst_addr:08x}") - host.write(dst_addr, data8, srcaddr=src_addr) - print(f"umi read from addr 0x{dst_addr:08x}") - val8 = host.read(dst_addr, length, np.uint8, srcaddr=src_addr) + print(f"[{count}] umi writing {length} bytes to addr 0x{dst_addr:08x}") + host.write(dst_addr, data8, srcaddr=src_addr, max_bytes=16) + print(f"[{count}] umi read from addr 0x{dst_addr:08x}") + val8 = host.read(dst_addr, length, np.uint8, srcaddr=src_addr, max_bytes=16) if ~((val8 == data8).all()): print(f"ERROR umi read from addr 0x{dst_addr:08x}") print(f"Expected:") diff --git a/umi/testbench/testbench_fifo_flex.sv b/umi/testbench/testbench_fifo_flex.sv index 16ee2df..dcd9b95 100644 --- a/umi/testbench/testbench_fifo_flex.sv +++ b/umi/testbench/testbench_fifo_flex.sv @@ -51,7 +51,7 @@ module testbench ( wire [AW-1:0] umi_resp_in_srcaddr; wire umi_resp_in_valid; // End of automatics - reg nreset; + wire nreset; wire [CTRLW-1:0] sram_ctrl = 8'b0; @@ -86,10 +86,10 @@ module testbench ( ); umi_tx_sim #(.READY_MODE_DEFAULT(2), - .DW(ODW) + .DW(IDW) ) host_umi_tx_i (.clk(clk), - .data(umi_resp_out_data[ODW-1:0]), + .data(umi_resp_out_data[IDW-1:0]), .srcaddr(umi_resp_out_srcaddr[AW-1:0]), .dstaddr(umi_resp_out_dstaddr[AW-1:0]), .cmd(umi_resp_out_cmd[CW-1:0]), @@ -238,14 +238,17 @@ module testbench ( // VCD + reg [15:0] nreset_r; + assign nreset = ~nreset_r[15]; + initial begin - nreset = 1'b0; + nreset_r = 16'hFFFF; end // initial begin always @(negedge clk) begin - nreset <= nreset | 1'b1; + nreset_r <= nreset_r << 1; end // control block @@ -260,7 +263,7 @@ module testbench ( // auto-stop - auto_stop_sim #(.CYCLES(50000)) auto_stop_sim_i (.clk(clk)); + auto_stop_sim #(.CYCLES(500000)) auto_stop_sim_i (.clk(clk)); endmodule // Local Variables: diff --git a/utils/rtl/umi2tl_np.v b/utils/rtl/umi2tl_np.v index 029f8f3..7fe8c61 100644 --- a/utils/rtl/umi2tl_np.v +++ b/utils/rtl/umi2tl_np.v @@ -170,7 +170,7 @@ module umi2tl_np #( ); // Calculate byte shift needed - wire [$clog2(ODW/8):0] req_bytes = (1 << fifoflex_out_req_cmd_size)*(fifoflex_out_req_cmd_len + 1); + wire [7:0] req_bytes = (1 << fifoflex_out_req_cmd_size)*(fifoflex_out_req_cmd_len + 1); reg [2:0] masked_shift; reg [2:0] masked_tl_a_size; diff --git a/utils/rtl/umi_packet_merge_greedy.v b/utils/rtl/umi_packet_merge_greedy.v index cf42932..0282a41 100644 --- a/utils/rtl/umi_packet_merge_greedy.v +++ b/utils/rtl/umi_packet_merge_greedy.v @@ -148,7 +148,7 @@ module umi_packet_merge_greedy #( wire umi_in_ready_r; wire umi_in_cmd_commit_r; - reg [$clog2(ODW/8):0] byte_counter; + reg [7:0] byte_counter; localparam [$clog2(ODW/8):0] ODW_BYTES = ODW[3+$clog2(ODW/8):3]; localparam ADDR_PAD_BYTES = AW - 1 - $clog2(ODW/8); @@ -236,9 +236,9 @@ module umi_packet_merge_greedy #( wire umi_in_opcode_check; wire umi_in_field_match; wire umi_in_mergeable; - wire [$clog2(IDW/8):0] umi_in_bytes; + wire [7:0] umi_in_bytes; reg umi_in_mergeable_r; - reg [$clog2(IDW/8):0] umi_in_bytes_r; + reg [7:0] umi_in_bytes_r; reg [AW-1:0] umi_in_dstaddr_nx; reg [AW-1:0] umi_in_srcaddr_nx; diff --git a/utils/testbench/config.vlt b/utils/testbench/config.vlt index 2aa67ae..bdb19a7 100644 --- a/utils/testbench/config.vlt +++ b/utils/testbench/config.vlt @@ -18,5 +18,5 @@ lint_off -rule BLKSEQ -file "*switchboard/switchboard/verilog/*" lint_off -rule GENUNNAMED lint_off -rule TIMESCALEMOD // To be fixed: -lint_off -rule SYNCASYNCNET -lint_off -rule WIDTHTRUNC +//lint_off -rule SYNCASYNCNET +//lint_off -rule WIDTHTRUNC diff --git a/utils/testbench/testbench_umi2tl_np.v b/utils/testbench/testbench_umi2tl_np.v index 8fb1fd6..106f3d1 100644 --- a/utils/testbench/testbench_umi2tl_np.v +++ b/utils/testbench/testbench_umi2tl_np.v @@ -50,7 +50,7 @@ module testbench #( // Reset initialization always @(posedge clk) begin - nreset_vec <= {nreset_vec[15:0], 1'b1}; + nreset_vec <= {nreset_vec[14:0], 1'b1}; end assign nreset = nreset_vec[14]; diff --git a/utils/testbench/testbench_umi_packet_merge_greedy.v b/utils/testbench/testbench_umi_packet_merge_greedy.v index 8dc2973..1c63e34 100644 --- a/utils/testbench/testbench_umi_packet_merge_greedy.v +++ b/utils/testbench/testbench_umi_packet_merge_greedy.v @@ -56,7 +56,7 @@ module testbench #( wire [ODW-1:0] umi_dut2check_data; reg umi_dut2check_ready; - always @(posedge clk) begin + always @(posedge clk or negedge nreset) begin if(~nreset) umi_dut2check_ready <= 1'b0; else