verilator/test_regress/t/t_sv_conditional.v
2017-09-11 19:18:58 -04:00

477 lines
14 KiB
Systemverilog

// DESCRIPTION: Verilator: System Verilog test of case and if
//
// This code instantiates and runs a simple CPU written in System Verilog.
//
// This file ONLY is placed into the Public Domain, for any use, without
// warranty.
// Contributed 2012 by M W Lund, Atmel Corporation and Jeremy Bennett, Embecosm.
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
/*AUTOWIRE*/
// **************************************************************************
// Regs and Wires
// **************************************************************************
reg rst;
integer rst_count;
st3_testbench st3_testbench_i (/*AUTOINST*/
// Inputs
.clk (clk),
.rst (rst));
// **************************************************************************
// Reset Generation
// **************************************************************************
initial begin
rst = 1'b1;
rst_count = 0;
end
always @( posedge clk ) begin
if (rst_count < 2) begin
rst_count++;
end
else begin
rst = 1'b0;
end
end
// **************************************************************************
// Closing message
// **************************************************************************
final begin
$write("*-* All Finished *-*\n");
end
endmodule
module st3_testbench (/*AUTOARG*/
// Inputs
clk, rst
);
input clk;
input rst;
logic clk;
logic rst;
logic [8*16-1:0] wide_input_bus;
logic decrementA; // 0=Up-counting, 1=down-counting
logic dual_countA; // Advance counter by 2 steps at a time
logic cntA_en; // Enable Counter A
logic decrementB; // 0=Up-counting, 1=down-counting
logic dual_countB; // Advance counter by 2 steps at a time
logic cntB_en; // Enable counter B
logic [47:0] selected_out;
integer i;
initial begin
decrementA = 1'b0;
dual_countA = 1'b0;
cntA_en = 1'b1;
decrementB = 1'b0;
dual_countB = 1'b0;
cntB_en = 1'b1;
wide_input_bus = {8'hf5,
8'hef,
8'hd5,
8'hc5,
8'hb5,
8'ha5,
8'h95,
8'h85,
8'ha7,
8'ha6,
8'ha5,
8'ha4,
8'ha3,
8'ha2,
8'ha1,
8'ha0};
i = 0;
end
simple_test_3
simple_test_3_i
(// Outputs
.selected_out (selected_out[47:0]),
// Inputs
.wide_input_bus (wide_input_bus[8*16-1:0]),
.rst (rst),
.clk (clk),
.decrementA (decrementA),
.dual_countA (dual_countA),
.cntA_en (cntA_en),
.decrementB (decrementB),
.dual_countB (dual_countB),
.cntB_en (cntB_en));
// Logic to print outputs and then finish.
always @(posedge clk) begin
if (i < 50) begin
`ifdef TEST_VERBOSE
$display("%x", simple_test_3_i.cntA_reg ,"%x",
simple_test_3_i.cntB_reg ," ", "%x", selected_out);
`endif
i <= i + 1;
end
else begin
$finish();
end
end // always @ (posedge clk)
endmodule
// Module testing:
// - Unique case
// - Priority case
// - Unique if
// - ++, --, =- and =+ operands.
module simple_test_3
(input logic [8*16-1:0] wide_input_bus,
input logic rst,
input logic clk,
// Counter A
input logic decrementA, // 0=Up-counting, 1=down-counting
input logic dual_countA, // Advance counter by 2 steps at a time
input logic cntA_en, // Enable Counter A
// Counter B
input logic decrementB, // 0=Up-counting, 1=down-counting
input logic dual_countB, // Advance counter by 2 steps at a time
input logic cntB_en, // Enable counter B
// Outputs
output logic [47:0] selected_out);
// Declarations
logic [3:0] cntA_reg; // Registered version of cntA
logic [3:0] cntB_reg; // Registered version of cntA
counterA
counterA_inst
(/*AUTOINST*/
// Outputs
.cntA_reg (cntA_reg[3:0]),
// Inputs
.decrementA (decrementA),
.dual_countA (dual_countA),
.cntA_en (cntA_en),
.clk (clk),
.rst (rst));
counterB
counterB_inst
(/*AUTOINST*/
// Outputs
.cntB_reg (cntB_reg[3:0]),
// Inputs
.decrementB (decrementB),
.dual_countB (dual_countB),
.cntB_en (cntB_en),
.clk (clk),
.rst (rst));
simple_test_3a
sta
(.wide_input_bus (wide_input_bus),
.selector (cntA_reg),
.selected_out (selected_out[7:0]));
simple_test_3b
stb
(.wide_input_bus (wide_input_bus),
.selector (cntA_reg),
.selected_out (selected_out[15:8]));
simple_test_3c
stc
(.wide_input_bus (wide_input_bus),
.selector (cntB_reg),
.selected_out (selected_out[23:16]));
simple_test_3d
std
(.wide_input_bus (wide_input_bus),
.selector (cntB_reg),
.selected_out (selected_out[31:24]));
simple_test_3e
ste
(.wide_input_bus (wide_input_bus),
.selector (cntB_reg),
.selected_out (selected_out[39:32]));
simple_test_3f
stf
(.wide_input_bus (wide_input_bus),
.selector (cntB_reg),
.selected_out (selected_out[47:40]));
endmodule // simple_test_3
module counterA
(output logic [3:0] cntA_reg, // Registered version of cntA
input logic decrementA, // 0=Up-counting, 1=down-counting
input logic dual_countA, // Advance counter by 2 steps at a time
input logic cntA_en, // Enable Counter A
input logic clk, // Clock
input logic rst); // Synchronous reset
logic [3:0] cntA; // combinational count variable.
// Counter A
// Sequential part of counter CntA
always_ff @(posedge clk)
begin
cntA_reg <= cntA;
end
// Combinational part of counter
// Had to be split up to test C-style update, as there are no
// non-blocking version like -<=
always_comb
if (rst)
cntA = 0;
else begin
cntA = cntA_reg; // Necessary to avoid latch
if (cntA_en) begin
if (decrementA)
if (dual_countA)
//cntA = cntA - 2;
cntA -= 2;
else
//cntA = cntA - 1;
cntA--;
else
if (dual_countA)
//cntA = cntA + 2;
cntA += 2;
else
//cntA = cntA + 1;
cntA++;
end // if (cntA_en)
end
endmodule // counterA
module counterB
(output logic [3:0] cntB_reg, // Registered version of cntA
input logic decrementB, // 0=Up-counting, 1=down-counting
input logic dual_countB, // Advance counter by 2 steps at a time
input logic cntB_en, // Enable counter B
input logic clk, // Clock
input logic rst); // Synchronous reset
// Counter B - tried to write sequential only, but ended up without
// SystemVerilog.
always_ff @(posedge clk) begin
if (rst)
cntB_reg <= 0;
else
if (cntB_en) begin
if (decrementB)
if (dual_countB)
cntB_reg <= cntB_reg - 2;
else
cntB_reg <= cntB_reg - 1;
// Attempts to write in SystemVerilog:
else
if (dual_countB)
cntB_reg <= cntB_reg + 2;
else
cntB_reg <= cntB_reg + 1;
// Attempts to write in SystemVerilog:
end
end // always_ff @
endmodule
// A multiplexor in terms of look-up
module simple_test_3a
(input logic [8*16-1:0] wide_input_bus,
input logic [3:0] selector,
output logic [7:0] selected_out);
always_comb
selected_out = {wide_input_bus[selector*8+7],
wide_input_bus[selector*8+6],
wide_input_bus[selector*8+5],
wide_input_bus[selector*8+4],
wide_input_bus[selector*8+3],
wide_input_bus[selector*8+2],
wide_input_bus[selector*8+1],
wide_input_bus[selector*8]};
endmodule // simple_test_3a
// A multiplexer in terms of standard case
module simple_test_3b
(input logic [8*16-1:0] wide_input_bus,
input logic [3:0] selector,
output logic [7:0] selected_out);
always_comb begin
case (selector)
4'h0: selected_out = wide_input_bus[ 7: 0];
4'h1: selected_out = wide_input_bus[ 15: 8];
4'h2: selected_out = wide_input_bus[ 23: 16];
4'h3: selected_out = wide_input_bus[ 31: 24];
4'h4: selected_out = wide_input_bus[ 39: 32];
4'h5: selected_out = wide_input_bus[ 47: 40];
4'h6: selected_out = wide_input_bus[ 55: 48];
4'h7: selected_out = wide_input_bus[ 63: 56];
4'h8: selected_out = wide_input_bus[ 71: 64];
4'h9: selected_out = wide_input_bus[ 79: 72];
4'ha: selected_out = wide_input_bus[ 87: 80];
4'hb: selected_out = wide_input_bus[ 95: 88];
4'hc: selected_out = wide_input_bus[103: 96];
4'hd: selected_out = wide_input_bus[111:104];
4'he: selected_out = wide_input_bus[119:112];
4'hf: selected_out = wide_input_bus[127:120];
endcase // case (selector)
end
endmodule // simple_test_3b
// A multiplexer in terms of unique case
module simple_test_3c
(input logic [8*16-1:0] wide_input_bus,
input logic [3:0] selector,
output logic [7:0] selected_out);
always_comb begin
unique case (selector)
4'h0: selected_out = wide_input_bus[ 7: 0];
4'h1: selected_out = wide_input_bus[ 15: 8];
4'h2: selected_out = wide_input_bus[ 23: 16];
4'h3: selected_out = wide_input_bus[ 31: 24];
4'h4: selected_out = wide_input_bus[ 39: 32];
4'h5: selected_out = wide_input_bus[ 47: 40];
4'h6: selected_out = wide_input_bus[ 55: 48];
4'h7: selected_out = wide_input_bus[ 63: 56];
4'h8: selected_out = wide_input_bus[ 71: 64];
4'h9: selected_out = wide_input_bus[ 79: 72];
4'ha: selected_out = wide_input_bus[ 87: 80];
4'hb: selected_out = wide_input_bus[ 95: 88];
4'hc: selected_out = wide_input_bus[103: 96];
4'hd: selected_out = wide_input_bus[111:104];
4'he: selected_out = wide_input_bus[119:112];
4'hf: selected_out = wide_input_bus[127:120];
endcase // case (selector)
end
endmodule // simple_test_3c
// A multiplexer in terms of unique if
module simple_test_3d
(input logic [8*16-1:0] wide_input_bus,
input logic [3:0] selector,
output logic [7:0] selected_out);
always_comb begin
unique if (selector == 4'h0) selected_out = wide_input_bus[ 7: 0];
else if (selector == 4'h1) selected_out = wide_input_bus[ 15: 8];
else if (selector == 4'h2) selected_out = wide_input_bus[ 23: 16];
else if (selector == 4'h3) selected_out = wide_input_bus[ 31: 24];
else if (selector == 4'h4) selected_out = wide_input_bus[ 39: 32];
else if (selector == 4'h5) selected_out = wide_input_bus[ 47: 40];
else if (selector == 4'h6) selected_out = wide_input_bus[ 55: 48];
else if (selector == 4'h7) selected_out = wide_input_bus[ 63: 56];
else if (selector == 4'h8) selected_out = wide_input_bus[ 71: 64];
else if (selector == 4'h9) selected_out = wide_input_bus[ 79: 72];
else if (selector == 4'ha) selected_out = wide_input_bus[ 87: 80];
else if (selector == 4'hb) selected_out = wide_input_bus[ 95: 88];
else if (selector == 4'hc) selected_out = wide_input_bus[103: 96];
else if (selector == 4'hd) selected_out = wide_input_bus[111:104];
else if (selector == 4'he) selected_out = wide_input_bus[119:112];
else if (selector == 4'hf) selected_out = wide_input_bus[127:120];
end
endmodule // simple_test_3d
// Test of priority case
// Note: This does NOT try to implement the same function as above.
module simple_test_3e
(input logic [8*16-1:0] wide_input_bus,
input logic [3:0] selector,
output logic [7:0] selected_out);
always_comb begin
priority case (1'b1)
selector[0]: selected_out = wide_input_bus[ 7: 0]; // Bit 0 has highets priority
selector[2]: selected_out = wide_input_bus[ 39: 32]; // Note 2 higher priority than 1
selector[1]: selected_out = wide_input_bus[ 23: 16]; // Note 1 lower priority than 2
selector[3]: selected_out = wide_input_bus[ 71: 64]; // Bit 3 has lowest priority
default: selected_out = wide_input_bus[127:120]; // for selector = 0.
endcase // case (selector)
end
endmodule // simple_test_3e
// Test of "inside"
// Note: This does NOT try to implement the same function as above.
// Note: Support for "inside" is a separate Verilator feature request, so is
// not used inside a this version of the test.
module simple_test_3f
(input logic [8*16-1:0] wide_input_bus,
input logic [3:0] selector,
output logic [7:0] selected_out);
always_comb begin
/* -----\/----- EXCLUDED -----\/-----
if ( selector[3:0] inside { 4'b?00?, 4'b1100}) // Matching 0000, 0001, 1000, 1100, 1001
// if ( selector[3:2] inside { 2'b?0, selector[1:0]})
selected_out = wide_input_bus[ 7: 0];
else
-----/\----- EXCLUDED -----/\----- */
/* verilator lint_off CASEOVERLAP */
priority casez (selector[3:0])
4'b0?10: selected_out = wide_input_bus[ 15: 8]; // Matching 0010 and 0110
4'b0??0: selected_out = wide_input_bus[ 23: 16]; // Overlap: only 0100 remains (0000 in "if" above)
4'b0100: selected_out = wide_input_bus[ 31: 24]; // Overlap: Will never occur
default: selected_out = wide_input_bus[127:120]; // Remaining 0011,0100,0101,0111,1010,1011,1101,1110,1111
endcase // case (selector)
/* verilator lint_on CASEOVERLAP */
end
endmodule // simple_test_3f