EDA Playground lets you type in and run HDL code (using a selection of free and commercial simulators and synthesizers).
It's great for learning HDLs, it's great for testing out unfamiliar things and it's great for sharing code.
You can start typing straight away. But to run your code, you'll need to sign or log in. Logging in with a Google account gives you access to all non-commercial simulators and some commercial simulators:
To run commercial simulators, you need to register and log in with a username and password. Registration is free, and only pre-approved email's will have access to the commercial simulators.
206
// Code your testbench here
// or browse Examples
`include "riscv_pkg.sv"
`include "riscv_fetch.sv"
`include "riscv_decode.sv"
`include "riscv_regfile.sv"
`include "riscv_execute.sv"
`include "riscv_dmem.sv"
`include "riscv_control.sv"
module riscv_top (
input wire clk,
input wire reset,
output wire imem_psel_o,
output wire imem_penable_o,
output wire[31:0] imem_paddr_o,
output wire imem_pwrite_o,
output wire[31:0] imem_pwdata_o,
input wire imem_pready_i,
input wire[31:0] imem_prdata_i,
output wire dmem_psel_o,
output wire dmem_penable_o,
output wire[31:0] dmem_paddr_o,
output wire dmem_pwrite_o,
output wire[31:0] dmem_pwdata_o,
input wire dmem_pready_i,
input wire[31:0] dmem_prdata_i
);
wire instr_done;
wire if_dec_valid;
wire [31:0] if_dec_instr;
wire [31:0] ex_if_pc;
wire [4:0] rs1;
wire [4:0] rs2;
wire [4:0] rd;
wire [6:0] op;
wire [2:0] funct3;
wire [6:0] funct7;
logic is_r_type;
logic is_i_type;
logic is_s_type;
logic is_b_type;
logic is_u_type;
logic is_j_type;
logic[11:0] i_type_imm;
logic[11:0] s_type_imm;
logic[11:0] b_type_imm;
logic[19:0] u_type_imm;
logic[19:0] j_type_imm;
logic[1:0] pc_sel;
logic op1_sel;
logic[1:0] op2_sel;
logic[1:0] wb_sel;
logic pc4_sel;
logic mem_wr;
logic cpr_en;
logic rf_en;
logic[3:0] alu_op;
wire rf_wr_en;
wire[4:0] rf_wr_addr;
wire[31:0] rf_wr_data;
wire[4:0] rf_rd_p0;
wire[4:0] rf_rd_p1;
wire[31:0] rf_rd_p0_data;
wire[31:0] rf_rd_p1_data;
wire [31:0] opr_a;
wire [31:0] opr_b;
wire [3:0] op_sel;
wire [31:0] ex_res;
wire ex_dmem_valid;
wire[31:0] ex_dmem_addr;
wire[31:0] ex_dmem_wdata;
wire ex_dmem_wnr;
logic[31:0] dmem_data;
logic dmem_done;
logic[31:0] imm_sign_ext;
logic mem_op;
// Instantiate and connect all the submodules
assign instr_done = dmem_done | ~mem_op;
riscv_fetch FETCH (
.clk (clk),
.reset (reset),
.instr_done_i (instr_done),
.psel_o (imem_psel_o),
.penable_o (imem_penable_o),
.paddr_o (imem_paddr_o),
.pwrite_o (imem_pwrite_o),
.pwdata_o (imem_pwdata_o),
.pready_i (imem_pready_i),
.prdata_i (imem_prdata_i),
.if_dec_valid_o (if_dec_valid),
.if_dec_instr_o (if_dec_instr),
.ex_if_pc_i (ex_if_pc)
);
riscv_decode DECODE (
.if_dec_instr_i (if_dec_instr),
.rs1_o (rs1),
.rs2_o (rs2),
.rd_o (rd),
.op_o (op),
.funct3_o (funct3),
.funct7_o (funct7),
.is_r_type_o (is_r_type),
.is_i_type_o (is_i_type),
.is_s_type_o (is_s_type),
.is_b_type_o (is_b_type),
.is_u_type_o (is_u_type),
.is_j_type_o (is_j_type),
.i_type_imm_o (i_type_imm),
.s_type_imm_o (s_type_imm),
.b_type_imm_o (b_type_imm),
.u_type_imm_o (u_type_imm),
.j_type_imm_o (j_type_imm)
);
assign rf_wr_en = rf_en;
assign rf_wr_addr = rd;
assign rf_wr_data = wb_sel[0] ? ex_res :
wb_sel[1] ? ex_if_pc + 32'h4 :
dmem_data;
riscv_regfile REGFILE (
.clk (clk),
.reset (reset),
.rf_wr_en_i (rf_wr_en),
.rf_wr_addr_i (rf_wr_addr),
.rf_wr_data_i (rf_wr_data),
.rf_rd_p0_i (rf_rd_p0),
.rf_rd_p1_i (rf_rd_p1),
.rf_rd_p0_data_o (rf_rd_p0_data),
.rf_rd_p1_data_o (rf_rd_p1_data)
);
// Sign extend the immediate
assign imm_sign_ext = (is_i_type) ? {{30{i_type_imm[11]}}, i_type_imm} :
(is_s_type) ? {{30{s_type_imm[11]}}, s_type_imm} :
(is_b_type) ? {{30{b_type_imm[11]}}, b_type_imm} :
(is_u_type) ? {{12{u_type_imm[19]}}, u_type_imm} :
{{12{j_type_imm[19]}}, j_type_imm};
// Send the correct data to the ALU
assign opr_a = op1_sel ? imm_sign_ext : rf_rd_p0_data;
assign opr_b = &op2_sel ? rf_rd_p1_data :
op2_sel[0] ? imm_sign_ext :
ex_if_pc;
riscv_execute EXECUTE (
.opr_a_i (opr_a),
.opr_b_i (opr_b),
.op_sel_i (alu_op),
.ex_res_o (ex_res)
);
assign mem_op = is_s_type | (is_i_type & (op == 7'h3));
assign dmem_valid = if_dec_valid & mem_op;
assign ex_dmem_addr = ex_res;
assign ex_dmem_wnr = mem_wr;
assign ex_dmem_wdata = rf_rd_p0_data;
riscv_dmem DMEM (
.clk (clk),
.reset (reset),
.ex_dmem_valid_i (ex_dmem_valid), // Mem operation is valid
.ex_dmem_addr_i (ex_dmem_addr),
.ex_dmem_wdata_i (ex_dmem_wdata),
.ex_dmem_wnr_i (ex_dmem_wnr), // 1 - write, 0 - read
.psel_o (dmem_psel_o),
.penable_o (dmem_penable_o),
.paddr_o (dmem_paddr_o),
.pwrite_o (dmem_pwrite_o),
.pwdata_o (dmem_pwdata_o),
.pready_i (dmem_pready_i),
.prdata_i (dmem_prdata_i),
.dmem_data_o (dmem_data),
.dmem_done_o (dmem_done)
);
riscv_control CONTROL (
.instr_funct3_i (funct3),
.instr_funct7_i (funct7),
.instr_op_i (op),
.is_r_type_i (is_r_type),
.is_i_type_i (is_i_type),
.is_s_type_i (is_s_type),
.is_b_type_i (is_b_type),
.is_u_type_i (is_u_type),
.is_j_type_i (is_j_type),
.pc_sel_o (pc_sel),
.op1_sel_o (op1_sel),
.op2_sel_o (op2_sel),
.wb_sel_o (wb_sel),
.pc4_sel_o (pc4_sel),
.mem_wr_o (mem_wr),
.cpr_en_o (/* TODO */),
.rf_en_o (rf_en),
.alu_op_o (alu_op)
);
endmodule
xxxxxxxxxx
module riscv_decode (
input logic[31:0] if_dec_instr_i,
output logic[4:0] rs1_o,
output logic[4:0] rs2_o,
output logic[4:0] rd_o,
output logic[6:0] op_o,
output logic[2:0] funct3_o,
output logic[6:0] funct7_o,
output logic is_r_type_o,
output logic is_i_type_o,
output logic is_s_type_o,
output logic is_b_type_o,
output logic is_u_type_o,
output logic is_j_type_o,
output logic[11:0] i_type_imm_o,
output logic[11:0] s_type_imm_o,
output logic[11:0] b_type_imm_o,
output logic[19:0] u_type_imm_o,
output logic[19:0] j_type_imm_o
);
assign rd_o = if_dec_instr_i[11:7];
assign rs1_o = if_dec_instr_i[19:15];
assign rs2_o = if_dec_instr_i[24:20];
assign op_o = if_dec_instr_i[6:0];
assign funct3_o = if_dec_instr_i[14:12];
assign funct7_o = if_dec_instr_i[31:25];
// Decode the type of the instruction
always_comb begin
is_r_type_o = 1'b0;
is_i_type_o = 1'b0;
is_s_type_o = 1'b0;
is_b_type_o = 1'b0;
is_u_type_o = 1'b0;
is_j_type_o = 1'b0;
case (op_o)
7'h33 : is_r_type_o = 1'b1;
// I-type data processing
// I-type LW
// JALR
7'h13,
7'h03,
7'h67 : is_i_type_o = 1'b1;
7'h23 : is_s_type_o = 1'b1;
7'h63 : is_b_type_o = 1'b1;
7'h6F : is_j_type_o = 1'b1;
endcase
end
assign i_type_imm_o[11:0] = if_dec_instr_i[31:20];
assign s_type_imm_o[11:0] = {if_dec_instr_i[31:25], if_dec_instr_i[11:7]};
assign b_type_imm_o[11:0] = {if_dec_instr_i[31], if_dec_instr_i[7], if_dec_instr_i[30:25],
if_dec_instr_i[11:8]};
assign u_type_imm_o[19:0] = if_dec_instr_i[31:12];
assign j_type_imm_o[19:0] = {if_dec_instr_i[31], if_dec_instr_i[19:12], if_dec_instr_i[20],
if_dec_instr_i[30:21]};
endmodule
xxxxxxxxxx
// APB Master for the instruction fetch unit
module riscv_fetch (
input wire clk,
input wire reset,
input wire instr_done_i,
// ------------------------------------------------------------
// APB Interface to memory
// ------------------------------------------------------------
output wire psel_o,
output wire penable_o,
output wire[31:0] paddr_o,
output wire pwrite_o,
output wire[31:0] pwdata_o,
input wire pready_i,
input wire[31:0] prdata_i,
// ------------------------------------------------------------
// Instruction output
// ------------------------------------------------------------
output logic if_dec_valid_o,
output logic[31:0] if_dec_instr_o,
input wire[31:0] ex_if_pc_i
);
// Enum for the APB state
typedef enum logic[1:0] {ST_IDLE = 2'b00, ST_SETUP = 2'b01, ST_ACCESS = 2'b10} apb_state_t;
apb_state_t nxt_state;
apb_state_t state_q;
logic [31:0] if_pc_q;
logic nxt_dec_valid;
always_ff @(posedge clk or posedge reset)
if (reset)
state_q <= ST_IDLE;
else
state_q <= nxt_state;
always_comb begin
nxt_state = state_q;
case (state_q)
// Memory responses may not be single cycle. Wait for the
// memory request to complete before requesting the next
// instruction
ST_IDLE : nxt_state = instr_done_i ? ST_SETUP : ST_IDLE;
ST_SETUP : nxt_state = ST_ACCESS;
ST_ACCESS : begin
if (pready_i) nxt_state = ST_IDLE;
end
endcase
end
assign psel_o = (state_q == ST_SETUP) | (state_q == ST_ACCESS);
assign penable_o = (state_q == ST_ACCESS);
assign pwrite_o = 1'b0; // No writes to IMEM
assign paddr_o = if_pc_q; // Current instruction counter
assign pwdata_o = 32'h0;
// Start from 0x8000_0000 on reset
always_ff @(posedge clk or posedge reset)
if (reset)
if_pc_q <= 32'h8000_0000;
else
if_pc_q <= ex_if_pc_i;
// Capture the read data as the current instruction opcode
always_ff @(posedge clk or posedge reset)
if (reset) begin
if_dec_instr_o <= 32'h0;
end else if (penable_o && pready_i) begin
if_dec_instr_o <= prdata_i;
end
always_ff @(posedge clk or posedge reset)
if (reset) begin
if_dec_valid_o <= 1'b0;
end else if ((penable_o && pready_i) | if_dec_valid_o) begin
if_dec_valid_o <= nxt_dec_valid;
end
// Set valid on:
// - Valid APB transfer and clear it next cycle if no valid transfer
// and if the flag was set
assign nxt_dec_valid = (penable_o && pready_i);
endmodule
xxxxxxxxxx
module riscv_regfile (
input wire clk,
input wire reset,
// Single write address
input wire rf_wr_en_i,
input wire[4:0] rf_wr_addr_i,
input wire[31:0] rf_wr_data_i,
// Two read addresses
input wire[4:0] rf_rd_p0_i,
input wire[4:0] rf_rd_p1_i,
output wire[31:0] rf_rd_p0_data_o,
output wire[31:0] rf_rd_p1_data_o
);
// Register file
logic [31:0] reg_file [31:0];
// Write logic
always_ff @(posedge clk)
if (rf_wr_en_i)
reg_file[rf_wr_addr_i] <= rf_wr_data_i;
// Read logic
assign rf_rd_p0_data_o = 32'(|rf_rd_p0_i) & reg_file[rf_rd_p0_i];
assign rf_rd_p0_data_o = 32'(|rf_rd_p1_i) & reg_file[rf_rd_p1_i];
endmodule
xxxxxxxxxx
`include "riscv_pkg.sv"
module riscv_execute import riscv_pkg::*; (
input wire [31:0] opr_a_i,
input wire [31:0] opr_b_i,
input wire [3:0] op_sel_i,
output wire [31:0] ex_res_o
);
logic [31:0] alu_res;
logic signed [31:0] sign_opr_a;
logic signed [31:0] sign_opr_b;
assign sign_opr_a = opr_a_i;
assign sign_opr_b = opr_b_i;
always_comb begin
alu_res = 32'h0;
case (op_sel_i)
OP_ADD: alu_res = opr_a_i + opr_b_i;
OP_SUB: alu_res = opr_a_i - opr_b_i;
OP_SLL: alu_res = opr_a_i << opr_b_i[4:0];
OP_LSR: alu_res = opr_a_i >> opr_b_i[4:0];
OP_ASR: alu_res = sign_opr_a >>> opr_b_i[4:0];
OP_OR: alu_res = opr_a_i | opr_b_i;
OP_AND: alu_res = opr_a_i & opr_b_i;
OP_XOR: alu_res = opr_a_i ^ opr_b_i;
OP_EQL: alu_res = {31'h0, opr_a_i == opr_b_i};
OP_ULT: alu_res = {31'h0, opr_a_i < opr_b_i};
OP_UGT: alu_res = {31'h0, opr_a_i >= opr_b_i};
OP_SLT: alu_res = {31'h0, sign_opr_a < sign_opr_b};
OP_SGT: alu_res = {31'h0, sign_opr_a >= sign_opr_b};
endcase
end
assign ex_res_o = alu_res;
endmodule
xxxxxxxxxx
// APB Master for the data memory unit
module riscv_dmem (
input wire clk,
input wire reset,
input wire ex_dmem_valid_i, // Mem operation is valid
input wire[31:0] ex_dmem_addr_i,
input wire[31:0] ex_dmem_wdata_i,
input wire ex_dmem_wnr_i, // 1 - write, 0 - read
// ------------------------------------------------------------
// APB Interface to memory
// ------------------------------------------------------------
output wire psel_o,
output wire penable_o,
output wire[31:0] paddr_o,
output wire pwrite_o,
output wire[31:0] pwdata_o,
input wire pready_i,
input wire[31:0] prdata_i,
// ------------------------------------------------------------
// Data output
// ------------------------------------------------------------
output logic[31:0] dmem_data_o,
output logic dmem_done_o
);
// Enum for the APB state
typedef enum logic[1:0] {ST_IDLE = 2'b00, ST_SETUP = 2'b01, ST_ACCESS = 2'b10} apb_state_t;
apb_state_t nxt_state;
apb_state_t state_q;
logic [31:0] if_pc_q;
always_ff @(posedge clk or posedge reset)
if (reset)
state_q <= ST_IDLE;
else
state_q <= nxt_state;
always_comb begin
nxt_state = state_q;
case (state_q)
ST_IDLE : nxt_state = ex_dmem_valid_i ? ST_SETUP : ST_IDLE;
ST_SETUP : nxt_state = ST_ACCESS;
ST_ACCESS : begin
if (pready_i) nxt_state = ST_IDLE;
end
endcase
end
assign psel_o = (state_q == ST_SETUP) | (state_q == ST_ACCESS);
assign penable_o = (state_q == ST_ACCESS);
assign pwrite_o = ex_dmem_wnr_i;
assign paddr_o = ex_dmem_addr_i; // Memory address
assign pwdata_o = ex_dmem_wdata_i;
assign dmem_done_o = penable_o && pready_i;
assign dmem_data_o = prdata_i;
endmodule
xxxxxxxxxx
`include "riscv_pkg.sv"
module riscv_control import riscv_pkg::*; (
input wire[2:0] instr_funct3_i,
input wire[6:0] instr_funct7_i,
input wire[6:0] instr_op_i,
input wire is_r_type_i,
input wire is_i_type_i,
input wire is_s_type_i,
input wire is_b_type_i,
input wire is_u_type_i,
input wire is_j_type_i,
output logic[1:0] pc_sel_o,
output logic op1_sel_o,
output logic[1:0] op2_sel_o,
output logic[1:0] wb_sel_o,
output logic pc4_sel_o,
output logic mem_wr_o,
output logic cpr_en_o,
output logic rf_en_o,
output logic[3:0] alu_op_o
);
logic[14:0] controls;
logic[3:0] instr_funct_ctl;
logic[4:0] instr_op_ctl;
assign {pc_sel_o, op1_sel_o, op2_sel_o, wb_sel_o,
pc4_sel_o, mem_wr_o, cpr_en_o, rf_en_o, alu_op_o} = controls;
assign instr_funct_ctl = {instr_funct7_i[5], instr_funct3_i};
assign instr_op_ctl = {instr_op_i[4], {1'b0, instr_funct3_i}};
always_comb begin
case (1'b1)
is_r_type_i : begin
// Drive control signals for the R-type instruction
case (instr_funct_ctl)
ADD : controls = {2'b00, 1'b0, 2'b11, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_ADD};
AND : controls = {2'b00, 1'b0, 2'b11, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_AND};
OR : controls = {2'b00, 1'b0, 2'b11, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_OR};
SLL : controls = {2'b00, 1'b0, 2'b11, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_SLL};
SLT : controls = {2'b00, 1'b0, 2'b11, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_SLT};
SLTU : controls = {2'b00, 1'b0, 2'b11, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_SLT};
SRA : controls = {2'b00, 1'b0, 2'b11, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_ASR};
SRL : controls = {2'b00, 1'b0, 2'b11, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_LSR};
SUB : controls = {2'b00, 1'b0, 2'b11, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_SUB};
XOR : controls = {2'b00, 1'b0, 2'b11, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_XOR};
default: controls = {2'b00, 1'b0, 2'b11, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_ADD};
endcase
end
is_i_type_i : begin
case (instr_op_ctl)
LB : controls = {2'b00, 1'b0, 2'b01, 2'b00, 1'b0, 1'b0, 1'b0, 1'b1, OP_ADD};
LBU : controls = {2'b00, 1'b0, 2'b01, 2'b00, 1'b0, 1'b0, 1'b0, 1'b1, OP_ADD};
LH : controls = {2'b00, 1'b0, 2'b01, 2'b00, 1'b0, 1'b0, 1'b0, 1'b1, OP_ADD};
LHU : controls = {2'b00, 1'b0, 2'b01, 2'b00, 1'b0, 1'b0, 1'b0, 1'b1, OP_ADD};
LW : controls = {2'b00, 1'b0, 2'b01, 2'b00, 1'b0, 1'b0, 1'b0, 1'b1, OP_ADD};
ADDI : controls = {2'b00, 1'b0, 2'b01, 2'b01, 1'b1, 1'b0, 1'b0, 1'b1, OP_ADD};
ANDI : controls = {2'b00, 1'b0, 2'b01, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_AND};
ORI : controls = {2'b00, 1'b0, 2'b01, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_OR};
SLLI : controls = {2'b00, 1'b0, 2'b01, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_SLL};
SRLI : controls = {2'b00, 1'b0, 2'b01, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_LSR};
SLTI : controls = {2'b00, 1'b0, 2'b01, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_SLT};
SLTIU : controls = {2'b00, 1'b0, 2'b01, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_SLT};
//SRAI : controls = {2'b00, 1'b0, 2'b01, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_ASR};
XORI : controls = {2'b00, 1'b0, 2'b01, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_XOR};
JALR : controls = {2'b00, 1'b0, 2'b01, 2'b10, 1'b1, 1'b0, 1'b0, 1'b1, OP_ADD};
default: controls = {2'b00, 1'b0, 2'b01, 2'b00, 1'b0, 1'b0, 1'b0, 1'b1, OP_ADD};
endcase
end
is_s_type_i : begin
case (6'(instr_funct3_i))
SB: controls = {2'b00, 1'b0, 2'b01, 2'b01, 1'b0, 1'b1, 1'b0, 1'b0, OP_ADD};
SH: controls = {2'b00, 1'b0, 2'b01, 2'b01, 1'b0, 1'b1, 1'b0, 1'b0, OP_ADD};
SW: controls = {2'b00, 1'b0, 2'b01, 2'b01, 1'b0, 1'b1, 1'b0, 1'b0, OP_ADD};
default: controls = '0;
endcase
end
is_b_type_i : begin
case (6'(instr_funct3_i))
BEQ : controls = {2'b01, 1'b0, 2'b11, 2'b00, 1'b0, 1'b0, 1'b0, 1'b0, OP_SUB};
BNE : controls = {2'b01, 1'b0, 2'b11, 2'b00, 1'b0, 1'b0, 1'b0, 1'b0, OP_SUB};
BLT : controls = {2'b01, 1'b0, 2'b11, 2'b00, 1'b0, 1'b0, 1'b0, 1'b0, OP_SUB};
BGE : controls = {2'b01, 1'b0, 2'b11, 2'b00, 1'b0, 1'b0, 1'b0, 1'b0, OP_SUB};
BLTU : controls = {2'b01, 1'b0, 2'b11, 2'b00, 1'b0, 1'b0, 1'b0, 1'b0, OP_ULT};
BGEU : controls = {2'b01, 1'b0, 2'b11, 2'b00, 1'b0, 1'b0, 1'b0, 1'b0, OP_UGT};
default: controls = '0;
endcase
end
is_u_type_i : begin
case (instr_op_i[5:0])
AUIPC : controls = {2'b00, 1'b1, 2'b10, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_ADD};
LUI : controls = {2'b00, 1'b1, 2'b00, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_ADD};
default: controls = '0;
endcase
end
is_j_type_i : begin
controls = {2'b01, 1'b1, 2'b10, 2'b01, 1'b0, 1'b0, 1'b0, 1'b1, OP_ADD};
end
default: controls = '0;
endcase
end
endmodule
xxxxxxxxxx
`ifndef RISCV_PKG
`define RISCV_PKG
package riscv_pkg;
// Supported ALU Operations
typedef enum logic[3:0] {
OP_ADD = 4'b0000,
OP_SUB = 4'b0001,
OP_SLL = 4'b0010,
OP_LSR = 4'b0011,
OP_ASR = 4'b0100,
OP_OR = 4'b0101,
OP_AND = 4'b0110,
OP_XOR = 4'b0111,
OP_EQL = 4'b1000,
OP_ULT = 4'b1001,
OP_UGT = 4'b1010,
OP_SLT = 4'b1011,
OP_SGT = 4'b1100} alu_op_t;
typedef enum logic [5:0] {
// R-type defines
ADD = 6'h0,
AND = 6'h7,
OR = 6'h6,
SLL = 6'h1,
SLT = 6'h2,
SLTU = 6'h3,
SRA = 6'hD,
SRL = 6'h5,
SUB = 6'h8,
XOR = 6'h4 } r_type_instr_t;
typedef enum logic [5:0] {
// I-type defines
LB = 6'h0,
LBU = 6'h4,
LH = 6'h1,
LHU = 6'h5,
LW = 6'h2,
ADDI = 6'h10, // Formed with {opc[4], {1'b0, funct3}}
ANDI = 6'h1C,
ORI = 6'h16,
SLLI = 6'h11,
SRLI = 6'h15,
SLTI = 6'h12,
SLTIU = 6'h13,
//SRAI = 6'h15, // TODO: Update enum to avoid duplicates
XORI = 6'h14,
JALR = 6'h7
} i_type_instr_t;
typedef enum logic [5:0] {
SB = 6'h0,
SH = 6'h1,
SW = 6'h2
} s_type_instr_t;
typedef enum logic [5:0] {
BEQ = 6'h0,
BNE = 6'h1,
BLT = 6'h4,
BGE = 6'h5,
BLTU = 6'h6,
BGEU = 6'h7
} b_type_instr_t;
typedef enum logic [5:0] {
AUIPC = 6'h27,
LUI = 6'h37
} u_type_instr_t;
typedef enum logic [5:0] {
JAL = 6'h3
} j_type_instr_t;
endpackage
`endif
Your account is not validated. If you wish to use commercial simulators, you need a validated account.
If you have already registered (or have recently changed your email address), but have not clicked on the link in the email we sent you, please do so. If you cannot find the email, please check your spam/junk folder. Or click here to resend the email.
If you have not already registered for a full account, you can do so by clicking below. You will then need to provide us with some identification information. You may wish to save your code first.
Creating, deleting, and renaming files is not supported during Collaboration. To encourage development of these features for Collaboration, tweet to @EDAPlayground
This playground may have been modified. Please save or copy before starting collaboration.
Your exercise has been submitted.