Line 8... |
Line 8... |
// Email: admin@ultra-embedded.com
|
// Email: admin@ultra-embedded.com
|
//
|
//
|
// License: LGPL
|
// License: LGPL
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
//
|
//
|
// Copyright (C) 2011 - 2013 Ultra-Embedded.com
|
// Copyright (C) 2011 - 2014 Ultra-Embedded.com
|
//
|
//
|
// This source file may be used and distributed without
|
// This source file may be used and distributed without
|
// restriction provided that this copyright statement is not
|
// restriction provided that this copyright statement is not
|
// removed from the file and that any derivative work contains
|
// removed from the file and that any derivative work contains
|
// the original copyright notice and the associated disclaimer.
|
// the original copyright notice and the associated disclaimer.
|
Line 84... |
Line 84... |
// Reg D
|
// Reg D
|
input [4:0] reg_rd_i /*verilator public*/,
|
input [4:0] reg_rd_i /*verilator public*/,
|
|
|
// Output
|
// Output
|
output [31:0] opcode_o /*verilator public*/,
|
output [31:0] opcode_o /*verilator public*/,
|
|
output [31:0] opcode_pc_o /*verilator public*/,
|
output [4:0] reg_rd_o /*verilator public*/,
|
output [4:0] reg_rd_o /*verilator public*/,
|
output [31:0] reg_rd_value_o /*verilator public*/,
|
output [31:0] reg_rd_value_o /*verilator public*/,
|
output mult_o /*verilator public*/,
|
output mult_o /*verilator public*/,
|
output [31:0] mult_res_o /*verilator public*/,
|
output [31:0] mult_res_o /*verilator public*/,
|
|
|
Line 122... |
Line 123... |
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
// Registers
|
// Registers
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
|
|
// Branch PC
|
// Branch PC
|
reg [31:0] r_pc_branch;
|
reg [31:0] pc_branch_q;
|
reg r_pc_fetch;
|
reg pc_fetch_q;
|
|
|
// Exception saved program counter
|
// Exception saved program counter
|
reg [31:0] r_epc;
|
reg [31:0] epc_q;
|
|
|
// Supervisor register
|
// Supervisor register
|
reg [31:0] r_sr;
|
reg [31:0] sr_q;
|
|
|
// Exception saved supervisor register
|
// Exception saved supervisor register
|
reg [31:0] r_esr;
|
reg [31:0] esr_q;
|
|
|
// Destination register number (post execute stage)
|
// Destination register number (post execute stage)
|
reg [4:0] r_e_rd;
|
reg [4:0] ex_rd_q;
|
|
|
// Current opcode (PC for debug)
|
// Current opcode (PC for debug)
|
reg [31:0] r_e_opcode;
|
reg [31:0] ex_opcode_q;
|
reg [31:0] r_e_opcode_pc;
|
reg [31:0] ex_opcode_pc_q;
|
|
|
// ALU input A
|
// ALU input A
|
reg [31:0] r_e_alu_a;
|
reg [31:0] ex_alu_a_q;
|
|
|
// ALU input B
|
// ALU input B
|
reg [31:0] r_e_alu_b;
|
reg [31:0] ex_alu_b_q;
|
|
|
// ALU output
|
// ALU output
|
wire [31:0] r_e_result;
|
wire [31:0] ex_result_w;
|
|
|
// Resolved RA/RB register contents
|
// Resolved RA/RB register contents
|
wire [31:0] ra_value_resolved;
|
wire [31:0] ra_resolved_w;
|
wire [31:0] rb_value_resolved;
|
wire [31:0] rb_resolved_w;
|
wire operand_resolved;
|
wire operand_resolved_w;
|
wire resolve_failed;
|
wire resolve_failed_w;
|
|
|
// ALU Carry
|
// ALU Carry
|
wire alu_carry_out;
|
wire alu_carry_out_w;
|
wire alu_carry_update;
|
wire alu_carry_update_w;
|
wire alu_flag_update;
|
wire alu_flag_update_w;
|
|
|
// ALU Comparisons
|
// ALU Comparisons
|
wire compare_equal_w;
|
wire compare_equal_w;
|
wire compare_gts_w;
|
wire compare_gts_w;
|
wire compare_gt_w;
|
wire compare_gt_w;
|
wire compare_lts_w;
|
wire compare_lts_w;
|
wire compare_lt_w;
|
wire compare_lt_w;
|
|
|
// ALU operation selection
|
// ALU operation selection
|
reg [3:0] r_e_alu_func;
|
reg [3:0] ex_alu_func_q;
|
|
|
// Load instruction details
|
// Load instruction details
|
reg [4:0] r_load_rd;
|
reg [4:0] load_rd_q;
|
reg [7:0] r_load_inst;
|
reg [7:0] load_inst_q;
|
reg [1:0] r_load_offset;
|
reg [1:0] load_offset_q;
|
|
|
// Load forwarding
|
// Load forwarding
|
wire load_insn;
|
wire load_inst_w;
|
wire [31:0] load_result;
|
wire [31:0] load_result_w;
|
|
|
// Memory access?
|
// Memory access?
|
reg r_mem_load;
|
reg mem_load_q;
|
reg r_mem_store;
|
reg mem_store_q;
|
reg r_mem_access;
|
reg mem_access_q;
|
|
|
wire load_pending;
|
wire load_pending_w;
|
wire store_pending;
|
wire store_pending_w;
|
wire load_insert;
|
wire load_insert_w;
|
wire load_stall;
|
wire load_stall_w;
|
|
|
reg d_mem_load;
|
reg d_mem_load_q;
|
|
|
// Delayed NMI
|
// Delayed NMI
|
reg r_nmi;
|
reg nmi_q;
|
|
|
// SIM PUTC
|
// SIM PUTC
|
`ifdef SIM_EXT_PUTC
|
`ifdef SIM_EXT_PUTC
|
reg [7:0] r_putc;
|
reg [7:0] putc_q;
|
`endif
|
`endif
|
|
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
// Instantiation
|
|
//-----------------------------------------------------------------
|
|
|
|
// ALU
|
// ALU
|
|
//-----------------------------------------------------------------
|
altor32_alu alu
|
altor32_alu alu
|
(
|
(
|
// ALU operation select
|
// ALU operation select
|
.op_i(r_e_alu_func),
|
.op_i(ex_alu_func_q),
|
|
|
// Operands
|
// Operands
|
.a_i(r_e_alu_a),
|
.a_i(ex_alu_a_q),
|
.b_i(r_e_alu_b),
|
.b_i(ex_alu_b_q),
|
.c_i(r_sr[`OR32_SR_CY]),
|
.c_i(sr_q[`OR32_SR_CY]),
|
|
|
// Result
|
// Result
|
.p_o(r_e_result),
|
.p_o(ex_result_w),
|
|
|
// Carry
|
// Carry
|
.c_o(alu_carry_out),
|
.c_o(alu_carry_out_w),
|
.c_update_o(alu_carry_update),
|
.c_update_o(alu_carry_update_w),
|
|
|
// Comparisons
|
// Comparisons
|
.equal_o(compare_equal_w),
|
.equal_o(compare_equal_w),
|
.greater_than_signed_o(compare_gts_w),
|
.greater_than_signed_o(compare_gts_w),
|
.greater_than_o(compare_gt_w),
|
.greater_than_o(compare_gt_w),
|
.less_than_signed_o(compare_lts_w),
|
.less_than_signed_o(compare_lts_w),
|
.less_than_o(compare_lt_w),
|
.less_than_o(compare_lt_w),
|
.flag_update_o(alu_flag_update)
|
.flag_update_o(alu_flag_update_w)
|
);
|
);
|
|
|
|
//-----------------------------------------------------------------
|
// Load result forwarding
|
// Load result forwarding
|
|
//-----------------------------------------------------------------
|
altor32_lfu
|
altor32_lfu
|
u_lfu
|
u_lfu
|
(
|
(
|
// Opcode
|
// Opcode
|
.opcode_i(r_load_inst),
|
.opcode_i(load_inst_q),
|
|
|
// Memory load result
|
// Memory load result
|
.mem_result_i(dmem_data_in_i),
|
.mem_result_i(dmem_data_in_i),
|
.mem_offset_i(r_load_offset),
|
.mem_offset_i(load_offset_q),
|
|
|
// Result
|
// Result
|
.load_result_o(load_result),
|
.load_result_o(load_result_w),
|
.load_insn_o(load_insn)
|
.load_insn_o(load_inst_w)
|
);
|
);
|
|
|
|
//-----------------------------------------------------------------
|
// Load / store pending logic
|
// Load / store pending logic
|
|
//-----------------------------------------------------------------
|
altor32_lsu
|
altor32_lsu
|
u_lsu
|
u_lsu
|
(
|
(
|
// Current instruction
|
// Current instruction
|
.opcode_valid_i(opcode_valid_i & ~r_pc_fetch),
|
.opcode_valid_i(opcode_valid_i & ~pc_fetch_q),
|
.opcode_i({2'b00,opcode_i[31:26]}),
|
.opcode_i({2'b00,opcode_i[31:26]}),
|
|
|
// Load / Store pending
|
// Load / Store pending
|
.load_pending_i(r_mem_load),
|
.load_pending_i(mem_load_q),
|
.store_pending_i(r_mem_store),
|
.store_pending_i(mem_store_q),
|
|
|
// Load dest register
|
// Load dest register
|
.rd_load_i(r_load_rd),
|
.rd_load_i(load_rd_q),
|
|
|
// Load insn in WB stage
|
// Load insn in WB stage
|
.load_wb_i(d_mem_load),
|
.load_wb_i(d_mem_load_q),
|
|
|
// Memory status
|
// Memory status
|
.mem_access_i(r_mem_access),
|
.mem_access_i(mem_access_q),
|
.mem_ack_i(dmem_ack_i),
|
.mem_ack_i(dmem_ack_i),
|
|
|
// Load / store still pending
|
// Load / store still pending
|
.load_pending_o(load_pending),
|
.load_pending_o(load_pending_w),
|
.store_pending_o(store_pending),
|
.store_pending_o(store_pending_w),
|
|
|
// Insert load result into pipeline
|
// Insert load result into pipeline
|
.write_result_o(load_insert),
|
.write_result_o(load_insert_w),
|
|
|
// Stall pipeline due
|
// Stall pipeline due
|
.stall_o(load_stall)
|
.stall_o(load_stall_w)
|
);
|
);
|
|
|
|
//-----------------------------------------------------------------
|
// Operand forwarding
|
// Operand forwarding
|
|
//-----------------------------------------------------------------
|
altor32_dfu
|
altor32_dfu
|
u_dfu
|
u_dfu
|
(
|
(
|
// Input registers
|
// Input registers
|
.ra_i(reg_ra_i),
|
.ra_i(reg_ra_i),
|
Line 293... |
Line 298... |
// Input register contents
|
// Input register contents
|
.ra_regval_i(reg_ra_value_i),
|
.ra_regval_i(reg_ra_value_i),
|
.rb_regval_i(reg_rb_value_i),
|
.rb_regval_i(reg_rb_value_i),
|
|
|
// Dest register (EXEC stage)
|
// Dest register (EXEC stage)
|
.rd_ex_i(r_e_rd),
|
.rd_ex_i(ex_rd_q),
|
|
|
// Dest register (WB stage)
|
// Dest register (WB stage)
|
.rd_wb_i(wb_rd_i),
|
.rd_wb_i(wb_rd_i),
|
|
|
// Load pending / target
|
// Load pending / target
|
.load_pending_i(load_pending),
|
.load_pending_i(load_pending_w),
|
.rd_load_i(r_load_rd),
|
.rd_load_i(load_rd_q),
|
|
|
// Multiplier status
|
// Multiplier status
|
.mult_lo_ex_i(1'b0),
|
.mult_lo_ex_i(1'b0),
|
.mult_hi_ex_i(1'b0),
|
.mult_hi_ex_i(1'b0),
|
.mult_lo_wb_i(1'b0),
|
.mult_lo_wb_i(1'b0),
|
Line 312... |
Line 317... |
|
|
// Multiplier result
|
// Multiplier result
|
.result_mult_i(64'b0),
|
.result_mult_i(64'b0),
|
|
|
// Result (EXEC)
|
// Result (EXEC)
|
.result_ex_i(r_e_result),
|
.result_ex_i(ex_result_w),
|
|
|
// Result (WB)
|
// Result (WB)
|
.result_wb_i(wb_rd_value_i),
|
.result_wb_i(wb_rd_value_i),
|
|
|
// Resolved register values
|
// Resolved register values
|
.result_ra_o(ra_value_resolved),
|
.result_ra_o(ra_resolved_w),
|
.result_rb_o(rb_value_resolved),
|
.result_rb_o(rb_resolved_w),
|
|
|
// Operands required forwarding
|
// Operands required forwarding
|
.resolved_o(operand_resolved),
|
.resolved_o(operand_resolved_w),
|
|
|
// Stall due to failed resolve
|
// Stall due to failed resolve
|
.stall_o(resolve_failed)
|
.stall_o(resolve_failed_w)
|
);
|
);
|
|
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
// Opcode decode
|
// Opcode decode
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
Line 368... |
Line 373... |
uint16_r = opcode_i[15:0];
|
uint16_r = opcode_i[15:0];
|
int32_r = sign_extend_imm16(opcode_i[15:0]);
|
int32_r = sign_extend_imm16(opcode_i[15:0]);
|
uint32_r = extend_imm16(opcode_i[15:0]);
|
uint32_r = extend_imm16(opcode_i[15:0]);
|
|
|
// Register values [ra/rb]
|
// Register values [ra/rb]
|
reg_ra_r = ra_value_resolved;
|
reg_ra_r = ra_resolved_w;
|
reg_rb_r = rb_value_resolved;
|
reg_rb_r = rb_resolved_w;
|
|
|
// Shift ammount (from register[rb])
|
// Shift ammount (from register[rb])
|
shift_rb_r = {26'b00,rb_value_resolved[5:0]};
|
shift_rb_r = {26'b00,rb_resolved_w[5:0]};
|
|
|
// Shift ammount (from immediate)
|
// Shift ammount (from immediate)
|
shift_imm_r = {26'b00,opcode_i[5:0]};
|
shift_imm_r = {26'b00,opcode_i[5:0]};
|
|
|
// MTSPR/MFSPR operand
|
// MTSPR/MFSPR operand
|
Line 459... |
Line 464... |
begin
|
begin
|
execute_inst_r = 1'b1;
|
execute_inst_r = 1'b1;
|
stall_inst_r = 1'b0;
|
stall_inst_r = 1'b0;
|
|
|
// No opcode ready or branch delay slot
|
// No opcode ready or branch delay slot
|
if (~opcode_valid_i | r_pc_fetch)
|
if (~opcode_valid_i | pc_fetch_q)
|
execute_inst_r = 1'b0;
|
execute_inst_r = 1'b0;
|
// Valid instruction, but load result / operand not ready
|
// Valid instruction, but load result / operand not ready
|
else if (resolve_failed | load_stall |
|
else if (resolve_failed_w | load_stall_w |
|
(operand_resolved & (inst_mfspr_w | inst_mtspr_w)))
|
(operand_resolved_w & (inst_mfspr_w | inst_mtspr_w)))
|
stall_inst_r = 1'b1;
|
stall_inst_r = 1'b1;
|
end
|
end
|
|
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
// Next PC
|
// Next PC
|
Line 485... |
Line 490... |
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
reg [31:0] next_sr_r;
|
reg [31:0] next_sr_r;
|
reg compare_result_r;
|
reg compare_result_r;
|
always @ *
|
always @ *
|
begin
|
begin
|
next_sr_r = r_sr;
|
next_sr_r = sr_q;
|
|
|
// Update SR.F
|
// Update SR.F
|
if (alu_flag_update)
|
if (alu_flag_update_w)
|
next_sr_r[`OR32_SR_F] = compare_result_r;
|
next_sr_r[`OR32_SR_F] = compare_result_r;
|
|
|
// Latch carry if updated
|
// Latch carry if updated
|
if (alu_carry_update)
|
if (alu_carry_update_w)
|
next_sr_r[`OR32_SR_CY] = alu_carry_out;
|
next_sr_r[`OR32_SR_CY] = alu_carry_out_w;
|
|
|
// If valid instruction, check if SR needs updating
|
// If valid instruction, check if SR needs updating
|
if (execute_inst_r & ~stall_inst_r)
|
if (execute_inst_r & ~stall_inst_r)
|
begin
|
begin
|
case (1'b1)
|
case (1'b1)
|
Line 516... |
Line 521... |
default:
|
default:
|
;
|
;
|
endcase
|
endcase
|
end
|
end
|
inst_rfe_w:
|
inst_rfe_w:
|
next_sr_r = r_esr;
|
next_sr_r = esr_q;
|
default:
|
default:
|
;
|
;
|
endcase
|
endcase
|
end
|
end
|
end
|
end
|
Line 531... |
Line 536... |
reg [31:0] next_epc_r;
|
reg [31:0] next_epc_r;
|
reg [31:0] next_esr_r;
|
reg [31:0] next_esr_r;
|
|
|
always @ *
|
always @ *
|
begin
|
begin
|
next_epc_r = r_epc;
|
next_epc_r = epc_q;
|
next_esr_r = r_esr;
|
next_esr_r = esr_q;
|
|
|
case (1'b1)
|
case (1'b1)
|
inst_mtspr_w: // l.mtspr
|
inst_mtspr_w: // l.mtspr
|
begin
|
begin
|
case (mxspr_uint16_r)
|
case (mxspr_uint16_r)
|
Line 690... |
Line 695... |
end
|
end
|
|
|
// EPCR - EPC Exception saved PC
|
// EPCR - EPC Exception saved PC
|
`SPR_REG_EPCR:
|
`SPR_REG_EPCR:
|
begin
|
begin
|
alu_input_a_r = r_epc;
|
alu_input_a_r = epc_q;
|
write_rd_r = 1'b1;
|
write_rd_r = 1'b1;
|
end
|
end
|
|
|
// ESR - Exception saved SR
|
// ESR - Exception saved SR
|
`SPR_REG_ESR:
|
`SPR_REG_ESR:
|
begin
|
begin
|
alu_input_a_r = r_esr;
|
alu_input_a_r = esr_q;
|
write_rd_r = 1'b1;
|
write_rd_r = 1'b1;
|
end
|
end
|
default:
|
default:
|
;
|
;
|
endcase
|
endcase
|
Line 983... |
Line 988... |
end
|
end
|
|
|
inst_rfe_w: // l.rfe
|
inst_rfe_w: // l.rfe
|
begin
|
begin
|
branch_r = 1'b1;
|
branch_r = 1'b1;
|
branch_target_r = r_epc;
|
branch_target_r = epc_q;
|
end
|
end
|
|
|
inst_sys_w: // l.sys
|
inst_sys_w: // l.sys
|
begin
|
begin
|
branch_r = 1'b1;
|
branch_r = 1'b1;
|
Line 1074... |
Line 1079... |
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
always @ (posedge clk_i or posedge rst_i)
|
always @ (posedge clk_i or posedge rst_i)
|
begin
|
begin
|
if (rst_i == 1'b1)
|
if (rst_i == 1'b1)
|
begin
|
begin
|
r_e_alu_func <= `ALU_NONE;
|
ex_alu_func_q <= `ALU_NONE;
|
r_e_alu_a <= 32'h00000000;
|
ex_alu_a_q <= 32'h00000000;
|
r_e_alu_b <= 32'h00000000;
|
ex_alu_b_q <= 32'h00000000;
|
r_e_rd <= 5'b00000;
|
ex_rd_q <= 5'b00000;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
// Instruction not ready
|
// Instruction not ready
|
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
if (~execute_inst_r | stall_inst_r)
|
if (~execute_inst_r | stall_inst_r)
|
begin
|
begin
|
// Insert load result?
|
// Insert load result?
|
if (load_insert)
|
if (load_insert_w)
|
begin
|
begin
|
// Feed load result into pipeline
|
// Feed load result into pipeline
|
r_e_alu_func <= `ALU_NONE;
|
ex_alu_func_q <= `ALU_NONE;
|
r_e_alu_a <= load_result;
|
ex_alu_a_q <= load_result_w;
|
r_e_alu_b <= 32'b0;
|
ex_alu_b_q <= 32'b0;
|
r_e_rd <= r_load_rd;
|
ex_rd_q <= load_rd_q;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
// No ALU operation (output == input_a)
|
// No ALU operation (output == input_a)
|
r_e_alu_func <= `ALU_NONE;
|
ex_alu_func_q <= `ALU_NONE;
|
r_e_alu_a <= 32'b0;
|
ex_alu_a_q <= 32'b0;
|
r_e_alu_b <= 32'b0;
|
ex_alu_b_q <= 32'b0;
|
r_e_rd <= 5'b0;
|
ex_rd_q <= 5'b0;
|
end
|
end
|
end
|
end
|
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
// Valid instruction
|
// Valid instruction
|
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
else
|
else
|
begin
|
begin
|
// Update ALU input flops
|
// Update ALU input flops
|
r_e_alu_func <= alu_func_r;
|
ex_alu_func_q <= alu_func_r;
|
r_e_alu_a <= alu_input_a_r;
|
ex_alu_a_q <= alu_input_a_r;
|
r_e_alu_b <= alu_input_b_r;
|
ex_alu_b_q <= alu_input_b_r;
|
|
|
// Branch and link (Rd = LR/R9)
|
// Branch and link (Rd = LR/R9)
|
if (branch_link_r)
|
if (branch_link_r)
|
r_e_rd <= 5'd9;
|
ex_rd_q <= 5'd9;
|
// Instruction with register writeback
|
// Instruction with register writeback
|
else if (write_rd_r)
|
else if (write_rd_r)
|
r_e_rd <= reg_rd_i;
|
ex_rd_q <= reg_rd_i;
|
else
|
else
|
r_e_rd <= 5'b0;
|
ex_rd_q <= 5'b0;
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
Line 1133... |
Line 1138... |
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
always @ (posedge clk_i or posedge rst_i)
|
always @ (posedge clk_i or posedge rst_i)
|
begin
|
begin
|
if (rst_i == 1'b1)
|
if (rst_i == 1'b1)
|
begin
|
begin
|
r_e_opcode <= 32'h00000000;
|
ex_opcode_q <= 32'h00000000;
|
r_e_opcode_pc <= 32'h00000000;
|
ex_opcode_pc_q <= 32'h00000000;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
// Instruction not ready
|
// Instruction not ready
|
if (~execute_inst_r | stall_inst_r)
|
if (~execute_inst_r | stall_inst_r)
|
begin
|
begin
|
// Store bubble opcode
|
// Store bubble opcode
|
r_e_opcode <= `OPCODE_INST_BUBBLE;
|
ex_opcode_q <= `OPCODE_INST_BUBBLE;
|
r_e_opcode_pc <= opcode_pc_i;
|
ex_opcode_pc_q <= opcode_pc_i;
|
end
|
end
|
// Valid instruction
|
// Valid instruction
|
else
|
else
|
begin
|
begin
|
// Store opcode
|
// Store opcode
|
r_e_opcode <= opcode_i;
|
ex_opcode_q <= opcode_i;
|
r_e_opcode_pc <= opcode_pc_i;
|
ex_opcode_pc_q <= opcode_pc_i;
|
|
|
`ifdef CONF_CORE_TRACE
|
`ifdef CONF_CORE_TRACE
|
$display("%08x: Execute 0x%08x", opcode_pc_i, opcode_i);
|
$display("%08x: Execute 0x%08x", opcode_pc_i, opcode_i);
|
$display(" rA[%d] = 0x%08x", reg_ra_i, reg_ra_r);
|
$display(" rA[%d] = 0x%08x", reg_ra_i, reg_ra_r);
|
$display(" rB[%d] = 0x%08x", reg_rb_i, reg_rb_r);
|
$display(" rB[%d] = 0x%08x", reg_rb_i, reg_rb_r);
|
Line 1168... |
Line 1173... |
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
always @ (posedge clk_i or posedge rst_i)
|
always @ (posedge clk_i or posedge rst_i)
|
begin
|
begin
|
if (rst_i == 1'b1)
|
if (rst_i == 1'b1)
|
begin
|
begin
|
r_pc_branch <= 32'h00000000;
|
pc_branch_q <= 32'h00000000;
|
r_pc_fetch <= 1'b0;
|
pc_fetch_q <= 1'b0;
|
|
|
// Status registers
|
// Status registers
|
r_epc <= 32'h00000000;
|
epc_q <= 32'h00000000;
|
r_sr <= 32'h00000000;
|
sr_q <= 32'h00000000;
|
r_esr <= 32'h00000000;
|
esr_q <= 32'h00000000;
|
|
|
fault_o <= 1'b0;
|
fault_o <= 1'b0;
|
|
|
r_nmi <= 1'b0;
|
nmi_q <= 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
// Record NMI in-case it can't be processed this cycle
|
// Record NMI in-case it can't be processed this cycle
|
if (nmi_i)
|
if (nmi_i)
|
r_nmi <= 1'b1;
|
nmi_q <= 1'b1;
|
|
|
// Reset branch request
|
// Reset branch request
|
r_pc_fetch <= 1'b0;
|
pc_fetch_q <= 1'b0;
|
|
|
// Update SR
|
// Update SR
|
r_sr <= next_sr_r;
|
sr_q <= next_sr_r;
|
|
|
// Instruction ready
|
// Instruction ready
|
if (execute_inst_r & ~stall_inst_r)
|
if (execute_inst_r & ~stall_inst_r)
|
begin
|
begin
|
// Exception: Instruction opcode not valid / supported, invalid PC
|
// Exception: Instruction opcode not valid / supported, invalid PC
|
if (invalid_inst_r || (opcode_pc_i[1:0] != 2'b00))
|
if (invalid_inst_r || (opcode_pc_i[1:0] != 2'b00))
|
begin
|
begin
|
// Save PC of next instruction
|
// Save PC of next instruction
|
r_epc <= next_pc_r;
|
epc_q <= next_pc_r;
|
r_esr <= next_sr_r;
|
esr_q <= next_sr_r;
|
|
|
// Disable further interrupts
|
// Disable further interrupts
|
r_sr <= 32'b0;
|
sr_q <= 32'b0;
|
|
|
// Set PC to exception vector
|
// Set PC to exception vector
|
if (invalid_inst_r)
|
if (invalid_inst_r)
|
r_pc_branch <= ISR_VECTOR + `VECTOR_ILLEGAL_INST;
|
pc_branch_q <= ISR_VECTOR + `VECTOR_ILLEGAL_INST;
|
else
|
else
|
r_pc_branch <= ISR_VECTOR + `VECTOR_BUS_ERROR;
|
pc_branch_q <= ISR_VECTOR + `VECTOR_BUS_ERROR;
|
r_pc_fetch <= 1'b1;
|
pc_fetch_q <= 1'b1;
|
|
|
fault_o <= 1'b1;
|
fault_o <= 1'b1;
|
end
|
end
|
// Exception: Syscall / Break
|
// Exception: Syscall / Break
|
else if (branch_except_r)
|
else if (branch_except_r)
|
begin
|
begin
|
// Save PC of next instruction
|
// Save PC of next instruction
|
r_epc <= next_pc_r;
|
epc_q <= next_pc_r;
|
r_esr <= next_sr_r;
|
esr_q <= next_sr_r;
|
|
|
// Disable further interrupts
|
// Disable further interrupts
|
r_sr <= 32'b0;
|
sr_q <= 32'b0;
|
|
|
// Set PC to exception vector
|
// Set PC to exception vector
|
r_pc_branch <= branch_target_r;
|
pc_branch_q <= branch_target_r;
|
r_pc_fetch <= 1'b1;
|
pc_fetch_q <= 1'b1;
|
|
|
`ifdef CONF_CORE_DEBUG
|
`ifdef CONF_CORE_DEBUG
|
$display(" Exception 0x%08x", branch_target_r);
|
$display(" Exception 0x%08x", branch_target_r);
|
`endif
|
`endif
|
end
|
end
|
// Non-maskable interrupt
|
// Non-maskable interrupt
|
else if (nmi_i | r_nmi)
|
else if (nmi_i | nmi_q)
|
begin
|
begin
|
r_nmi <= 1'b0;
|
nmi_q <= 1'b0;
|
|
|
// Save PC of next instruction
|
// Save PC of next instruction
|
if (branch_r)
|
if (branch_r)
|
r_epc <= branch_target_r;
|
epc_q <= branch_target_r;
|
// Next expected PC (current PC + 4)
|
// Next expected PC (current PC + 4)
|
else
|
else
|
r_epc <= next_pc_r;
|
epc_q <= next_pc_r;
|
|
|
r_esr <= next_sr_r;
|
esr_q <= next_sr_r;
|
|
|
// Disable further interrupts
|
// Disable further interrupts
|
r_sr <= 32'b0;
|
sr_q <= 32'b0;
|
|
|
// Set PC to exception vector
|
// Set PC to exception vector
|
r_pc_branch <= ISR_VECTOR + `VECTOR_NMI;
|
pc_branch_q <= ISR_VECTOR + `VECTOR_NMI;
|
r_pc_fetch <= 1'b1;
|
pc_fetch_q <= 1'b1;
|
|
|
`ifdef CONF_CORE_DEBUG
|
`ifdef CONF_CORE_DEBUG
|
$display(" NMI 0x%08x", ISR_VECTOR + `VECTOR_NMI);
|
$display(" NMI 0x%08x", ISR_VECTOR + `VECTOR_NMI);
|
`endif
|
`endif
|
end
|
end
|
// External interrupt
|
// External interrupt
|
else if (intr_i && next_sr_r[`OR32_SR_IEE])
|
else if (intr_i && next_sr_r[`OR32_SR_IEE])
|
begin
|
begin
|
// Save PC of next instruction & SR
|
// Save PC of next instruction & SR
|
if (branch_r)
|
if (branch_r)
|
r_epc <= branch_target_r;
|
epc_q <= branch_target_r;
|
// Next expected PC (current PC + 4)
|
// Next expected PC (current PC + 4)
|
else
|
else
|
r_epc <= next_pc_r;
|
epc_q <= next_pc_r;
|
|
|
r_esr <= next_sr_r;
|
esr_q <= next_sr_r;
|
|
|
// Disable further interrupts
|
// Disable further interrupts
|
r_sr <= 32'b0;
|
sr_q <= 32'b0;
|
|
|
// Set PC to external interrupt vector
|
// Set PC to external interrupt vector
|
r_pc_branch <= ISR_VECTOR + `VECTOR_EXTINT;
|
pc_branch_q <= ISR_VECTOR + `VECTOR_EXTINT;
|
r_pc_fetch <= 1'b1;
|
pc_fetch_q <= 1'b1;
|
|
|
`ifdef CONF_CORE_DEBUG
|
`ifdef CONF_CORE_DEBUG
|
$display(" External Interrupt 0x%08x", ISR_VECTOR + `VECTOR_EXTINT);
|
$display(" External Interrupt 0x%08x", ISR_VECTOR + `VECTOR_EXTINT);
|
`endif
|
`endif
|
end
|
end
|
// Branch (l.bf, l.bnf, l.j, l.jal, l.jr, l.jalr, l.rfe)
|
// Branch (l.bf, l.bnf, l.j, l.jal, l.jr, l.jalr, l.rfe)
|
else if (branch_r)
|
else if (branch_r)
|
begin
|
begin
|
// Perform branch
|
// Perform branch
|
r_pc_branch <= branch_target_r;
|
pc_branch_q <= branch_target_r;
|
r_pc_fetch <= 1'b1;
|
pc_fetch_q <= 1'b1;
|
|
|
`ifdef CONF_CORE_DEBUG
|
`ifdef CONF_CORE_DEBUG
|
$display(" Branch to 0x%08x", branch_target_r);
|
$display(" Branch to 0x%08x", branch_target_r);
|
`endif
|
`endif
|
end
|
end
|
// Non branch
|
// Non branch
|
else
|
else
|
begin
|
begin
|
// Update EPC / ESR which may have been updated
|
// Update EPC / ESR which may have been updated
|
// by an MTSPR write
|
// by an MTSPR write
|
r_epc <= next_epc_r;
|
epc_q <= next_epc_r;
|
r_esr <= next_esr_r;
|
esr_q <= next_esr_r;
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
Line 1318... |
Line 1323... |
dmem_we_o <= 1'b0;
|
dmem_we_o <= 1'b0;
|
dmem_sel_o <= 4'b0000;
|
dmem_sel_o <= 4'b0000;
|
dmem_stb_o <= 1'b0;
|
dmem_stb_o <= 1'b0;
|
dmem_cyc_o <= 1'b0;
|
dmem_cyc_o <= 1'b0;
|
|
|
r_mem_load <= 1'b0;
|
mem_load_q <= 1'b0;
|
r_mem_store <= 1'b0;
|
mem_store_q <= 1'b0;
|
r_mem_access <= 1'b0;
|
mem_access_q <= 1'b0;
|
|
|
r_load_rd <= 5'b00000;
|
load_rd_q <= 5'b00000;
|
r_load_inst <= 8'h00;
|
load_inst_q <= 8'h00;
|
r_load_offset <= 2'b00;
|
load_offset_q <= 2'b00;
|
|
|
d_mem_load <= 1'b0;
|
d_mem_load_q <= 1'b0;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
|
|
// If memory access accepted by slave
|
// If memory access accepted by slave
|
Line 1338... |
Line 1343... |
dmem_stb_o <= 1'b0;
|
dmem_stb_o <= 1'b0;
|
|
|
if (dmem_ack_i)
|
if (dmem_ack_i)
|
dmem_cyc_o <= 1'b0;
|
dmem_cyc_o <= 1'b0;
|
|
|
r_mem_access <= 1'b0;
|
mem_access_q <= 1'b0;
|
d_mem_load <= r_mem_access & r_mem_load;
|
d_mem_load_q <= mem_access_q & mem_load_q;
|
|
|
// Pending accesses
|
// Pending accesses
|
r_mem_load <= load_pending;
|
mem_load_q <= load_pending_w;
|
r_mem_store <= store_pending;
|
mem_store_q <= store_pending_w;
|
|
|
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
// Valid instruction
|
// Valid instruction
|
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
if (execute_inst_r & ~stall_inst_r)
|
if (execute_inst_r & ~stall_inst_r)
|
Line 1355... |
Line 1360... |
// Branch and link (Rd = LR/R9)
|
// Branch and link (Rd = LR/R9)
|
if (branch_link_r)
|
if (branch_link_r)
|
begin
|
begin
|
// Load outstanding, check if result target is being
|
// Load outstanding, check if result target is being
|
// overwritten (to avoid WAR hazard)
|
// overwritten (to avoid WAR hazard)
|
if (r_load_rd == 5'd9)
|
if (load_rd_q == 5'd9)
|
// Ditch load result when it arrives
|
// Ditch load result when it arrives
|
r_load_rd <= 5'b00000;
|
load_rd_q <= 5'b00000;
|
end
|
end
|
// Instruction with register writeback
|
// Instruction with register writeback
|
else if (write_rd_r)
|
else if (write_rd_r)
|
begin
|
begin
|
// Load outstanding, check if result target is being
|
// Load outstanding, check if result target is being
|
// overwritten (to avoid WAR hazard)
|
// overwritten (to avoid WAR hazard)
|
if (reg_rd_i == r_load_rd && ~load_inst_r)
|
if (reg_rd_i == load_rd_q && ~load_inst_r)
|
// Ditch load result when it arrives
|
// Ditch load result when it arrives
|
r_load_rd <= 5'b00000;
|
load_rd_q <= 5'b00000;
|
end
|
end
|
|
|
case (1'b1)
|
case (1'b1)
|
|
|
// l.lbs l.lhs l.lws l.lbz l.lhz l.lwz
|
// l.lbs l.lhs l.lws l.lbz l.lhz l.lwz
|
Line 1382... |
Line 1387... |
dmem_we_o <= 1'b0;
|
dmem_we_o <= 1'b0;
|
dmem_stb_o <= 1'b1;
|
dmem_stb_o <= 1'b1;
|
dmem_cyc_o <= 1'b1;
|
dmem_cyc_o <= 1'b1;
|
|
|
// Mark load as pending
|
// Mark load as pending
|
r_mem_load <= 1'b1;
|
mem_load_q <= 1'b1;
|
r_mem_access <= 1'b1;
|
mem_access_q <= 1'b1;
|
|
|
// Record target register
|
// Record target register
|
r_load_rd <= reg_rd_i;
|
load_rd_q <= reg_rd_i;
|
r_load_inst <= inst_r;
|
load_inst_q <= inst_r;
|
r_load_offset <= mem_addr_r[1:0];
|
load_offset_q <= mem_addr_r[1:0];
|
|
|
`ifdef CONF_CORE_DEBUG
|
`ifdef CONF_CORE_DEBUG
|
$display(" Load from 0x%08x to R%d", mem_addr_r, reg_rd_i);
|
$display(" Load from 0x%08x to R%d", mem_addr_r, reg_rd_i);
|
`endif
|
`endif
|
end
|
end
|
|
|
inst_sb_w: // l.sb
|
inst_sb_w: // l.sb
|
begin
|
begin
|
dmem_addr_o <= mem_addr_r;
|
dmem_addr_o <= mem_addr_r;
|
r_mem_access <= 1'b1;
|
mem_access_q <= 1'b1;
|
case (mem_addr_r[1:0])
|
case (mem_addr_r[1:0])
|
2'b00 :
|
2'b00 :
|
begin
|
begin
|
dmem_data_out_o <= {reg_rb_r[7:0],24'h000000};
|
dmem_data_out_o <= {reg_rb_r[7:0],24'h000000};
|
dmem_sel_o <= 4'b1000;
|
dmem_sel_o <= 4'b1000;
|
dmem_we_o <= 1'b1;
|
dmem_we_o <= 1'b1;
|
dmem_stb_o <= 1'b1;
|
dmem_stb_o <= 1'b1;
|
dmem_cyc_o <= 1'b1;
|
dmem_cyc_o <= 1'b1;
|
r_mem_store <= 1'b1;
|
mem_store_q <= 1'b1;
|
end
|
end
|
2'b01 :
|
2'b01 :
|
begin
|
begin
|
dmem_data_out_o <= {{8'h00,reg_rb_r[7:0]},16'h0000};
|
dmem_data_out_o <= {{8'h00,reg_rb_r[7:0]},16'h0000};
|
dmem_sel_o <= 4'b0100;
|
dmem_sel_o <= 4'b0100;
|
dmem_we_o <= 1'b1;
|
dmem_we_o <= 1'b1;
|
dmem_stb_o <= 1'b1;
|
dmem_stb_o <= 1'b1;
|
dmem_cyc_o <= 1'b1;
|
dmem_cyc_o <= 1'b1;
|
r_mem_store <= 1'b1;
|
mem_store_q <= 1'b1;
|
end
|
end
|
2'b10 :
|
2'b10 :
|
begin
|
begin
|
dmem_data_out_o <= {{16'h0000,reg_rb_r[7:0]},8'h00};
|
dmem_data_out_o <= {{16'h0000,reg_rb_r[7:0]},8'h00};
|
dmem_sel_o <= 4'b0010;
|
dmem_sel_o <= 4'b0010;
|
dmem_we_o <= 1'b1;
|
dmem_we_o <= 1'b1;
|
dmem_stb_o <= 1'b1;
|
dmem_stb_o <= 1'b1;
|
dmem_cyc_o <= 1'b1;
|
dmem_cyc_o <= 1'b1;
|
r_mem_store <= 1'b1;
|
mem_store_q <= 1'b1;
|
end
|
end
|
2'b11 :
|
2'b11 :
|
begin
|
begin
|
dmem_data_out_o <= {24'h000000,reg_rb_r[7:0]};
|
dmem_data_out_o <= {24'h000000,reg_rb_r[7:0]};
|
dmem_sel_o <= 4'b0001;
|
dmem_sel_o <= 4'b0001;
|
dmem_we_o <= 1'b1;
|
dmem_we_o <= 1'b1;
|
dmem_stb_o <= 1'b1;
|
dmem_stb_o <= 1'b1;
|
dmem_cyc_o <= 1'b1;
|
dmem_cyc_o <= 1'b1;
|
r_mem_store <= 1'b1;
|
mem_store_q <= 1'b1;
|
end
|
end
|
default :
|
default :
|
;
|
;
|
endcase
|
endcase
|
end
|
end
|
|
|
inst_sh_w: // l.sh
|
inst_sh_w: // l.sh
|
begin
|
begin
|
dmem_addr_o <= mem_addr_r;
|
dmem_addr_o <= mem_addr_r;
|
r_mem_access <= 1'b1;
|
mem_access_q <= 1'b1;
|
case (mem_addr_r[1:0])
|
case (mem_addr_r[1:0])
|
2'b00 :
|
2'b00 :
|
begin
|
begin
|
dmem_data_out_o <= {reg_rb_r[15:0],16'h0000};
|
dmem_data_out_o <= {reg_rb_r[15:0],16'h0000};
|
dmem_sel_o <= 4'b1100;
|
dmem_sel_o <= 4'b1100;
|
dmem_we_o <= 1'b1;
|
dmem_we_o <= 1'b1;
|
dmem_stb_o <= 1'b1;
|
dmem_stb_o <= 1'b1;
|
dmem_cyc_o <= 1'b1;
|
dmem_cyc_o <= 1'b1;
|
r_mem_store <= 1'b1;
|
mem_store_q <= 1'b1;
|
end
|
end
|
2'b10 :
|
2'b10 :
|
begin
|
begin
|
dmem_data_out_o <= {16'h0000,reg_rb_r[15:0]};
|
dmem_data_out_o <= {16'h0000,reg_rb_r[15:0]};
|
dmem_sel_o <= 4'b0011;
|
dmem_sel_o <= 4'b0011;
|
dmem_we_o <= 1'b1;
|
dmem_we_o <= 1'b1;
|
dmem_stb_o <= 1'b1;
|
dmem_stb_o <= 1'b1;
|
dmem_cyc_o <= 1'b1;
|
dmem_cyc_o <= 1'b1;
|
r_mem_store <= 1'b1;
|
mem_store_q <= 1'b1;
|
end
|
end
|
default :
|
default :
|
;
|
;
|
endcase
|
endcase
|
end
|
end
|
Line 1477... |
Line 1482... |
dmem_data_out_o <= reg_rb_r;
|
dmem_data_out_o <= reg_rb_r;
|
dmem_sel_o <= 4'b1111;
|
dmem_sel_o <= 4'b1111;
|
dmem_we_o <= 1'b1;
|
dmem_we_o <= 1'b1;
|
dmem_stb_o <= 1'b1;
|
dmem_stb_o <= 1'b1;
|
dmem_cyc_o <= 1'b1;
|
dmem_cyc_o <= 1'b1;
|
r_mem_access <= 1'b1;
|
mem_access_q <= 1'b1;
|
r_mem_store <= 1'b1;
|
mem_store_q <= 1'b1;
|
|
|
`ifdef CONF_CORE_DEBUG
|
`ifdef CONF_CORE_DEBUG
|
$display(" Store R%d to 0x%08x = 0x%08x", reg_rb_i, {mem_addr_r[31:2],2'b00}, reg_rb_r);
|
$display(" Store R%d to 0x%08x = 0x%08x", reg_rb_i, {mem_addr_r[31:2],2'b00}, reg_rb_r);
|
`endif
|
`endif
|
end
|
end
|
Line 1545... |
Line 1550... |
always @ (posedge clk_i or posedge rst_i)
|
always @ (posedge clk_i or posedge rst_i)
|
begin
|
begin
|
if (rst_i == 1'b1)
|
if (rst_i == 1'b1)
|
begin
|
begin
|
`ifdef SIM_EXT_PUTC
|
`ifdef SIM_EXT_PUTC
|
r_putc <= 8'b0;
|
putc_q <= 8'b0;
|
`endif
|
`endif
|
end
|
end
|
else
|
else
|
begin
|
begin
|
`ifdef SIM_EXT_PUTC
|
`ifdef SIM_EXT_PUTC
|
r_putc <= 8'b0;
|
putc_q <= 8'b0;
|
`endif
|
`endif
|
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
// Valid instruction
|
// Valid instruction
|
//---------------------------------------------------------------
|
//---------------------------------------------------------------
|
if (execute_inst_r & ~stall_inst_r)
|
if (execute_inst_r & ~stall_inst_r)
|
Line 1567... |
Line 1572... |
case (uint16_r)
|
case (uint16_r)
|
// NOP_PUTC
|
// NOP_PUTC
|
16'h0004:
|
16'h0004:
|
begin
|
begin
|
`ifdef SIM_EXT_PUTC
|
`ifdef SIM_EXT_PUTC
|
r_putc <= reg_ra_r[7:0];
|
putc_q <= reg_ra_r[7:0];
|
`else
|
`else
|
$write("%c", reg_ra_r[7:0]);
|
$write("%c", reg_ra_r[7:0]);
|
`endif
|
`endif
|
end
|
end
|
// NOP
|
// NOP
|
Line 1588... |
Line 1593... |
|
|
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
// Assignments
|
// Assignments
|
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
|
|
assign branch_pc_o = r_pc_branch;
|
assign branch_pc_o = pc_branch_q;
|
assign branch_o = r_pc_fetch;
|
assign branch_o = pc_fetch_q;
|
assign stall_o = stall_inst_r;
|
assign stall_o = stall_inst_r;
|
|
|
assign opcode_o = r_e_opcode;
|
assign opcode_o = ex_opcode_q;
|
|
assign opcode_pc_o = ex_opcode_pc_q;
|
|
|
assign reg_rd_o = r_e_rd;
|
assign reg_rd_o = ex_rd_q;
|
assign reg_rd_value_o = r_e_result;
|
assign reg_rd_value_o = ex_result_w;
|
|
|
assign mult_o = 1'b0;
|
assign mult_o = 1'b0;
|
assign mult_res_o = 32'b0;
|
assign mult_res_o = 32'b0;
|
|
|
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
// Hooks for debug
|
// Hooks for debug
|
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
`ifdef verilator
|
`ifdef verilator
|
function [31:0] get_opcode_ex;
|
function [31:0] get_opcode_ex;
|
// verilator public
|
// verilator public
|
get_opcode_ex = r_e_opcode;
|
get_opcode_ex = ex_opcode_q;
|
endfunction
|
endfunction
|
function [31:0] get_pc_ex;
|
function [31:0] get_pc_ex;
|
// verilator public
|
// verilator public
|
get_pc_ex = r_e_opcode_pc;
|
get_pc_ex = ex_opcode_pc_q;
|
endfunction
|
endfunction
|
function [7:0] get_putc;
|
function [7:0] get_putc;
|
// verilator public
|
// verilator public
|
`ifdef SIM_EXT_PUTC
|
`ifdef SIM_EXT_PUTC
|
get_putc = r_putc;
|
get_putc = putc_q;
|
`else
|
`else
|
get_putc = 8'b0;
|
get_putc = 8'b0;
|
`endif
|
`endif
|
endfunction
|
endfunction
|
function [0:0] get_reg_valid;
|
function [0:0] get_reg_valid;
|
// verilator public
|
// verilator public
|
get_reg_valid = ~(resolve_failed | load_stall | ~opcode_valid_i);
|
get_reg_valid = ~(resolve_failed_w | load_stall_w | ~opcode_valid_i);
|
endfunction
|
endfunction
|
function [4:0] get_reg_ra;
|
function [4:0] get_reg_ra;
|
// verilator public
|
// verilator public
|
get_reg_ra = reg_ra_i;
|
get_reg_ra = reg_ra_i;
|
endfunction
|
endfunction
|
function [31:0] get_reg_ra_value;
|
function [31:0] get_reg_ra_value;
|
// verilator public
|
// verilator public
|
get_reg_ra_value = ra_value_resolved;
|
get_reg_ra_value = ra_resolved_w;
|
endfunction
|
endfunction
|
function [4:0] get_reg_rb;
|
function [4:0] get_reg_rb;
|
// verilator public
|
// verilator public
|
get_reg_rb = reg_rb_i;
|
get_reg_rb = reg_rb_i;
|
endfunction
|
endfunction
|
function [31:0] get_reg_rb_value;
|
function [31:0] get_reg_rb_value;
|
// verilator public
|
// verilator public
|
get_reg_rb_value = rb_value_resolved;
|
get_reg_rb_value = rb_resolved_w;
|
endfunction
|
endfunction
|
`endif
|
`endif
|
|
|
endmodule
|
endmodule
|
|
|
No newline at end of file
|
No newline at end of file
|