`timescale 1ns / 1ps module tb_core_full_1024; // // Headers // `include "../rtl/modexpng_parameters.vh" // // Test Vectors // localparam TB_MODULUS_LENGTH_N = 1024; localparam TB_MODULUS_LENGTH_PQ = TB_MODULUS_LENGTH_N / 2; localparam TB_NUM_WORDS_PQ = TB_MODULUS_LENGTH_PQ / BUS_DATA_W; localparam TB_NUM_WORDS_N = TB_MODULUS_LENGTH_N / BUS_DATA_W; localparam CORE_NUM_WORDS_PQ = TB_MODULUS_LENGTH_PQ / WORD_W; localparam CORE_NUM_WORDS_N = TB_MODULUS_LENGTH_N / WORD_W; reg [31:0] M[0:TB_NUM_WORDS_N-1]; reg [31:0] N[0:TB_NUM_WORDS_N-1]; reg [31:0] N_FACTOR[0:TB_NUM_WORDS_N-1]; reg [31:0] N_COEFF[0:TB_NUM_WORDS_N]; reg [31:0] X[0:TB_NUM_WORDS_N-1]; reg [31:0] Y[0:TB_NUM_WORDS_N-1]; reg [31:0] P[0:TB_NUM_WORDS_PQ-1]; reg [31:0] Q[0:TB_NUM_WORDS_PQ-1]; reg [31:0] P_FACTOR[0:TB_NUM_WORDS_PQ-1]; 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]; reg [31:0] XM[0:TB_NUM_WORDS_N-1]; reg [31:0] YM[0:TB_NUM_WORDS_N-1]; reg [31:0] S[0:TB_NUM_WORDS_N-1]; reg [31:0] XM_READBACK[0:TB_NUM_WORDS_N-1]; reg [31:0] YM_READBACK[0:TB_NUM_WORDS_N-1]; reg [31:0] S_READBACK[0:TB_NUM_WORDS_N-1]; initial begin M[ 0] = 32'he1b3c6ac; M[ 1] = 32'haa2c5d8c; M[ 2] = 32'hbecc676a; M[ 3] = 32'hda087a3e; M[ 4] = 32'hf0816496; M[ 5] = 32'hf9e17fd8; M[ 6] = 32'h304d4896; M[ 7] = 32'h81d4e9ab; M[ 8] = 32'h80eff76c; M[ 9] = 32'he5b8f9b6; M[ 10] = 32'h4b1ebe55; M[ 11] = 32'ha1feb9dc; M[ 12] = 32'heca4192f; M[ 13] = 32'h6ad6ea8e; M[ 14] = 32'hf34aed05; M[ 15] = 32'had38c275; M[ 16] = 32'h8d3b583b; M[ 17] = 32'hc370f07e; M[ 18] = 32'hb9078738; M[ 19] = 32'haf37f86c; M[ 20] = 32'h02f0e161; M[ 21] = 32'h0506a68a; M[ 22] = 32'h1ae65107; M[ 23] = 32'hcd3a97f1; M[ 24] = 32'hb27244b8; M[ 25] = 32'h9bc3c400; M[ 26] = 32'he4d5636e; M[ 27] = 32'h35187c07; M[ 28] = 32'h78a661c9; M[ 29] = 32'h1e7ec273; M[ 30] = 32'hcdc31041; M[ 31] = 32'h002291d8; N[ 0] = 32'h6719997f; N[ 1] = 32'hef2df706; N[ 2] = 32'h9ba95792; N[ 3] = 32'h747e0580; N[ 4] = 32'h7507684c; N[ 5] = 32'h7a10d0d1; N[ 6] = 32'h83a33941; N[ 7] = 32'haef9fda5; N[ 8] = 32'h17972933; N[ 9] = 32'h0a98251a; N[ 10] = 32'h7dce3d13; N[ 11] = 32'hdad49a60; N[ 12] = 32'h9f98006b; N[ 13] = 32'h46fd4a05; N[ 14] = 32'h51966e1d; N[ 15] = 32'hb1c59fab; N[ 16] = 32'h8ab3096e; N[ 17] = 32'hef1f0436; N[ 18] = 32'heeed776f; N[ 19] = 32'h106d9d82; N[ 20] = 32'hdd2a44af; N[ 21] = 32'h17c32585; N[ 22] = 32'hc854e454; N[ 23] = 32'h600fb6df; N[ 24] = 32'h25c2d4bb; N[ 25] = 32'h5f09d790; N[ 26] = 32'he5a2bb93; N[ 27] = 32'h5bc6b044; N[ 28] = 32'h2ecbb15f; N[ 29] = 32'h464817f5; N[ 30] = 32'h05cae32b; N[ 31] = 32'hde97bb85; N_FACTOR[ 0] = 32'ha06a1113; N_FACTOR[ 1] = 32'hc9974806; N_FACTOR[ 2] = 32'h572d7a20; N_FACTOR[ 3] = 32'h04000838; N_FACTOR[ 4] = 32'hb275c37a; N_FACTOR[ 5] = 32'hea78a046; N_FACTOR[ 6] = 32'h029e13b8; N_FACTOR[ 7] = 32'hae540753; N_FACTOR[ 8] = 32'h1e98bc21; N_FACTOR[ 9] = 32'h34ede47a; N_FACTOR[ 10] = 32'h0c565ecd; N_FACTOR[ 11] = 32'h027ff3bf; N_FACTOR[ 12] = 32'h08290d30; N_FACTOR[ 13] = 32'hb92857df; N_FACTOR[ 14] = 32'he6c59eb3; N_FACTOR[ 15] = 32'h09e53d6a; N_FACTOR[ 16] = 32'h980d127e; N_FACTOR[ 17] = 32'h4dd6ced0; N_FACTOR[ 18] = 32'h3b9400d0; N_FACTOR[ 19] = 32'h276c6711; N_FACTOR[ 20] = 32'h72eaf2e6; N_FACTOR[ 21] = 32'h749f81eb; N_FACTOR[ 22] = 32'h17b7d05f; N_FACTOR[ 23] = 32'h41a3a2cd; N_FACTOR[ 24] = 32'h1ba098f3; N_FACTOR[ 25] = 32'h9b884af9; N_FACTOR[ 26] = 32'hdafd920c; N_FACTOR[ 27] = 32'h7b1f5cc6; N_FACTOR[ 28] = 32'hb0a0d098; N_FACTOR[ 29] = 32'h4ee55bcf; N_FACTOR[ 30] = 32'haed9b905; N_FACTOR[ 31] = 32'h42d541fb; N_COEFF[ 0] = 32'hb383d981; N_COEFF[ 1] = 32'h9bf1c20c; N_COEFF[ 2] = 32'h268999ff; N_COEFF[ 3] = 32'h11a3c01a; N_COEFF[ 4] = 32'h12665495; N_COEFF[ 5] = 32'h515b0d96; N_COEFF[ 6] = 32'hb704fb07; N_COEFF[ 7] = 32'h8e1bd1d6; N_COEFF[ 8] = 32'h62c5f506; N_COEFF[ 9] = 32'hfdcd0163; N_COEFF[ 10] = 32'h8dd55dee; N_COEFF[ 11] = 32'h6d79c8b1; N_COEFF[ 12] = 32'hca16d0b9; N_COEFF[ 13] = 32'h88bead48; N_COEFF[ 14] = 32'hbcdb1e94; N_COEFF[ 15] = 32'h950c171d; N_COEFF[ 16] = 32'h4fa810af; N_COEFF[ 17] = 32'h9b63e6d2; N_COEFF[ 18] = 32'ha2d0c26b; N_COEFF[ 19] = 32'hafa1ef25; N_COEFF[ 20] = 32'h111bd21e; N_COEFF[ 21] = 32'hc2d896f0; N_COEFF[ 22] = 32'h189dc2cf; N_COEFF[ 23] = 32'h6144156a; N_COEFF[ 24] = 32'hd1c67123; N_COEFF[ 25] = 32'ha127e4f3; N_COEFF[ 26] = 32'h40d342ef; N_COEFF[ 27] = 32'hee476d42; N_COEFF[ 28] = 32'hee05f26a; N_COEFF[ 29] = 32'h4fc717bd; N_COEFF[ 30] = 32'h6baa4d60; N_COEFF[ 31] = 32'h1d6b10db; N_COEFF[ 32] = 32'h00006545; X[ 0] = 32'ha838f053; X[ 1] = 32'h8eb9747c; X[ 2] = 32'h5991b9eb; X[ 3] = 32'h74e6e776; X[ 4] = 32'hcb5aa9e2; X[ 5] = 32'h7f8083d4; X[ 6] = 32'h3f7d47ec; X[ 7] = 32'hbd76a787; X[ 8] = 32'hf4c166b7; X[ 9] = 32'hdbf67229; X[ 10] = 32'h975a5cfb; X[ 11] = 32'he8c35dca; X[ 12] = 32'h6abc86e8; X[ 13] = 32'hfee472cb; X[ 14] = 32'h83ac8f2e; X[ 15] = 32'h82825cff; X[ 16] = 32'h2d532c22; X[ 17] = 32'h2d3c3b06; X[ 18] = 32'he2862a8f; X[ 19] = 32'he8616ce4; X[ 20] = 32'h5d77ee51; X[ 21] = 32'he609de07; X[ 22] = 32'hef718044; X[ 23] = 32'h82f35f8b; X[ 24] = 32'hcdb9dcfe; X[ 25] = 32'hff6ea364; X[ 26] = 32'h0994ae28; X[ 27] = 32'h409b369b; X[ 28] = 32'hcfabda4e; X[ 29] = 32'h5cd52bbc; X[ 30] = 32'hd90e1715; X[ 31] = 32'h00f4dcf2; Y[ 0] = 32'h01b2730a; Y[ 1] = 32'h04ff1664; Y[ 2] = 32'h6d55dc06; Y[ 3] = 32'h1cda0da7; Y[ 4] = 32'h98c812b4; Y[ 5] = 32'ha8f79f3b; Y[ 6] = 32'hb18d9ee1; Y[ 7] = 32'ha53e97db; Y[ 8] = 32'hfbbfd687; Y[ 9] = 32'h6b8a8bf6; Y[ 10] = 32'h59fe5575; Y[ 11] = 32'he6ee62ca; Y[ 12] = 32'h9fe3f32a; Y[ 13] = 32'h6d758eaa; Y[ 14] = 32'h121e3dac; Y[ 15] = 32'h31d77884; Y[ 16] = 32'h8f2701dd; Y[ 17] = 32'hca5e7ac3; Y[ 18] = 32'h731977a3; Y[ 19] = 32'hc3c1af70; Y[ 20] = 32'h5606786a; Y[ 21] = 32'h94b71191; Y[ 22] = 32'hd044c7e2; Y[ 23] = 32'h7d899cd7; Y[ 24] = 32'hb17d4f5d; Y[ 25] = 32'h446e04de; Y[ 26] = 32'h9c40b33d; Y[ 27] = 32'habc2e23e; Y[ 28] = 32'hbb98b1f6; Y[ 29] = 32'hf1f87f7e; Y[ 30] = 32'hf19f3050; Y[ 31] = 32'h91305f4c; P[ 0] = 32'h18bb0f97; P[ 1] = 32'h08588a44; P[ 2] = 32'h042c6647; P[ 3] = 32'hc8d3fa09; P[ 4] = 32'he2ddbbc7; P[ 5] = 32'hef4a17fd; P[ 6] = 32'h90c102ef; P[ 7] = 32'h28b132db; P[ 8] = 32'hebfd5f0a; P[ 9] = 32'h958717ca; P[ 10] = 32'h563cd266; P[ 11] = 32'h433f41af; P[ 12] = 32'hbc198e83; P[ 13] = 32'h5b5300b2; P[ 14] = 32'h9bc50e5d; P[ 15] = 32'hefffa822; Q[ 0] = 32'h25de0259; Q[ 1] = 32'hd81461d0; Q[ 2] = 32'h613815b3; Q[ 3] = 32'h9bf274e0; Q[ 4] = 32'hbfd89a48; Q[ 5] = 32'hc53e71ac; Q[ 6] = 32'hcce7aed3; Q[ 7] = 32'hce1d017c; Q[ 8] = 32'h646547e1; Q[ 9] = 32'hd6779694; Q[ 10] = 32'h20ae39c0; Q[ 11] = 32'hef0d4b5b; Q[ 12] = 32'h8e5f59d6; Q[ 13] = 32'h7e267974; Q[ 14] = 32'h14c86644; Q[ 15] = 32'hed6efcd0; P_FACTOR[ 0] = 32'h614f99ce; P_FACTOR[ 1] = 32'hbcee5381; P_FACTOR[ 2] = 32'h10b70a9a; P_FACTOR[ 3] = 32'h1a697756; P_FACTOR[ 4] = 32'h1a972b27; P_FACTOR[ 5] = 32'hd7c43f9e; P_FACTOR[ 6] = 32'h48cbad9c; P_FACTOR[ 7] = 32'hc350e206; P_FACTOR[ 8] = 32'h51098b50; P_FACTOR[ 9] = 32'h93388ec6; P_FACTOR[ 10] = 32'h548960b5; P_FACTOR[ 11] = 32'h5ecd6b04; P_FACTOR[ 12] = 32'h04d1d543; P_FACTOR[ 13] = 32'ha53994af; P_FACTOR[ 14] = 32'hd390be70; P_FACTOR[ 15] = 32'h0acdced0; Q_FACTOR[ 0] = 32'h8a19423f; Q_FACTOR[ 1] = 32'h9d729c78; Q_FACTOR[ 2] = 32'h26ed5239; Q_FACTOR[ 3] = 32'h5a7eba92; Q_FACTOR[ 4] = 32'h8465f60f; Q_FACTOR[ 5] = 32'hd50817dd; Q_FACTOR[ 6] = 32'hba703ab1; Q_FACTOR[ 7] = 32'h3d59bd42; Q_FACTOR[ 8] = 32'h2c197fcc; Q_FACTOR[ 9] = 32'hed14f573; Q_FACTOR[ 10] = 32'hb860c105; Q_FACTOR[ 11] = 32'h89af91e7; Q_FACTOR[ 12] = 32'h13a3742d; Q_FACTOR[ 13] = 32'h96e41677; Q_FACTOR[ 14] = 32'h86506b4d; Q_FACTOR[ 15] = 32'h4a834535; P_COEFF[ 0] = 32'hb3679fd9; P_COEFF[ 1] = 32'hde24e467; P_COEFF[ 2] = 32'hf0e82022; P_COEFF[ 3] = 32'h99012919; P_COEFF[ 4] = 32'h023bda43; P_COEFF[ 5] = 32'hf04eebf8; P_COEFF[ 6] = 32'h29e9942f; P_COEFF[ 7] = 32'h8c257cb0; P_COEFF[ 8] = 32'h5cdc4e60; P_COEFF[ 9] = 32'h279bdff7; P_COEFF[ 10] = 32'hf04a610d; P_COEFF[ 11] = 32'h342901dc; P_COEFF[ 12] = 32'hc3e2f78c; P_COEFF[ 13] = 32'h39c00ed8; P_COEFF[ 14] = 32'hf7032ac2; P_COEFF[ 15] = 32'h22d9c54e; P_COEFF[ 16] = 32'h0000f994; Q_COEFF[ 0] = 32'h95beda17; Q_COEFF[ 1] = 32'ha4b101fa; Q_COEFF[ 2] = 32'hd0b854bc; Q_COEFF[ 3] = 32'h5c952a67; Q_COEFF[ 4] = 32'h56722aa8; Q_COEFF[ 5] = 32'h2176cace; Q_COEFF[ 6] = 32'h69beef2d; Q_COEFF[ 7] = 32'h95bf6eb2; Q_COEFF[ 8] = 32'h0cf1175c; Q_COEFF[ 9] = 32'h4911b74e; Q_COEFF[ 10] = 32'h331e61cb; Q_COEFF[ 11] = 32'he9527ead; Q_COEFF[ 12] = 32'h8d6a5911; Q_COEFF[ 13] = 32'hae42d654; Q_COEFF[ 14] = 32'he10d29a8; Q_COEFF[ 15] = 32'h50a5dd76; Q_COEFF[ 16] = 32'h0000ed75; D[ 0] = 32'h6d4e7831; D[ 1] = 32'ha96f72d6; D[ 2] = 32'h3b47788f; D[ 3] = 32'h07207984; D[ 4] = 32'h3247b99f; D[ 5] = 32'hfe6ade84; D[ 6] = 32'h0e0fdec4; D[ 7] = 32'hc31450bd; D[ 8] = 32'hb8624e9a; D[ 9] = 32'h362966c6; D[ 10] = 32'h4d8a15bf; D[ 11] = 32'h845b6e48; D[ 12] = 32'h0b2259bf; D[ 13] = 32'h793bfff7; D[ 14] = 32'h28eeceb0; D[ 15] = 32'h8d6fde7f; D[ 16] = 32'h0d618632; D[ 17] = 32'hfb371e4b; D[ 18] = 32'h0b80a9a0; D[ 19] = 32'h5c1a1381; D[ 20] = 32'h8dfe755c; D[ 21] = 32'h82564b31; D[ 22] = 32'heee93cbd; D[ 23] = 32'h22bb686e; D[ 24] = 32'hf2ccae97; D[ 25] = 32'he3400736; D[ 26] = 32'h11c4a85e; D[ 27] = 32'ha0c904d0; D[ 28] = 32'hb495cecf; D[ 29] = 32'h32ceb818; D[ 30] = 32'ha2e46c28; D[ 31] = 32'h6915229e; DP[ 0] = 32'h63d165e5; DP[ 1] = 32'h856ac81e; DP[ 2] = 32'hc4b8779d; DP[ 3] = 32'h8b119544; DP[ 4] = 32'had780837; DP[ 5] = 32'h3e920266; DP[ 6] = 32'he9d10f2e; DP[ 7] = 32'h7c1b42b2; DP[ 8] = 32'hc7daca3b; DP[ 9] = 32'h7883be11; DP[ 10] = 32'ha384548d; DP[ 11] = 32'he0848b23; DP[ 12] = 32'h0b62bdff; DP[ 13] = 32'h11c64350; DP[ 14] = 32'h2aa1e225; DP[ 15] = 32'h9c2bcaa7; DQ[ 0] = 32'hd7ffdc71; DQ[ 1] = 32'hed01b8aa; DQ[ 2] = 32'h2f99d3a6; DQ[ 3] = 32'h8ccb4428; DQ[ 4] = 32'hb1574616; DQ[ 5] = 32'hfc218e36; DQ[ 6] = 32'h4fe24f91; DQ[ 7] = 32'h9c367c42; DQ[ 8] = 32'h69dfa208; DQ[ 9] = 32'h3ee3de79; DQ[ 10] = 32'h54ded59b; DQ[ 11] = 32'hcb3b487d; DQ[ 12] = 32'hbcc0db4e; DQ[ 13] = 32'hb3e6678c; DQ[ 14] = 32'h3d13ec03; DQ[ 15] = 32'h99e0f684; QINV[ 0] = 32'h9a2f0db2; QINV[ 1] = 32'h4a8075a5; QINV[ 2] = 32'hb61201fa; QINV[ 3] = 32'h0e876a42; QINV[ 4] = 32'h94667476; QINV[ 5] = 32'h7538b796; QINV[ 6] = 32'h8d8dfa35; QINV[ 7] = 32'h689ee4a7; QINV[ 8] = 32'h6779dd63; QINV[ 9] = 32'he15b6b5e; QINV[ 10] = 32'h8275500c; QINV[ 11] = 32'he4dcd058; QINV[ 12] = 32'haf54b86c; QINV[ 13] = 32'hba76dc50; QINV[ 14] = 32'h473d0d6d; QINV[ 15] = 32'ha023ba44; XM[ 0] = 32'h9b067dd2; XM[ 1] = 32'hf47b497a; XM[ 2] = 32'he8044305; XM[ 3] = 32'hf74f1735; XM[ 4] = 32'h494825f4; XM[ 5] = 32'h077bf4a3; XM[ 6] = 32'h637a9f36; XM[ 7] = 32'h3c3821a2; XM[ 8] = 32'haa1fe167; XM[ 9] = 32'h01c7289a; XM[ 10] = 32'hb463d63d; XM[ 11] = 32'hc992252e; XM[ 12] = 32'he43762bf; XM[ 13] = 32'h351d9416; XM[ 14] = 32'h10e7f813; XM[ 15] = 32'h33187c87; XM[ 16] = 32'h9eb98306; XM[ 17] = 32'hb29be7b6; XM[ 18] = 32'h32b237a8; XM[ 19] = 32'h6c1d5e46; XM[ 20] = 32'h1cf10b4a; XM[ 21] = 32'hd874a710; XM[ 22] = 32'h7d2df198; XM[ 23] = 32'h463701cc; XM[ 24] = 32'h9b648da0; XM[ 25] = 32'hdc5d3b10; XM[ 26] = 32'hef88e7fd; XM[ 27] = 32'hcb888210; XM[ 28] = 32'h24397651; XM[ 29] = 32'h9b9bd5a2; XM[ 30] = 32'hbc796763; XM[ 31] = 32'h5be48377; YM[ 0] = 32'h78aba2bd; YM[ 1] = 32'h6885ed1d; YM[ 2] = 32'h0d4983a2; YM[ 3] = 32'h3b775d20; YM[ 4] = 32'hf83145f4; YM[ 5] = 32'h66e52536; YM[ 6] = 32'h25c2377e; YM[ 7] = 32'h91ef1342; YM[ 8] = 32'h73013f57; YM[ 9] = 32'h3862aa1a; YM[ 10] = 32'h37846437; YM[ 11] = 32'ha6ddd3c9; YM[ 12] = 32'h3974d1b2; YM[ 13] = 32'h02aea3f6; YM[ 14] = 32'h2e71b229; YM[ 15] = 32'hb898d5b6; YM[ 16] = 32'h71258bb8; YM[ 17] = 32'h654f94e8; YM[ 18] = 32'h5539e56e; YM[ 19] = 32'hd49567f2; YM[ 20] = 32'he73efaa1; YM[ 21] = 32'h3e4e2162; YM[ 22] = 32'h772d786a; YM[ 23] = 32'hc27be96a; YM[ 24] = 32'h9911c92d; YM[ 25] = 32'hddc1b0fd; YM[ 26] = 32'h829186bb; YM[ 27] = 32'h1bab454e; YM[ 28] = 32'h2f9fd9ce; YM[ 29] = 32'ha57103d4; YM[ 30] = 32'h1a93390c; YM[ 31] = 32'hc0376429; S[ 0] = 32'h8eb4aa6e; S[ 1] = 32'hababa077; S[ 2] = 32'h8758f3f6; S[ 3] = 32'h8282e4f4; S[ 4] = 32'h747947ce; S[ 5] = 32'h9ac7dbb0; S[ 6] = 32'h9184f0b5; S[ 7] = 32'h4b572f47; S[ 8] = 32'hf4807458; S[ 9] = 32'h6da8dcd4; S[ 10] = 32'h9f331c40; S[ 11] = 32'h65e2b7a2; S[ 12] = 32'hd3704e85; S[ 13] = 32'h3366f4f0; S[ 14] = 32'h035044b1; S[ 15] = 32'h54758bc4; S[ 16] = 32'h2a7e0970; S[ 17] = 32'hbcc7783c; S[ 18] = 32'hf62193e6; S[ 19] = 32'h5d7bb220; S[ 20] = 32'hb0fcabdd; S[ 21] = 32'he6dc5c88; S[ 22] = 32'h8e4d5e53; S[ 23] = 32'haa40acba; S[ 24] = 32'h1dfc9178; S[ 25] = 32'h842821bc; S[ 26] = 32'h318fc8e1; S[ 27] = 32'h0f8161fe; S[ 28] = 32'hbf3d7945; S[ 29] = 32'he33612c7; S[ 30] = 32'h7eec7f9d; S[ 31] = 32'h66da2c5a; 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_PERIOD_QUARTER_NS (0.5 * `CLK_PERIOD_HALF_NS) `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_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 task sync_clk_bus; while (clk_bus_idle !== 1) _wait_quarter_clk_tick; endtask // // Reset // reg rst = 1'b1; wire rst_n = ~rst; // // Control / Status // reg [ 7:0] word_index_last_n; reg [ 7:0] word_index_last_pq; reg [11:0] bit_index_last_n; reg [11:0] bit_index_last_pq; reg core_next = 1'b0; wire core_valid; reg core_crt_mode; // // System Bus // reg bus_cs = 1'b0; reg bus_we = 1'b0; reg [11:0] bus_addr; reg [31:0] bus_data_wr; wire [31:0] bus_data_rd; wire [ 1:0] bus_addr_sel = bus_addr[11:10]; wire [ 2:0] bus_addr_bank = bus_addr[9:7]; wire [ 6:0] bus_addr_data = bus_addr[6:0]; // // UUT // modexpng_core_top uut ( .clk (clk), .clk_bus (clk_bus), .rst_n (rst_n), .next (core_next), .valid (core_valid), .crt_mode (core_crt_mode), .word_index_last_n (word_index_last_n), .word_index_last_pq (word_index_last_pq), .bit_index_last_n (bit_index_last_n), .bit_index_last_pq (bit_index_last_pq), .bus_cs (bus_cs), .bus_we (bus_we), .bus_addr (bus_addr), .bus_data_wr (bus_data_wr), .bus_data_rd (bus_data_rd) ); // // Bus Init Routine // 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 // // Script // initial main; // // Main Routine (Control/Status, Bus) // integer i, j, k; task main; begin sync_clk; // switch to fast core clock core_reset; // reset core core_set_params; // set parameters (modulus width, exponent length) 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 core_print_load; // 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 core_print_load; // end endtask task core_reset; begin wait_clk_ticks(100); rst = 1'b0; wait_clk_ticks(10); $display("Core reset finished."); end endtask 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 // integer _w, _n; // // core_set_input_1 // task core_set_input_1; reg [9:0] _tn; 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 ", XM[_w] ^ XM_READBACK[_w]); $write("\n"); end // if (!ym_ok) // for (_w=0; _w ", YM[_w] ^ YM_READBACK[_w]); $write("\n"); end // if (!s_ok) // for (_w=0; _w ", S[_w] ^ S_READBACK[_w]); $write("\n"); end // $write("XM is "); if (xm_ok) $write("OK.\n"); else $write("WRONG!\n"); // $write("YM is "); if (ym_ok) $write("OK.\n"); else $write("WRONG!\n"); // $write("S is "); if (s_ok) $write("OK.\n"); else $write("WRONG!\n"); // end // endtask // // _bus_drive() // task _bus_drive; input cs; input we; input [11:0] addr; input [31:0] data; {bus_cs, bus_we, bus_addr, bus_data_wr} <= {cs, we, addr, data}; endtask // // bus_write() // task bus_write; input [ 1:0] sel; input [ 2:0] bank; input [ 6:0] addr; input [31:0] data; begin _bus_drive(1'b1, 1'b1, {sel, bank, addr}, data); wait_clk_bus_tick; _bus_drive(1'b0, 1'b0, 12'hXXX, 32'hXXXXXXXX); end endtask // // bus_read() // task bus_read; input [ 1:0] sel; input [ 2:0] bank; input [ 6:0] addr; output [31:0] data; begin _bus_drive(1'b1, 1'b0, {sel, bank, addr}, 32'hXXXXXXXX); wait_clk_bus_tick; data = bus_data_rd; _bus_drive(1'b0, 1'b0, 12'hXXX, 32'hXXXXXXXX); end endtask // // _wait_quarter_clk_tick() // task _wait_quarter_clk_tick; #`CLK_PERIOD_QUARTER_NS; endtask // // _wait_half_clk_tick() // task _wait_half_clk_tick; begin _wait_quarter_clk_tick; _wait_quarter_clk_tick; end endtask // // wait_clk_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_clk_ticks() // task wait_clk_ticks; input integer num_ticks; for (_n=0; _n