diff options
author | Pavel V. Shatov (Meister) <meisterpaul1@yandex.ru> | 2019-10-21 13:04:07 +0300 |
---|---|---|
committer | Pavel V. Shatov (Meister) <meisterpaul1@yandex.ru> | 2019-10-21 13:04:07 +0300 |
commit | 72902f5b40ac695786f5103d2a5a456c6c7ee83f (patch) | |
tree | 59a644e74fa4fdc25c92b8d261150ef4899323f5 /bench | |
parent | 9eac252242c69e51a38a9a88c87b564dd40b6257 (diff) |
Redesigned the testbench. Core clock does not necessarily need to be twice
faster than the bus clock now. It can be the same, or say four times faster.
Diffstat (limited to 'bench')
-rw-r--r-- | bench/tb_core_full_512.v | 294 |
1 files changed, 184 insertions, 110 deletions
diff --git a/bench/tb_core_full_512.v b/bench/tb_core_full_512.v index 221a2c6..75accff 100644 --- a/bench/tb_core_full_512.v +++ b/bench/tb_core_full_512.v @@ -31,6 +31,7 @@ module tb_core_full_512; reg [31:0] Q_FACTOR[0:TB_NUM_WORDS_PQ-1]; reg [31:0] P_COEFF[0:TB_NUM_WORDS_PQ]; reg [31:0] Q_COEFF[0:TB_NUM_WORDS_PQ]; + reg [31:0] D[0:TB_NUM_WORDS_N-1]; reg [31:0] DP[0:TB_NUM_WORDS_PQ-1]; reg [31:0] DQ[0:TB_NUM_WORDS_PQ-1]; reg [31:0] QINV[0:TB_NUM_WORDS_PQ-1]; @@ -81,6 +82,10 @@ module tb_core_full_512; Q_COEFF[ 0] = 32'h5eee9ecd; Q_COEFF[ 1] = 32'h085153b0; Q_COEFF[ 2] = 32'h85326da6; Q_COEFF[ 3] = 32'h7521931a; Q_COEFF[ 4] = 32'h99e0eef1; Q_COEFF[ 5] = 32'ha219917b; Q_COEFF[ 6] = 32'he8e9087a; Q_COEFF[ 7] = 32'h5239d12b; Q_COEFF[ 8] = 32'h0000ed92; + D[ 0] = 32'hf127ca41; D[ 1] = 32'hc4975ff0; D[ 2] = 32'h69ebbe13; D[ 3] = 32'h66fe0018; + D[ 4] = 32'hf2089237; D[ 5] = 32'hfa3f05ab; D[ 6] = 32'h2ab183c4; D[ 7] = 32'h1e4b3c04; + D[ 8] = 32'ha67974e8; D[ 9] = 32'ha6714d63; D[ 10] = 32'hfe5cd801; D[ 11] = 32'h13f2071a; + D[ 12] = 32'h0b978309; D[ 13] = 32'hb0ddb4a0; D[ 14] = 32'ha437a2cc; D[ 15] = 32'h2391b2fb; DP[ 0] = 32'h3891ed91; DP[ 1] = 32'h775046c2; DP[ 2] = 32'h60180c26; DP[ 3] = 32'h5130700a; DP[ 4] = 32'hb13c8216; DP[ 5] = 32'h833fcf78; DP[ 6] = 32'h7ab89b12; DP[ 7] = 32'hb976758c; DQ[ 0] = 32'h28cc59ad; DQ[ 1] = 32'h3ce6ed45; DQ[ 2] = 32'ha1f53aeb; DQ[ 3] = 32'h06ca05e1; @@ -100,26 +105,45 @@ module tb_core_full_512; S[ 8] = 32'h2854a51a; S[ 9] = 32'h0245619b; S[ 10] = 32'hfb67ef8f; S[ 11] = 32'hcc5bdd4f; S[ 12] = 32'ha70f58bd; S[ 13] = 32'h31f15702; S[ 14] = 32'hd6f36259; S[ 15] = 32'h280e67e0; end - // // Clocks // - `define CLK_FREQUENCY_MHZ (100.0) - `define CLK_PERIOD_NS (1000.0 / `CLK_FREQUENCY_MHZ) - `define CLK_PERIOD_HALF_NS (0.5 * `CLK_PERIOD_NS) + `define CLK_FREQUENCY_MHZ (100.0) + `define CLK_PERIOD_NS (1000.0 / `CLK_FREQUENCY_MHZ) + `define CLK_PERIOD_HALF_NS (0.5 * `CLK_PERIOD_NS) + `define CLK_PERIOD_QUARTER_NS (0.5 * `CLK_PERIOD_HALF_NS) - `define CLK_BUS_FREQUENCY_MHZ (50.0) - `define CLK_BUS_PERIOD_NS (1000.0 / `CLK_BUS_FREQUENCY_MHZ) - `define CLK_BUS_PERIOD_HALF_NS (0.5 * `CLK_BUS_PERIOD_NS) - - reg clk = 1'b1; - reg clk_bus = 1'b0; + `define CLK_BUS_FREQUENCY_MHZ (25.0) + `define CLK_BUS_PERIOD_NS (1000.0 / `CLK_BUS_FREQUENCY_MHZ) + `define CLK_BUS_PERIOD_HALF_NS (0.5 * `CLK_BUS_PERIOD_NS) + + reg clk = 1'b1; + reg clk_dly = 1'b0; + wire clk_idle = clk & clk_dly; + + reg clk_bus = 1'b1; + reg clk_bus_dly = 1'b0; + wire clk_bus_idle = clk_bus & clk_bus_dly; - always #`CLK_PERIOD_HALF_NS clk = ~clk; + always #`CLK_PERIOD_HALF_NS clk <= ~clk; + always #`CLK_BUS_PERIOD_HALF_NS clk_bus <= ~clk_bus; + + always @(clk ) clk_dly <= #(`CLK_PERIOD_HALF_NS - `CLK_PERIOD_QUARTER_NS) clk; + always @(clk_bus) clk_bus_dly <= #(`CLK_BUS_PERIOD_HALF_NS - `CLK_PERIOD_QUARTER_NS) clk_bus; + + + // + // Clock Sync + // + task sync_clk; + while (clk_idle !== 1) _wait_quarter_clk_tick; + endtask - always #`CLK_BUS_PERIOD_HALF_NS clk_bus = ~clk_bus; + task sync_clk_bus; + while (clk_bus_idle !== 1) _wait_quarter_clk_tick; + endtask // @@ -143,7 +167,6 @@ module tb_core_full_512; // // System Bus // - reg bus_ready; reg bus_cs = 1'b0; reg bus_we = 1'b0; reg [11:0] bus_addr; @@ -185,67 +208,102 @@ module tb_core_full_512; // - // Routine (Bus) + // Bus Init Routine // - initial begin - - bus_ready = 1'b0; + task core_set_input; + begin + core_set_input_1; + core_set_input_2; + wait_clk_bus_ticks(10); + $display("Core input banks written."); + end + endtask - while (rst) wait_clock_bus_tick; - wait_clock_bus_ticks(10); - $display("Core came out of reset."); - - set_input_1; - set_input_2; - - wait_clock_bus_ticks(10); - bus_ready = 1'b1; - end + // + // Script + // + initial main; // - // Routine (Control/Status, Bus) + // Main Routine (Control/Status, Bus) // - initial begin - - _wait_half_clock_tick; - wait_clock_ticks(100); - rst = 1'b0; - - while (!bus_ready) wait_clock_tick; - wait_clock_ticks(10); - $display("Core input banks written."); - - word_index_last_n = CORE_NUM_WORDS_N - 1; - word_index_last_pq = CORE_NUM_WORDS_PQ - 1; - - bit_index_last_n = TB_MODULUS_LENGTH_N - 1; - bit_index_last_pq = TB_MODULUS_LENGTH_N / 2 - 1; + task main; + begin - core_crt_mode = 1'b1; + sync_clk; // switch to fast core clock + core_reset; // reset core + core_set_params; // set parameters (modulus width, exponent length) - core_next = 1'b1; - wait_clock_tick; - core_next = 1'b0; - $display("Pulsed 'next' control signal."); + sync_clk_bus; // switch to slow bus clock + core_set_input; // write to core input banks + /* + sync_clk; // switch to fast core clock + core_set_crt_mode(1); // enable CRT signing + core_pulse_next; // assert 'next' bit for one cycle + core_wait_valid; // wait till 'valid' bit gets asserted + + sync_clk_bus; // switch to slow bus clock + core_get_output; // read from core output banks + core_verify_output; // check, whether core output matches precomputed known good refrence values + */ + sync_clk; // switch to fast core clock + core_set_crt_mode(0); // disable CRT signing + core_pulse_next; // assert 'next' bit for one cycle + core_wait_valid; // wait till 'valid' bit gets asserted + + sync_clk_bus; // switch to slow bus clock + core_get_output; // read from core output banks + core_verify_output; // check, whether core output matches precomputed known good refrence values + end + endtask - while (!core_valid) wait_clock_tick; - wait_clock_ticks(10); - - $display("Detected high 'valid' status signal."); - core_crt_mode = 1'bX; - - wait_clock_ticks(10); - get_output; - wait_clock_ticks(10); - - $display("Core output banks read."); - - verify; + task core_reset; + begin + wait_clk_ticks(100); + rst = 1'b0; + wait_clk_ticks(10); + $display("Core reset finished."); + end + endtask - end + task core_set_params; + begin + word_index_last_n = CORE_NUM_WORDS_N - 1; + word_index_last_pq = CORE_NUM_WORDS_PQ - 1; + bit_index_last_n = TB_MODULUS_LENGTH_N - 1; + bit_index_last_pq = TB_MODULUS_LENGTH_N / 2 - 1; + $display("Core parameters set."); + end + endtask + task core_set_crt_mode; + input _crt; + begin + core_crt_mode = _crt; + if (_crt) $display("Enabled CRT mode."); + else $display("Disabled CRT mode."); + end + endtask + + task core_pulse_next; + begin + core_next = 1'b1; + wait_clk_tick; + core_next = 1'b0; + $display("Pulsed core 'next' control signal."); + end + endtask + + task core_wait_valid; + begin + while (!core_valid) wait_clk_tick; + wait_clk_ticks(10); + $display("Detected high core 'valid' status signal."); + end + endtask + // // Variables @@ -254,58 +312,61 @@ module tb_core_full_512; // - // set_input_1; + // core_set_input_1 // - task set_input_1; - reg [9:0] _tn; + task core_set_input_1; + reg [9:0] _tn; + reg [31:0] zzz; begin _tn = BANK_IN_1_N_COEFF * 2 ** BUS_OP_ADDR_W + TB_NUM_WORDS_N; // trick to write extra trailer word - for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_write(2'd0, BANK_IN_1_M, _w[6:0], M[_w]); - for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_write(2'd0, BANK_IN_1_N, _w[6:0], N[_w]); - for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_write(2'd0, BANK_IN_1_N_FACTOR, _w[6:0], N_FACTOR[_w]); - for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_write(2'd0, BANK_IN_1_N_COEFF, _w[6:0], N_COEFF[_w]); - bus_write(2'd0, _tn[9:7], _tn[6:0], N_COEFF[TB_NUM_WORDS_N]); - for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_write(2'd0, BANK_IN_1_X, _w[6:0], X[_w]); - for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_write(2'd0, BANK_IN_1_Y, _w[6:0], Y[_w]); + for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_write(2'd1, BANK_IN_1_M, _w[6:0], M[_w]); + for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_write(2'd1, BANK_IN_1_N, _w[6:0], N[_w]); + for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_write(2'd1, BANK_IN_1_N_FACTOR, _w[6:0], N_FACTOR[_w]); + for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_write(2'd1, BANK_IN_1_N_COEFF, _w[6:0], N_COEFF[_w]); + bus_write(2'd1, _tn[9:7], _tn[6:0], N_COEFF[TB_NUM_WORDS_N]); + for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_write(2'd1, BANK_IN_1_X, _w[6:0], X[_w]); + for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_write(2'd1, BANK_IN_1_Y, _w[6:0], Y[_w]); end endtask // - // set_input_2; + // core_set_input_2 // - task set_input_2; + task core_set_input_2; begin -// for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_write(2'd0, BANK_IN_1_M, _w[6:0], M[_w]); - for (_w=0; _w< TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd1, BANK_IN_2_P, {1'b0, _w[5:0]}, P [_w]); - for (_w=0; _w< TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd1, BANK_IN_2_P, {1'b1, _w[5:0]}, DP [_w]); - for (_w=0; _w< TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd1, BANK_IN_2_P_FACTOR, { _w[6:0]}, P_FACTOR[_w]); - for (_w=0; _w<=TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd1, BANK_IN_2_P_COEFF, { _w[6:0]}, P_COEFF [_w]); - for (_w=0; _w< TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd1, BANK_IN_2_Q, {1'b0, _w[5:0]}, Q [_w]); - for (_w=0; _w< TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd1, BANK_IN_2_Q, {1'b1, _w[5:0]}, DQ [_w]); - for (_w=0; _w< TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd1, BANK_IN_2_Q_FACTOR, { _w[6:0]}, Q_FACTOR[_w]); - for (_w=0; _w<=TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd1, BANK_IN_2_Q_COEFF, { _w[6:0]}, Q_COEFF [_w]); - for (_w=0; _w< TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd1, BANK_IN_2_QINV, { _w[6:0]}, QINV [_w]); + //for (_w=0; _w< TB_NUM_WORDS_N; _w=_w+1) bus_write(2'd2, BANK_IN_2_D, { _w[6:0]}, D [_w]); + for (_w=0; _w< TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd2, BANK_IN_2_P, {1'b0, _w[5:0]}, P [_w]); + for (_w=0; _w< TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd2, BANK_IN_2_P, {1'b1, _w[5:0]}, DP [_w]); + for (_w=0; _w< TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd2, BANK_IN_2_P_FACTOR, { _w[6:0]}, P_FACTOR[_w]); + for (_w=0; _w<=TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd2, BANK_IN_2_P_COEFF, { _w[6:0]}, P_COEFF [_w]); + for (_w=0; _w< TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd2, BANK_IN_2_Q, {1'b0, _w[5:0]}, Q [_w]); + for (_w=0; _w< TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd2, BANK_IN_2_Q, {1'b1, _w[5:0]}, DQ [_w]); + for (_w=0; _w< TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd2, BANK_IN_2_Q_FACTOR, { _w[6:0]}, Q_FACTOR[_w]); + for (_w=0; _w<=TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd2, BANK_IN_2_Q_COEFF, { _w[6:0]}, Q_COEFF [_w]); + for (_w=0; _w< TB_NUM_WORDS_PQ; _w=_w+1) bus_write(2'd2, BANK_IN_2_QINV, { _w[6:0]}, QINV [_w]); end endtask // - // get_output; + // core_get_output // - task get_output; + task core_get_output; begin - for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_read(2'd2, BANK_OUT_XM, _w[6:0], XM_READBACK[_w]); - for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_read(2'd2, BANK_OUT_YM, _w[6:0], YM_READBACK[_w]); - for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_read(2'd2, BANK_OUT_S, _w[6:0], S_READBACK[_w]); + for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_read(2'd3, BANK_OUT_XM, _w[6:0], XM_READBACK[_w]); + for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_read(2'd3, BANK_OUT_YM, _w[6:0], YM_READBACK[_w]); + for (_w=0; _w<TB_NUM_WORDS_N; _w=_w+1) bus_read(2'd3, BANK_OUT_S, _w[6:0], S_READBACK[_w]); + wait_clk_bus_ticks(10); + $display("Core output banks read."); end endtask // - // verify; + // core_verify_output // - task verify; + task core_verify_output; // reg xm_ok; reg ym_ok; @@ -387,7 +448,7 @@ module tb_core_full_512; input [31:0] data; begin _bus_drive(1'b1, 1'b1, {sel, bank, addr}, data); - wait_clock_bus_tick; + wait_clk_bus_tick; _bus_drive(1'b0, 1'b0, 12'hXXX, 32'hXXXXXXXX); end endtask @@ -403,7 +464,7 @@ module tb_core_full_512; output [31:0] data; begin _bus_drive(1'b1, 1'b0, {sel, bank, addr}, 32'hXXXXXXXX); - wait_clock_bus_tick; + wait_clk_bus_tick; data = bus_data_rd; _bus_drive(1'b0, 1'b0, 12'hXXX, 32'hXXXXXXXX); end @@ -411,48 +472,61 @@ module tb_core_full_512; // - // _wait_half_clock_tick() + // _wait_quarter_clk_tick() // - task _wait_half_clock_tick; - #`CLK_PERIOD_HALF_NS; + task _wait_quarter_clk_tick; + #`CLK_PERIOD_QUARTER_NS; endtask + // - // wait_clock_tick() + // _wait_half_clk_tick() // - task wait_clock_tick; + task _wait_half_clk_tick; begin - _wait_half_clock_tick; - _wait_half_clock_tick; + _wait_quarter_clk_tick; + _wait_quarter_clk_tick; end endtask // - // wait_clock_bus_tick() + // wait_clk_tick() // - task wait_clock_bus_tick; + task wait_clk_tick; + begin + _wait_half_clk_tick; + _wait_half_clk_tick; + end + endtask + + + // + // wait_clk_bus_tick() + // + task wait_clk_bus_tick; #`CLK_BUS_PERIOD_NS; endtask // - // wait_clock_ticks() + // wait_clk_ticks() // - task wait_clock_ticks; + task wait_clk_ticks; input integer num_ticks; for (_n=0; _n<num_ticks; _n=_n+1) - wait_clock_tick; + wait_clk_tick; endtask - + // - // wait_clock_bus_ticks() + // wait_clk_bus_ticks() // - task wait_clock_bus_ticks; + task wait_clk_bus_ticks; input integer num_ticks; for (_n=0; _n<num_ticks; _n=_n+1) - wait_clock_bus_tick; + wait_clk_bus_tick; endtask - + + endmodule |