system verilog中新加了很多幅值语句,虽然都只适用于阻塞幅值,但是在某些场合中非常实用。
下面是一段有意思的代码,覆盖了一些用法。
1 package definitions; 2 typedef enum logic [2:0] {ADD,SUB,MULT,DIV,SL,SR} opcode_t; 3 typedef enum logic {UNSIGNED, SIGNED} operand_type_t; 4 typedef union packed { 5 logic [23:0] u_data; 6 logic signed [23:0] s_data; 7 } data_t; 8 typedef struct packed { 9 opcode_t opc; 10 operand_type_t op_type; 11 data_t op_a; 12 data_t op_b; 13 } instruction_t; 14 endpackage // definitions 15 16 import definitions::*; // import package into $unit space 17 18 module alu (input instruction_t instr, output data_t alu_out); 19 always_comb begin 20 if (instr.op_type == SIGNED) begin 21 alu_out.s_data = instr.op_a.s_data; 22 unique case (instr.opc) 23 ADD : alu_out.s_data += instr.op_b.s_data; 24 SUB : alu_out.s_data -= instr.op_b.s_data; 25 MULT : alu_out.s_data *= instr.op_b.s_data; 26 DIV : alu_out.s_data /= instr.op_b.s_data; 27 SL : alu_out.s_data <<<= 2; 28 SR : alu_out.s_data >>>= 2; 29 endcase 30 176 SystemVerilog for Design 31 end 32 else begin 33 alu_out.u_data = instr.op_a.u_data; 34 unique case (instr.opc) 35 ADD : alu_out.u_data += instr.op_b.u_data; 36 SUB : alu_out.u_data -= instr.op_b.u_data; 37 MULT : alu_out.u_data *= instr.op_b.u_data; 38 DIV : alu_out.u_data /= instr.op_b.u_data; 39 SL : alu_out.u_data <<= 2; 40 SR : alu_out.u_data >>= 2; 41 endcase 42 end 43 end 44 endmodule
代码中使用了package,structure以及一些新加的赋值语句。
注意这里使用的是always_comb,因为这些赋值语句都相当于阻塞赋值。