1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2009 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
integer cyc = 0;
reg [63:0] crc;
reg [63:0] sum;
// Take CRC data and apply to testblock inputs
wire [31:0] in = crc[31:0];
/*AUTOWIRE*/
// Async clears must not race with clocks if we want repeatable results
reg set_l = in[20];
reg clr_l = in[21];
always @ (negedge clk) begin
set_l <= in[20];
clr_l <= in[21];
end
//====== Mux
wire [1:0] qm;
// delay z a b sel
udp_mux2 #(0.1) m0 (qm[0], in[0], in[2], in[4]);
udp_mux2 #0.1 m1 (qm[1], in[1], in[3], in[4]);
`define verilatorxx
`ifdef verilatorxx
reg [1:0] ql;
reg [1:0] qd;
// No sequential tables, yet
// always @* begin
// if (!clk) ql = in[13:12];
// end
always @(posedge clk or negedge set_l or negedge clr_l) begin
if (!set_l) qd <= ~2'b0;
else if (!clr_l) qd <= 2'b0;
else qd <= in[17:16];
end
`else
//====== Latch
// wire [1:0] ql;
// // q clk d
// udp_latch l0 (ql[0], !in[8], in[12]);
// udp_latch l1 (ql[1], !in[8], in[13]);
//====== DFF
wire [1:0] qd;
//always @* $display("UL q=%b c=%b d=%b", ql[1:0], in[8], in[13:12]);
// q clk d set_l clr_l
udp_dff d0 (qd[0], in[8], in[16], set_l, clr_l);
udp_dff d2 (qd[1], in[8], in[17], set_l, clr_l);
`endif
// Aggregate outputs into a single result vector
wire [63:0] result = {52'h0, 2'b0,qd, 4'b0, 2'b0,qm};
// wire [63:0] result = {52'h0, 2'b0,qd, 2'b0,ql, 2'b0,qm};
// Test loop
always @ (posedge clk) begin
`ifdef TEST_VERBOSE
$write("[%0t] cyc==%0d crc=%x result=%x\n", $time, cyc, crc, result);
`endif
cyc <= cyc + 1;
crc <= {crc[62:0], crc[63] ^ crc[2] ^ crc[0]};
sum <= result ^ {sum[62:0], sum[63] ^ sum[2] ^ sum[0]};
if (cyc==0) begin
// Setup
crc <= 64'h5aef0c8d_d70a4497;
sum <= 64'h0;
end
else if (cyc<10) begin
sum <= 64'h0;
end
else if (cyc<90) begin
end
else if (cyc==99) begin
$write("[%0t] cyc==%0d crc=%x sum=%x\n", $time, cyc, crc, sum);
if (crc !== 64'hc77bb9b3784ea091) $stop;
// What checksum will we end up with (above print should match)
// Note not all simulators agree about the latch result. Maybe have a race?
`define EXPECTED_SUM 64'hb73acf228acaeaa3
if (sum !== `EXPECTED_SUM) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
primitive udp_mux2 (z, a, b, sel);
output z;
input a, b, sel;
table
//a b s o
? 1 1 : 1 ;
? 0 1 : 0 ;
1 ? 0 : 1 ;
0 ? 0 : 0 ;
1 1 x : 1 ;
0 0 x : 0 ;
endtable
endprimitive
primitive udp_latch (q, clk, d);
output q; reg q;
input clk, d;
table
//clk d q q'
0 1 : ? : 1;
0 0 : ? : 0;
1 ? : ? : -;
endtable
endprimitive
primitive udp_dff (q, clk, d, set_l, clr_l);
output q;
input clk, d, set_l, clr_l;
reg q;
table
//ck d s c : q : q'
r 0 1 ? : ? : 0 ;
r 1 ? 1 : ? : 1 ;
* 1 ? 1 : 1 : 1 ;
* 0 1 ? : 0 : 0 ;
f ? ? ? : ? : - ;
b * ? ? : ? : - ;
? ? 0 ? : ? : 1 ;
b ? * 1 : 1 : 1 ;
x 1 * 1 : 1 : 1 ;
? ? 1 0 : ? : 0 ;
b ? 1 * : 0 : 0 ;
x 0 1 * : 0 : 0 ;
endtable
endprimitive
|