From 051f3e68b557a8af4987f54e396896263d3a80b2 Mon Sep 17 00:00:00 2001 From: bsdevlin Date: Tue, 12 Mar 2019 23:48:28 -0400 Subject: [PATCH] Update to top level with interface and test bench --- ip_cores/fifo/src/rtl/axi_stream_fifo.sv | 2 +- ip_cores/fifo/src/rtl/cdc_fifo.sv | 34 +++++++++++++----- ip_cores/util/src/rtl/packet_arb.sv | 31 +++++++++++----- zcash_fpga/src/rtl/control/control_top.sv | 13 +++---- zcash_fpga/src/tb/zcash_fpga_top_tb.sv | 44 ++++++++++++++--------- 5 files changed, 84 insertions(+), 40 deletions(-) diff --git a/ip_cores/fifo/src/rtl/axi_stream_fifo.sv b/ip_cores/fifo/src/rtl/axi_stream_fifo.sv index 68fc9fa..9daf9cb 100644 --- a/ip_cores/fifo/src/rtl/axi_stream_fifo.sv +++ b/ip_cores/fifo/src/rtl/axi_stream_fifo.sv @@ -93,7 +93,7 @@ endgenerate // Control for full and empty, and assigning outputs from the ram always_comb begin - i_axi.rdy = ~o_full; + i_axi.rdy = ~o_full && ~i_rst; o_axi.dat = data_out[0 +: DAT_BITS]; o_axi.ctl = data_out[DAT_BITS +: CTL_BITS]; diff --git a/ip_cores/fifo/src/rtl/cdc_fifo.sv b/ip_cores/fifo/src/rtl/cdc_fifo.sv index 9ef597a..6674313 100644 --- a/ip_cores/fifo/src/rtl/cdc_fifo.sv +++ b/ip_cores/fifo/src/rtl/cdc_fifo.sv @@ -22,7 +22,8 @@ module cdc_fifo #( parameter SIZE = 4, // Needs to be a power of 2 parameter DAT_BITS = 8, - parameter USE_BRAM = 0 // If using BRAM there is an extra cycle delay between reads + parameter USE_BRAM = 0, // If using BRAM there is an extra cycle delay between reads + parameter RAM_PERFORMANCE = "HIGH_PERFORMANCE" ) ( input i_clk_a, i_rst_a, input i_clk_b, i_rst_b, @@ -74,26 +75,41 @@ generate end else begin logic [DAT_BITS-1:0] dat_b; + logic [1:0] read_cyc; if_ram #(.RAM_WIDTH(DAT_BITS), .RAM_DEPTH(SIZE)) bram_if_rd (i_clk_b, i_rst_b); if_ram #(.RAM_WIDTH(DAT_BITS), .RAM_DEPTH(SIZE)) bram_if_wr (i_clk_a, i_rst_a); bram #( - .RAM_WIDTH ( DAT_BITS ), - .RAM_DEPTH ( SIZE ), - .RAM_PERFORMANCE ( "LOW_LATENCY" ) + .RAM_WIDTH ( DAT_BITS ), + .RAM_DEPTH ( SIZE ), + .RAM_PERFORMANCE ( RAM_PERFORMANCE ) ) bram_i ( .a ( bram_if_rd ), .b ( bram_if_wr ) ); - + always_ff @ (posedge i_clk_b) begin - o_val_b <= 0; - if (~o_emp_b) o_val_b <= 1; - if (o_val_b && i_rdy_b) o_val_b <= 0; + if (i_rst_b) begin + read_cyc <= 0; + o_val_b <= 0; + end else begin + read_cyc <= read_cyc << 1; + o_val_b <= 0; + if (~o_emp_b) o_val_b <= 1; + + if (o_val_b && i_rdy_b) begin + o_val_b <= 0; + read_cyc[0] <= 1; + end + if (RAM_PERFORMANCE == "HIGH_PERFORMANCE" && read_cyc[0]) + o_val_b <= 0; + + end end always_comb begin + bram_if_rd.re = 1; bram_if_rd.a = rd_ptr_b[ABITS-1:0]; bram_if_rd.d = 0; @@ -144,7 +160,7 @@ always_comb begin end always_comb begin - o_rdy_a = ~o_full_a; + o_rdy_a = ~o_full_a && ~i_rst_a; o_rd_wrds_b = o_emp_b ? (1 << ABITS) : wr_ptr_b[ABITS-1:0] - rd_ptr_b[ABITS-1:0]; end diff --git a/ip_cores/util/src/rtl/packet_arb.sv b/ip_cores/util/src/rtl/packet_arb.sv index 568a364..c0e170a 100644 --- a/ip_cores/util/src/rtl/packet_arb.sv +++ b/ip_cores/util/src/rtl/packet_arb.sv @@ -18,6 +18,8 @@ */ module packet_arb # ( + parameter DAT_BYTS, + parameter CTL_BITS, parameter NUM_IN ) ( input i_clk, i_rst, @@ -26,10 +28,16 @@ module packet_arb # ( if_axi_stream.source o_axi ); +localparam DAT_BITS = DAT_BYTS*8; +localparam MOD_BITS = $clog2(DAT_BYTS); + logic [$clog2(NUM_IN)-1:0] idx; logic locked; -logic [NUM_IN-1:0] rdy, val, eop; +logic [NUM_IN-1:0] rdy, val, eop, sop, err; +logic [NUM_IN-1:0][DAT_BITS-1:0] dat; +logic [NUM_IN-1:0][MOD_BITS-1:0] mod; +logic [NUM_IN-1:0][CTL_BITS-1:0] ctl; generate genvar g; @@ -38,21 +46,28 @@ generate i_axi[g].rdy = rdy[g]; val[g] = i_axi[g].val; eop[g] = i_axi[g].eop; + sop[g] = i_axi[g].sop; + err[g] = i_axi[g].err; + dat[g] = i_axi[g].dat; + mod[g] = i_axi[g].mod; + ctl[g] = i_axi[g].ctl; end - - always_ff @ (posedge i_clk) begin - if(g == idx) - o_axi.copy_if(i_axi[g].to_struct()); - end - - end + end endgenerate always_comb begin rdy = 0; rdy[idx] = o_axi.rdy; + o_axi.dat = dat[idx]; + o_axi.mod = mod[idx]; + o_axi.ctl = ctl[idx]; + o_axi.val = val[idx]; + o_axi.err = err[idx]; + o_axi.sop = sop[idx]; + o_axi.eop = eop[idx]; end +// Logic to arbitrate is registered always_ff @ (posedge i_clk) begin if (i_rst) begin locked <= 0; diff --git a/zcash_fpga/src/rtl/control/control_top.sv b/zcash_fpga/src/rtl/control/control_top.sv index 6cdb0d4..43cc503 100644 --- a/zcash_fpga/src/rtl/control/control_top.sv +++ b/zcash_fpga/src/rtl/control/control_top.sv @@ -82,7 +82,7 @@ fpga_state_t fpga_state; always_comb begin fpga_state = 0; fpga_state.error = 0; - fpga_state.typ1_state = TYP1_IDLE; + fpga_state.typ1_state = typ1_msg_state; header = rx_int_if.dat; header0 = rx_typ0_if.dat; header1 = rx_typ1_if.dat; @@ -199,10 +199,9 @@ always_ff @ (posedge i_clk_core) begin equihash_index_val <= 0; sop_l <= 0; end else begin - rx_typ1_if.rdy <= 1; case (typ1_msg_state) - TYP1_IDLE: begin + rx_typ1_if_rdy <= 1; verify_equihash_rpl_val <= 0; equihash_index_val <= 0; sop_l <= 0; @@ -342,7 +341,7 @@ width_change_cdc_fifo #( .IN_DAT_BYTS ( IN_DAT_BYTS ), .OUT_DAT_BYTS ( CORE_DAT_BYTS ), .CTL_BITS ( 8 ), - .FIFO_ABITS ( $clog2(16*1024/IN_DAT_BITS) ), + .FIFO_ABITS ( $clog2(1024/IN_DAT_BITS) ), .USE_BRAM ( 1 ) ) cdc_fifo_rx ( @@ -356,7 +355,9 @@ cdc_fifo_rx ( // Arbitrator for sending messages back packet_arb # ( - .NUM_IN ( 2 ) + .NUM_IN ( 2 ), + .DAT_BYTS ( CORE_DAT_BYTS ), + .CTL_BITS ( 8 ) ) packet_arb_tx ( .i_clk ( i_clk_core ), @@ -371,7 +372,7 @@ width_change_cdc_fifo #( .IN_DAT_BYTS ( CORE_DAT_BYTS ), .OUT_DAT_BYTS ( IN_DAT_BYTS ), .CTL_BITS ( 8 ), - .FIFO_ABITS ( $clog2(16*1024/CORE_DAT_BYTS) ), + .FIFO_ABITS ( $clog2(1024/CORE_DAT_BYTS) ), .USE_BRAM ( 1 ) ) cdc_fifo_tx ( diff --git a/zcash_fpga/src/tb/zcash_fpga_top_tb.sv b/zcash_fpga/src/tb/zcash_fpga_top_tb.sv index eeaf482..66502d1 100644 --- a/zcash_fpga/src/tb/zcash_fpga_top_tb.sv +++ b/zcash_fpga/src/tb/zcash_fpga_top_tb.sv @@ -123,54 +123,66 @@ DUT( ); // This is a tests the sample block 346 in the block chain with the header to verify the equihash solution -// Also send a status request to check it is correct +// Also send a reset first and then status request to check it is correct task test_block_346_equihash(); begin header_t header; fpga_status_rpl_t fpga_status_rpl; + fpga_reset_rpl_t fpga_reset_rpl; verify_equihash_rpl_t verify_equihash_rpl; - integer signed get_len1, get_len2; - logic [common_pkg::MAX_SIM_BYTS*8-1:0] get_dat1, get_dat2; + integer signed get_len1, get_len2, get_len3; + logic [common_pkg::MAX_SIM_BYTS*8-1:0] get_dat1, get_dat2, get_dat3; logic fail = 0; $display("Running test_block_346_equihash..."); - header.cmd = FPGA_STATUS; - header.len = $bits(header_t)/8; - fork begin + // First send reset + header.cmd = RESET_FPGA; + header.len = $bits(header_t)/8; + tx_if.put_stream(header, $bits(header)/8); + // Wait for tx_if.rdy to go low (reset started) + while (tx_if.rdy) @(posedge tx_if.i_clk); + // Then send data start_346 = 1; while(!done_346) @(posedge clk_if); + // Then status request + header.cmd = FPGA_STATUS; + header.len = $bits(header_t)/8; tx_if.put_stream(header, $bits(header)/8); end begin - rx_if.get_stream(get_dat1, get_len1); - rx_if.get_stream(get_dat2, get_len2); + rx_if.get_stream(get_dat1, get_len1); // reset rpl + rx_if.get_stream(get_dat2, get_len2); // status rpl + rx_if.get_stream(get_dat3, get_len3); // equihash rpl end join - verify_equihash_rpl = get_dat2; - fpga_status_rpl = get_dat1; + fpga_reset_rpl = get_dat1; + verify_equihash_rpl = get_dat3; + fpga_status_rpl = get_dat2; - fail |= get_len2 != $bits(verify_equihash_rpl_t)/8; + fail |= get_len3 != $bits(verify_equihash_rpl_t)/8; fail |= verify_equihash_rpl.hdr.cmd != VERIFY_EQUIHASH_RPL; fail |= verify_equihash_rpl.hdr.len != $bits(verify_equihash_rpl_t)/8; fail |= verify_equihash_rpl.index != 1; fail |= verify_equihash_rpl.bm != 0; - assert (~fail) else $fatal(1, "%m %t ERROR: test_block_346_equihash equihash rply was wrong:\n%p", $time, verify_equihash_rpl); - fail |= get_len1 != $bits(fpga_status_rpl_t)/8; + fail |= get_len2 != $bits(fpga_status_rpl_t)/8; fail |= fpga_status_rpl.hdr.cmd != FPGA_STATUS_RPL; fail |= fpga_status_rpl.hdr.len != $bits(fpga_status_rpl_t)/8; - fail |= fpga_status_rpl.hdr.len != get_len1; + fail |= fpga_status_rpl.hdr.len != get_len2; fail |= fpga_status_rpl.version != FPGA_VERSION; fail |= fpga_status_rpl.build_host != "test"; fail |= fpga_status_rpl.build_date != "20180311"; - fail |= fpga_status_rpl.fpga_state.typ1_state == 1; - + fail |= fpga_status_rpl.fpga_state == 1; assert (~fail) else $fatal(1, "%m %t ERROR: test_block_346_equihash status reply was wrong:\n%p", $time, fpga_status_rpl); + fail |= get_len1 != $bits(fpga_reset_rpl_t)/8; + fail |= fpga_reset_rpl.hdr.cmd != RESET_FPGA_RPL; + assert (~fail) else $fatal(1, "%m %t ERROR: test_block_346_equihash reset reply was wrong:\n%p", $time, fpga_reset_rpl); + $display("test_block_346_equihash PASSED"); end