//definitions.sv
1 package definitions; 2 3 parameter VERSION = "1.2"; 4 5 typedef enum bit [2:0] {ADD, SUB, MULT, DIV, SL, SR} opcodes_t; 6 7 typedef logic [31:0] data_t; 8 9 typedef struct packed { 10 opcodes_t opc; 11 data_t op_a; 12 data_t op_b; 13 } instr_t; 14 15 endpackage
//ALU.sv
1 import definitions :: *; 2 3 module ALU( 4 input logic clock, 5 input instr_t IW, 6 output data_t alu_out ); 7 8 always @(posedge clock) begin 9 case (IW.opc) 10 ADD : alu_out = IW.op_a + IW.op_b; 11 SUB : alu_out = IW.op_a - IW.op_b; 12 MULT : alu_out = IW.op_a * IW.op_b; 13 DIV : alu_out = IW.op_a / IW.op_b; 14 SL : alu_out = IW.op_a << 1; 15 SR : alu_out = IW.op_a >> 1; 16 endcase 17 end 18 19 endmodule
//test.sv
import definitions :: *; module test; timeunit 10ns; timeprecision 1ns; instr_t IW; logic [31:0] alu_out; logic clock; ALU dut (.IW(IW), .alu_out(alu_out), .clock(clock)); initial begin clock = 0; forever #10 clock = ~ clock; end initial begin @(negedge clock) IW = {ADD, 123, 456}; @(negedge clock) IW = {SUB, 762, 456}; @(negedge clock) IW = {DIV, 900, 12}; @(negedge clock) IW = {MULT, 12, 46}; @(negedge clock) IW = {SL, 123, 0}; @(negedge clock) IW = {SR, 123, 0}; #40 $stop; end initial begin $monitor("%t\t%4d\t%4s\t%4d\t=%4d", $realtime, IW.op_a, IW.opc, IW.op_b, alu_out); end endmodule
# 0 x ADD x = x
# 200000 123 ADD 456 = x
# 300000 123 ADD 456 = 579
# 400000 762 SUB 456 = 579
# 500000 762 SUB 456 = 306
# 600000 900 DIV 12 = 306
# 700000 900 DIV 12 = 75
# 800000 12 MULT 46 = 75
# 900000 12 MULT 46 = 552
# 1000000 123 SL 0 = 552
# 1100000 123 SL 0 = 246
# 1200000 123 SR 0 = 246
# 1300000 123 SR 0 = 61