Reputation: 53
I'm trying to code a riscv decoder in system verilog, here's the code :
case(opcode)
7'b0110011: assign r_type = 1'b1;
7'b0010011: assign i_type = 1'b1;
7'b0000011: assign i_type = 1'b1;
7'b0100011: assign s_type = 1'b1;
7'b1100011: assign b_type = 1'b0;
7'b0110111: assign u_type = 1'b1;
7'b1101111: assign j_type = 1'b1;
endcase
casez({opcode, funct3, funct7})
// r-type
{r_type, 3'b000, 7'b0000000} : assign add = 1'b1;
{r_type, 3'b000, 7'b0100000} : assign sub = 1'b1;
{r_type, 3'b001, 7'b0000000} : assign sll = 1'b1;
{r_type, 3'b010, 7'b0000000} : assign slt = 1'b1;
{r_type, 3'b011, 7'b0000000} : assign sltu = 1'b1;
{r_type, 3'b100, 7'b0000000} : assign xorr = 1'b1;
{r_type, 3'b101, 7'b0000000} : assign srl = 1'b1;
{r_type, 3'b101, 7'b0100000} : assign sra = 1'b1;
{r_type, 3'b110, 7'b0000000} : assign orr = 1'b1;
{r_type, 3'b111, 7'b0000000} : assign andd = 1'b1;
// i-type
{i_type, 3'b000, 7'b???????} : assign addi = 1'b1;
{i_type, 3'b010, 7'b???????} : assign slti = 1'b1;
{i_type, 3'b011, 7'b???????} : assign sltiu = 1'b1;
{i_type, 3'b100, 7'b???????} : assign xori = 1'b1;
{i_type, 3'b110, 7'b???????} : assign ori = 1'b1;
{i_type, 3'b111, 7'b???????} : assign andi = 1'b1;
{i_type, 3'b001, 7'b???????} : assign slli = 1'b1;
{i_type, 3'b101, 7'b???????} : assign srli = 1'b1;
{i_type, 3'b101, 7'b???????} : assign srai = 1'b1;
endcase
It seems verilator doesn't recognize that ?? marks
I tried to ue casex and casez and i search through the verilator documentation but i didn't found any information about this
Upvotes: -1
Views: 162
Reputation: 19104
A case statement outside of the always block is part of the generate construct. Per the LRM only case
and if
are supported for generate construct (IEEE1800-2017 § A.4.2 Generated instantiation). casez
is not officially supported as a generate construct. Even then, the arguments and case item index must be constant expressions. You are using opcode
, funct3
, and funct7
which are likely dynamic.
Simple solution: Use an always block. Drop the assign statments in the always block. And remember to initialize/set-default-value all variables assigned in the always block (or latches will be inferred). Reminder your variables should be defined as logic
type for SystemVerilog (reg
if Verilog).
always_comb begin // always_comb for SystemVerilog. Verilog use always @*
// set default value
r_type = 1'b0;
i_type = 1'b0;
s_type = 1'b0;
b_type = 1'b0;
u_type = 1'b0;
j_type = 1'b0;
add = 1'b0;
sub = 1'b0;
sll = 1'b0;
slt = 1'b0;
sltu = 1'b0;
xorr = 1'b0;
srl = 1'b0;
sra = 1'b0;
orr = 1'b0;
andd = 1'b0;
addi = 1'b0;
subi = 1'b0;
slli = 1'b0;
slti = 1'b0;
sltui = 1'b0;
xorri = 1'b0;
srli = 1'b0;
srai = 1'b0;
orri = 1'b0;
anddi = 1'b0;
// update
case(opcode)
7'b0110011: r_type = 1'b1;
7'b0010011: i_type = 1'b1;
7'b0000011: i_type = 1'b1;
7'b0100011: s_type = 1'b1;
7'b1100011: b_type = 1'b0;
7'b0110111: u_type = 1'b1;
7'b1101111: j_type = 1'b1;
endcase
casez({opcode, funct3, funct7})
// r-type
{7'b0110011, 3'b000, 7'b0000000} : add = 1'b1;
{7'b0110011, 3'b000, 7'b0100000} : sub = 1'b1;
{7'b0110011, 3'b001, 7'b0000000} : sll = 1'b1;
{7'b0110011, 3'b010, 7'b0000000} : slt = 1'b1;
{7'b0110011, 3'b011, 7'b0000000} : sltu = 1'b1;
{7'b0110011, 3'b100, 7'b0000000} : xorr = 1'b1;
{7'b0110011, 3'b101, 7'b0000000} : srl = 1'b1;
{7'b0110011, 3'b101, 7'b0100000} : sra = 1'b1;
{7'b0110011, 3'b110, 7'b0000000} : orr = 1'b1;
{7'b0110011, 3'b111, 7'b0000000} : andd = 1'b1;
// i-type
{7'b0010011, 3'b000, 7'b???????} : addi = 1'b1;
{7'b0010011, 3'b010, 7'b???????} : slti = 1'b1;
{7'b0010011, 3'b011, 7'b???????} : sltiu = 1'b1;
{7'b0010011, 3'b100, 7'b???????} : xori = 1'b1;
{7'b0010011, 3'b110, 7'b???????} : ori = 1'b1;
{7'b0010011, 3'b111, 7'b???????} : andi = 1'b1;
{7'b0010011, 3'b001, 7'b???????} : slli = 1'b1;
{7'b0010011, 3'b101, 7'b???????} : srli = 1'b1;
{7'b0010011, 3'b101, 7'b???????} : srai = 1'b1;
endcase
end
Upvotes: 1