Skip to content

Instantly share code, notes, and snippets.

@zxmarcos
Created April 19, 2021 00:37
Show Gist options
  • Save zxmarcos/366d790f2cda1a33d1b63a05c3ff6f81 to your computer and use it in GitHub Desktop.
Save zxmarcos/366d790f2cda1a33d1b63a05c3ff6f81 to your computer and use it in GitHub Desktop.
module riscv_dasm();
//----------------------
task dasm(input [31:0] instr, output [20*8:0] dbuff);
reg [4:0] rd;
reg [4:0] rs1;
reg [4:0] rs2;
reg [2:0] funct3;
reg [6:0] funct7;
reg [6:0] opcode;
reg [31:0] imm_u_type;
reg [31:0] imm_i_type;
reg [31:0] imm_b_type;
reg [31:0] imm_j_type;
reg [31:0] imm_s_type;
reg[20*8:0] dasmbuf;
begin
rd = instr[11:7];
rs1 = instr[19:15];
rs2 = instr[24:20];
funct3 = instr[14:12];
funct7 = instr[31:25];
opcode = instr[6:0];
// Immediate values
imm_u_type = { instr[31:12], 12'b0 };
imm_i_type = { {20{instr[31]}}, instr[31:20] };
imm_b_type = { {19{instr[31]}}, instr[31], instr[ 7], instr[30:25], instr[11: 8], 1'b0 };
imm_j_type = { {11{instr[31]}}, instr[31], instr[19:12], instr[ 20], instr[30:21], 1'b0 };
imm_s_type = { {20{instr[31]}}, instr[31:25], instr[11: 7] };
if (opcode == 7'b0110111)
begin
$sformat(dasmbuf, "lui x%0d, %0d", rd, imm_u_type);
end else if (opcode == 7'b0010111)
begin
$sformat(dasmbuf, "auipc x%0d, %0d", rd, imm_u_type);
end else if (opcode == 7'b0010011)
begin
if (rd == rs1 && rd == 0)
begin
$sformat(dasmbuf, "nop");
end
else
begin
case (funct3)
3'b000: $sformat(dasmbuf, "addi x%0d, x%0d, %0d", rd, rs1, imm_i_type);
3'b001: $sformat(dasmbuf, "slli x%0d, x%0d, %0d", rd, rs1, imm_i_type);
3'b010: $sformat(dasmbuf, "slti x%0d, x%0d, %0d", rd, rs1, imm_i_type);
3'b011: $sformat(dasmbuf, "sltui x%0d, x%0d, %0d", rd, rs1, imm_i_type);
3'b100: $sformat(dasmbuf, "xori x%0d, x%0d, %0d", rd, rs1, imm_i_type);
3'b101: $sformat(dasmbuf, "%si x%0d, x%0d, %0d", (funct7 == 7'h20) ? "sra" : "srl", rd, rs1, imm_i_type);
3'b110: $sformat(dasmbuf, "ori x%0d, x%0d, %0d", rd, rs1, imm_i_type);
3'b111: $sformat(dasmbuf, "andi x%0d, x%0d, %0d", rd, rs1, imm_i_type);
endcase
end
end else if (opcode == 7'b0110011)
begin
if (rd == 0)
begin
$sformat(dasmbuf, "nop");
end
else
begin
case (funct3)
3'b000: $sformat(dasmbuf, "%s x%0d, x%0d, x%0d", (funct7 == 7'h20) ? "sub" : "add", rd, rs1, rs2);
3'b001: $sformat(dasmbuf, "sll x%0d, x%0d, x%0d", rd, rs1, rs2);
3'b010: $sformat(dasmbuf, "slt x%0d, x%0d, x%0d", rd, rs1, rs2);
3'b011: $sformat(dasmbuf, "sltu x%0d, x%0d, x%0d", rd, rs1, rs2);
3'b100: $sformat(dasmbuf, "xor x%0d, x%0d, x%0d", rd, rs1, rs2);
3'b101: $sformat(dasmbuf, "%s x%0d, x%0d, x%0d", (funct7 == 7'h20) ? "sra" : "srl", rd, rs1, rs2);
3'b110: $sformat(dasmbuf, "or x%0d, x%0d, x%0d", rd, rs1, rs2);
3'b111: $sformat(dasmbuf, "and x%0d, x%0d, x%0d", rd, rs1, rs2);
endcase
end
end else if (opcode == 7'b1100011)
begin
case (funct3)
3'b000: $sformat(dasmbuf, "beq x%0d, x%0d, %0d", rs1, rs2, imm_b_type); // BEQ
3'b001: $sformat(dasmbuf, "bne x%0d, x%0d, %0d", rs1, rs2, imm_b_type); // BNE
3'b100: $sformat(dasmbuf, "blt x%0d, x%0d, %0d", rs1, rs2, imm_b_type); // BLT
3'b101: $sformat(dasmbuf, "bge x%0d, x%0d, %0d", rs1, rs2, imm_b_type); // BGE
3'b110: $sformat(dasmbuf, "bltu x%0d, x%0d, %0d", rs1, rs2, imm_b_type); // BLTU
3'b111: $sformat(dasmbuf, "bgeu x%0d, x%0d, %0d", rs1, rs2, imm_b_type); // BGEU
default: $sformat(dasmbuf, "???");
endcase
end else if (opcode == 7'b0000011)
begin
case (funct3)
3'b000: $sformat(dasmbuf, "lb x%0d, x%0d(%0d)", rd, rs1, imm_i_type);
3'b001: $sformat(dasmbuf, "lh x%0d, x%0d(%0d)", rd, rs1, imm_i_type);
3'b010: $sformat(dasmbuf, "lw x%0d, x%0d(%0d)", rd, rs1, imm_i_type);
3'b100: $sformat(dasmbuf, "lbu x%0d, x%0d(%0d)", rd, rs1, imm_i_type);
3'b101: $sformat(dasmbuf, "lhu x%0d, x%0d(%0d)", rd, rs1, imm_i_type);
default: $sformat(dasmbuf, "???");
endcase
end else if (opcode == 7'b0100011)
begin
case (funct3)
3'b000: $sformat(dasmbuf, "sb x%0d, x%0d(%0d)", rs2, rs1, imm_s_type);
3'b001: $sformat(dasmbuf, "sh x%0d, x%0d(%0d)", rs2, rs1, imm_s_type);
3'b010: $sformat(dasmbuf, "sw x%0d, x%0d(%0d)", rs2, rs1, imm_s_type);
default: $sformat(dasmbuf, "???");
endcase
end else $sformat(dasmbuf, "???");
dbuff = dasmbuf;
end
endtask
endmodule
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment