mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-22 14:33:51 +00:00
166 lines
4.1 KiB
Verilog
166 lines
4.1 KiB
Verilog
// DESCRIPTION: Verilator: Verilog Test module
|
|
//
|
|
// This file ONLY is placed under the Creative Commons Public Domain, for
|
|
// any use, without warranty, 2008 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] Operand1 = crc[31:0];
|
|
wire [15:0] Operand2 = crc[47:32];
|
|
wire Unsigned = crc[48];
|
|
reg rst;
|
|
|
|
parameter wl = 16;
|
|
|
|
/*AUTOWIRE*/
|
|
// Beginning of automatic wires (for undeclared instantiated-module outputs)
|
|
wire [wl-1:0] Quotient; // From test of Test.v
|
|
wire [wl-1:0] Remainder; // From test of Test.v
|
|
// End of automatics
|
|
|
|
Test test (/*AUTOINST*/
|
|
// Outputs
|
|
.Quotient (Quotient[wl-1:0]),
|
|
.Remainder (Remainder[wl-1:0]),
|
|
// Inputs
|
|
.Operand1 (Operand1[wl*2-1:0]),
|
|
.Operand2 (Operand2[wl-1:0]),
|
|
.clk (clk),
|
|
.rst (rst),
|
|
.Unsigned (Unsigned));
|
|
|
|
// Aggregate outputs into a single result vector
|
|
wire [63:0] result = {32'h0, Quotient, Remainder};
|
|
|
|
// What checksum will we end up with
|
|
`define EXPECTED_SUM 64'h98d41f89a8be5693
|
|
|
|
// Test loop
|
|
always @ (posedge clk) begin
|
|
`ifdef TEST_VERBOSE
|
|
$write("[%0t] cyc==%0d crc=%x result=%x it=%x\n",$time, cyc, crc, result, test.Iteration);
|
|
`endif
|
|
cyc <= cyc + 1;
|
|
if (cyc < 20 || test.Iteration==4'd15) begin
|
|
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
|
|
end
|
|
sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]};
|
|
if (cyc==0) begin
|
|
// Setup
|
|
crc <= 64'h5aef0c8d_d70a4497;
|
|
rst <= 1'b1;
|
|
end
|
|
else if (cyc<20) begin
|
|
sum <= 64'h0;
|
|
rst <= 1'b0;
|
|
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'h8dd70a44972ad809) $stop;
|
|
if (sum !== `EXPECTED_SUM) $stop;
|
|
$write("*-* All Finished *-*\n");
|
|
$finish;
|
|
end
|
|
end
|
|
|
|
endmodule
|
|
|
|
module Test(clk, rst, Operand1, Operand2, Unsigned, Quotient, Remainder);
|
|
|
|
parameter wl = 16;
|
|
|
|
input [wl*2-1:0] Operand1;
|
|
input [wl-1:0] Operand2;
|
|
input clk, rst, Unsigned;
|
|
output [wl-1:0] Quotient, Remainder;
|
|
|
|
reg Cy, Overflow, Sign1, Sign2, Zero, Negative;
|
|
reg [wl-1:0] ah,al,Quotient, Remainder;
|
|
reg [3:0] Iteration;
|
|
reg [wl-1:0] sub_quot,op;
|
|
reg ah_ext;
|
|
|
|
reg [1:0] a,b,c,d,e;
|
|
|
|
always @(posedge clk) begin
|
|
if (!rst) begin
|
|
{a,b,c,d,e} = Operand1[9:0];
|
|
{a,b,c,d,e} = {e,d,c,b,a};
|
|
if (a != Operand1[1:0]) $stop;
|
|
if (b != Operand1[3:2]) $stop;
|
|
if (c != Operand1[5:4]) $stop;
|
|
if (d != Operand1[7:6]) $stop;
|
|
if (e != Operand1[9:8]) $stop;
|
|
end
|
|
end
|
|
|
|
always @(posedge clk) begin
|
|
if (rst) begin
|
|
Iteration <= 0;
|
|
Quotient <= 0;
|
|
Remainder <= 0;
|
|
end
|
|
else begin
|
|
if (Iteration == 0) begin
|
|
{ah,al} = Operand1;
|
|
op = Operand2;
|
|
Cy = 0;
|
|
Overflow = 0;
|
|
Sign1 = (~Unsigned)&ah[wl-1];
|
|
Sign2 = (~Unsigned)&(ah[wl-1]^op[wl-1]);
|
|
if (Sign1) {ah,al} = -{ah,al};
|
|
end
|
|
`define BUG1
|
|
`ifdef BUG1
|
|
{ah_ext,ah,al} = {ah,al,Cy};
|
|
`else
|
|
ah_ext = ah[15];
|
|
ah[15:1] = ah[14:0];
|
|
ah[0] = al[15];
|
|
al[15:1] = al[14:0];
|
|
al[0] = Cy;
|
|
`endif
|
|
`ifdef TEST_VERBOSE
|
|
$display("%x %x %x %x %x %x %x %x %x",
|
|
Iteration, ah, al, Quotient, Remainder, Overflow, ah_ext, sub_quot, Cy);
|
|
`endif
|
|
{Cy,sub_quot} = (~Unsigned)&op[wl-1]? {ah_ext,ah}+op : {ah_ext,ah} - {1'b1,op};
|
|
if (Cy)
|
|
begin
|
|
{ah_ext,ah} = {1'b0,sub_quot};
|
|
end
|
|
if (Iteration != 15 )
|
|
begin
|
|
if (ah_ext) Overflow = 1;
|
|
end
|
|
else
|
|
begin
|
|
if (al[14] && ~Unsigned) Overflow = 1;
|
|
Quotient <= Sign2 ? -{al[14:0],Cy} : {al[14:0],Cy};
|
|
Remainder <= Sign1 ? -ah : ah;
|
|
if (Overflow)
|
|
begin
|
|
Quotient <= Sign2 ? 16'h8001 : {Unsigned,{15{1'b1}}};
|
|
Remainder <= Unsigned ? 16'hffff : 16'h8000;
|
|
Zero = 1;
|
|
Negative = 1;
|
|
end
|
|
end
|
|
Iteration <= Iteration + 1; // Count number of times this instruction is repeated
|
|
end
|
|
end
|
|
|
|
endmodule
|