1// DESCRIPTION: Verilator: System Verilog test of case and if 2// 3// This code instantiates and runs a simple CPU written in System Verilog. 4// 5// This file ONLY is placed into the Public Domain, for any use, without 6// warranty. 7// SPDX-License-Identifier: CC0-1.0 8 9// Contributed 2012 by M W Lund, Atmel Corporation and Jeremy Bennett, Embecosm. 10 11 12module t (/*AUTOARG*/ 13 // Inputs 14 clk 15 ); 16 17 input clk; 18 19 /*AUTOWIRE*/ 20 21 // ************************************************************************** 22 // Regs and Wires 23 // ************************************************************************** 24 25 reg rst; 26 integer rst_count; 27 28 29 st3_testbench st3_testbench_i (/*AUTOINST*/ 30 // Inputs 31 .clk (clk), 32 .rst (rst)); 33 34 // ************************************************************************** 35 // Reset Generation 36 // ************************************************************************** 37 38 initial begin 39 rst = 1'b1; 40 rst_count = 0; 41 end 42 43 always @( posedge clk ) begin 44 if (rst_count < 2) begin 45 rst_count++; 46 end 47 else begin 48 rst = 1'b0; 49 end 50 end 51 52 // ************************************************************************** 53 // Closing message 54 // ************************************************************************** 55 56 final begin 57 $write("*-* All Finished *-*\n"); 58 end 59 60endmodule 61 62 63module st3_testbench (/*AUTOARG*/ 64 // Inputs 65 clk, rst 66 ); 67 68 input clk; 69 input rst; 70 71 logic clk; 72 logic rst; 73 logic [8*16-1:0] wide_input_bus; 74 logic decrementA; // 0=Up-counting, 1=down-counting 75 logic dual_countA; // Advance counter by 2 steps at a time 76 logic cntA_en; // Enable Counter A 77 logic decrementB; // 0=Up-counting, 1=down-counting 78 logic dual_countB; // Advance counter by 2 steps at a time 79 logic cntB_en; // Enable counter B 80 logic [47:0] selected_out; 81 integer i; 82 83 84 initial begin 85 decrementA = 1'b0; 86 dual_countA = 1'b0; 87 cntA_en = 1'b1; 88 decrementB = 1'b0; 89 dual_countB = 1'b0; 90 cntB_en = 1'b1; 91 wide_input_bus = {8'hf5, 92 8'hef, 93 8'hd5, 94 8'hc5, 95 8'hb5, 96 8'ha5, 97 8'h95, 98 8'h85, 99 8'ha7, 100 8'ha6, 101 8'ha5, 102 8'ha4, 103 8'ha3, 104 8'ha2, 105 8'ha1, 106 8'ha0}; 107 i = 0; 108 end 109 110 111 simple_test_3 112 simple_test_3_i 113 (// Outputs 114 .selected_out (selected_out[47:0]), 115 // Inputs 116 .wide_input_bus (wide_input_bus[8*16-1:0]), 117 .rst (rst), 118 .clk (clk), 119 .decrementA (decrementA), 120 .dual_countA (dual_countA), 121 .cntA_en (cntA_en), 122 .decrementB (decrementB), 123 .dual_countB (dual_countB), 124 .cntB_en (cntB_en)); 125 126 127 // Logic to print outputs and then finish. 128 always @(posedge clk) begin 129 if (i < 50) begin 130`ifdef TEST_VERBOSE 131 $display("%x", simple_test_3_i.cntA_reg ,"%x", 132 simple_test_3_i.cntB_reg ," ", "%x", selected_out); 133`endif 134 i <= i + 1; 135 end 136 else begin 137 $finish(); 138 end 139 end // always @ (posedge clk) 140 141endmodule 142 143 144// Module testing: 145// - Unique case 146// - Priority case 147// - Unique if 148// - ++, --, =- and =+ operands. 149 150module simple_test_3 151 (input logic [8*16-1:0] wide_input_bus, 152 input logic rst, 153 input logic clk, 154 // Counter A 155 input logic decrementA, // 0=Up-counting, 1=down-counting 156 input logic dual_countA, // Advance counter by 2 steps at a time 157 input logic cntA_en, // Enable Counter A 158 // Counter B 159 input logic decrementB, // 0=Up-counting, 1=down-counting 160 input logic dual_countB, // Advance counter by 2 steps at a time 161 input logic cntB_en, // Enable counter B 162 163 // Outputs 164 output logic [47:0] selected_out); 165 166 // Declarations 167 logic [3:0] cntA_reg; // Registered version of cntA 168 logic [3:0] cntB_reg; // Registered version of cntA 169 170 171 counterA 172 counterA_inst 173 (/*AUTOINST*/ 174 // Outputs 175 .cntA_reg (cntA_reg[3:0]), 176 // Inputs 177 .decrementA (decrementA), 178 .dual_countA (dual_countA), 179 .cntA_en (cntA_en), 180 .clk (clk), 181 .rst (rst)); 182 183 counterB 184 counterB_inst 185 (/*AUTOINST*/ 186 // Outputs 187 .cntB_reg (cntB_reg[3:0]), 188 // Inputs 189 .decrementB (decrementB), 190 .dual_countB (dual_countB), 191 .cntB_en (cntB_en), 192 .clk (clk), 193 .rst (rst)); 194 195 simple_test_3a 196 sta 197 (.wide_input_bus (wide_input_bus), 198 .selector (cntA_reg), 199 .selected_out (selected_out[7:0])); 200 201 simple_test_3b 202 stb 203 (.wide_input_bus (wide_input_bus), 204 .selector (cntA_reg), 205 .selected_out (selected_out[15:8])); 206 207 simple_test_3c 208 stc 209 (.wide_input_bus (wide_input_bus), 210 .selector (cntB_reg), 211 .selected_out (selected_out[23:16])); 212 213 simple_test_3d 214 std 215 (.wide_input_bus (wide_input_bus), 216 .selector (cntB_reg), 217 .selected_out (selected_out[31:24])); 218 219 simple_test_3e 220 ste 221 (.wide_input_bus (wide_input_bus), 222 .selector (cntB_reg), 223 .selected_out (selected_out[39:32])); 224 225 simple_test_3f 226 stf 227 (.wide_input_bus (wide_input_bus), 228 .selector (cntB_reg), 229 .selected_out (selected_out[47:40])); 230 231 232endmodule // simple_test_3 233 234 235module counterA 236 (output logic [3:0] cntA_reg, // Registered version of cntA 237 input logic decrementA, // 0=Up-counting, 1=down-counting 238 input logic dual_countA, // Advance counter by 2 steps at a time 239 input logic cntA_en, // Enable Counter A 240 input logic clk, // Clock 241 input logic rst); // Synchronous reset 242 243 244 245 logic [3:0] cntA; // combinational count variable. 246 247 // Counter A 248 // Sequential part of counter CntA 249 always_ff @(posedge clk) 250 begin 251 cntA_reg <= cntA; 252 end 253 254 // Combinational part of counter 255 // Had to be split up to test C-style update, as there are no 256 // non-blocking version like -<= 257 always_comb 258 if (rst) 259 cntA = 0; 260 else begin 261 cntA = cntA_reg; // Necessary to avoid latch 262 if (cntA_en) begin 263 if (decrementA) 264 if (dual_countA) 265 //cntA = cntA - 2; 266 cntA -= 2; 267 else 268 //cntA = cntA - 1; 269 cntA--; 270 else 271 if (dual_countA) 272 //cntA = cntA + 2; 273 cntA += 2; 274 else 275 //cntA = cntA + 1; 276 cntA++; 277 end // if (cntA_en) 278 end 279endmodule // counterA 280 281 282module counterB 283 (output logic [3:0] cntB_reg, // Registered version of cntA 284 input logic decrementB, // 0=Up-counting, 1=down-counting 285 input logic dual_countB, // Advance counter by 2 steps at a time 286 input logic cntB_en, // Enable counter B 287 input logic clk, // Clock 288 input logic rst); // Synchronous reset 289 290 // Counter B - tried to write sequential only, but ended up without 291 // SystemVerilog. 292 293 always_ff @(posedge clk) begin 294 if (rst) 295 cntB_reg <= 0; 296 else 297 if (cntB_en) begin 298 if (decrementB) 299 if (dual_countB) 300 cntB_reg <= cntB_reg - 2; 301 else 302 cntB_reg <= cntB_reg - 1; 303 // Attempts to write in SystemVerilog: 304 else 305 if (dual_countB) 306 cntB_reg <= cntB_reg + 2; 307 else 308 cntB_reg <= cntB_reg + 1; 309 // Attempts to write in SystemVerilog: 310 end 311 end // always_ff @ 312endmodule 313 314 315// A multiplexor in terms of look-up 316module simple_test_3a 317 (input logic [8*16-1:0] wide_input_bus, 318 input logic [3:0] selector, 319 output logic [7:0] selected_out); 320 321 322 always_comb 323 selected_out = {wide_input_bus[selector*8+7], 324 wide_input_bus[selector*8+6], 325 wide_input_bus[selector*8+5], 326 wide_input_bus[selector*8+4], 327 wide_input_bus[selector*8+3], 328 wide_input_bus[selector*8+2], 329 wide_input_bus[selector*8+1], 330 wide_input_bus[selector*8]}; 331 332endmodule // simple_test_3a 333 334 335// A multiplexer in terms of standard case 336module simple_test_3b 337 (input logic [8*16-1:0] wide_input_bus, 338 input logic [3:0] selector, 339 output logic [7:0] selected_out); 340 341 342 always_comb begin 343 case (selector) 344 4'h0: selected_out = wide_input_bus[ 7: 0]; 345 4'h1: selected_out = wide_input_bus[ 15: 8]; 346 4'h2: selected_out = wide_input_bus[ 23: 16]; 347 4'h3: selected_out = wide_input_bus[ 31: 24]; 348 4'h4: selected_out = wide_input_bus[ 39: 32]; 349 4'h5: selected_out = wide_input_bus[ 47: 40]; 350 4'h6: selected_out = wide_input_bus[ 55: 48]; 351 4'h7: selected_out = wide_input_bus[ 63: 56]; 352 4'h8: selected_out = wide_input_bus[ 71: 64]; 353 4'h9: selected_out = wide_input_bus[ 79: 72]; 354 4'ha: selected_out = wide_input_bus[ 87: 80]; 355 4'hb: selected_out = wide_input_bus[ 95: 88]; 356 4'hc: selected_out = wide_input_bus[103: 96]; 357 4'hd: selected_out = wide_input_bus[111:104]; 358 4'he: selected_out = wide_input_bus[119:112]; 359 4'hf: selected_out = wide_input_bus[127:120]; 360 endcase // case (selector) 361 362 end 363 364endmodule // simple_test_3b 365 366 367// A multiplexer in terms of unique case 368module simple_test_3c 369 (input logic [8*16-1:0] wide_input_bus, 370 input logic [3:0] selector, 371 output logic [7:0] selected_out); 372 373 374 always_comb begin 375 unique case (selector) 376 4'h0: selected_out = wide_input_bus[ 7: 0]; 377 4'h1: selected_out = wide_input_bus[ 15: 8]; 378 4'h2: selected_out = wide_input_bus[ 23: 16]; 379 4'h3: selected_out = wide_input_bus[ 31: 24]; 380 4'h4: selected_out = wide_input_bus[ 39: 32]; 381 4'h5: selected_out = wide_input_bus[ 47: 40]; 382 4'h6: selected_out = wide_input_bus[ 55: 48]; 383 4'h7: selected_out = wide_input_bus[ 63: 56]; 384 4'h8: selected_out = wide_input_bus[ 71: 64]; 385 4'h9: selected_out = wide_input_bus[ 79: 72]; 386 4'ha: selected_out = wide_input_bus[ 87: 80]; 387 4'hb: selected_out = wide_input_bus[ 95: 88]; 388 4'hc: selected_out = wide_input_bus[103: 96]; 389 4'hd: selected_out = wide_input_bus[111:104]; 390 4'he: selected_out = wide_input_bus[119:112]; 391 4'hf: selected_out = wide_input_bus[127:120]; 392 endcase // case (selector) 393 394 end 395 396endmodule // simple_test_3c 397 398 399// A multiplexer in terms of unique if 400module simple_test_3d 401 (input logic [8*16-1:0] wide_input_bus, 402 input logic [3:0] selector, 403 output logic [7:0] selected_out); 404 405 406 always_comb begin 407 unique if (selector == 4'h0) selected_out = wide_input_bus[ 7: 0]; 408 else if (selector == 4'h1) selected_out = wide_input_bus[ 15: 8]; 409 else if (selector == 4'h2) selected_out = wide_input_bus[ 23: 16]; 410 else if (selector == 4'h3) selected_out = wide_input_bus[ 31: 24]; 411 else if (selector == 4'h4) selected_out = wide_input_bus[ 39: 32]; 412 else if (selector == 4'h5) selected_out = wide_input_bus[ 47: 40]; 413 else if (selector == 4'h6) selected_out = wide_input_bus[ 55: 48]; 414 else if (selector == 4'h7) selected_out = wide_input_bus[ 63: 56]; 415 else if (selector == 4'h8) selected_out = wide_input_bus[ 71: 64]; 416 else if (selector == 4'h9) selected_out = wide_input_bus[ 79: 72]; 417 else if (selector == 4'ha) selected_out = wide_input_bus[ 87: 80]; 418 else if (selector == 4'hb) selected_out = wide_input_bus[ 95: 88]; 419 else if (selector == 4'hc) selected_out = wide_input_bus[103: 96]; 420 else if (selector == 4'hd) selected_out = wide_input_bus[111:104]; 421 else if (selector == 4'he) selected_out = wide_input_bus[119:112]; 422 else if (selector == 4'hf) selected_out = wide_input_bus[127:120]; 423 end 424 425endmodule // simple_test_3d 426 427 428// Test of priority case 429// Note: This does NOT try to implement the same function as above. 430module simple_test_3e 431 (input logic [8*16-1:0] wide_input_bus, 432 input logic [3:0] selector, 433 output logic [7:0] selected_out); 434 435 436 always_comb begin 437 priority case (1'b1) 438 selector[0]: selected_out = wide_input_bus[ 7: 0]; // Bit 0 has highets priority 439 selector[2]: selected_out = wide_input_bus[ 39: 32]; // Note 2 higher priority than 1 440 selector[1]: selected_out = wide_input_bus[ 23: 16]; // Note 1 lower priority than 2 441 selector[3]: selected_out = wide_input_bus[ 71: 64]; // Bit 3 has lowest priority 442 default: selected_out = wide_input_bus[127:120]; // for selector = 0. 443 endcase // case (selector) 444 445 end 446 447endmodule // simple_test_3e 448 449 450// Test of "inside" 451// Note: This does NOT try to implement the same function as above. 452// Note: Support for "inside" is a separate Verilator feature request, so is 453// not used inside a this version of the test. 454module simple_test_3f 455 (input logic [8*16-1:0] wide_input_bus, 456 input logic [3:0] selector, 457 output logic [7:0] selected_out); 458 459 460 always_comb begin 461/* -----\/----- EXCLUDED -----\/----- 462 if ( selector[3:0] inside { 4'b?00?, 4'b1100}) // Matching 0000, 0001, 1000, 1100, 1001 463 // if ( selector[3:2] inside { 2'b?0, selector[1:0]}) 464 selected_out = wide_input_bus[ 7: 0]; 465 else 466 -----/\----- EXCLUDED -----/\----- */ 467 /* verilator lint_off CASEOVERLAP */ 468 priority casez (selector[3:0]) 469 4'b0?10: selected_out = wide_input_bus[ 15: 8]; // Matching 0010 and 0110 470 4'b0??0: selected_out = wide_input_bus[ 23: 16]; // Overlap: only 0100 remains (0000 in "if" above) 471 4'b0100: selected_out = wide_input_bus[ 31: 24]; // Overlap: Will never occur 472 default: selected_out = wide_input_bus[127:120]; // Remaining 0011,0100,0101,0111,1010,1011,1101,1110,1111 473 endcase // case (selector) 474 /* verilator lint_on CASEOVERLAP */ 475 end 476 477endmodule // simple_test_3f 478