Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
2b7bddbb0This file is pinned to the selected release. Download the original to open it in your design tool.
`default_nettype none
module serv_ctrl
#(parameter RESET_STRATEGY = "MINI",
parameter RESET_PC = 32'd0,
parameter WITH_CSR = 1)
(
input wire clk,
input wire i_rst,
//State
input wire i_pc_en,
input wire i_cnt12to31,
input wire i_cnt0,
input wire i_cnt2,
//Control
input wire i_jump,
input wire i_jal_or_jalr,
input wire i_utype,
input wire i_pc_rel,
input wire i_trap,
//Data
input wire i_imm,
input wire i_buf,
input wire i_csr_pc,
output wire o_rd,
output wire o_bad_pc,
//External
output reg [31:0] o_ibus_adr);
wire pc_plus_4;
wire pc_plus_4_cy;
reg pc_plus_4_cy_r;
wire pc_plus_offset;
wire pc_plus_offset_cy;
reg pc_plus_offset_cy_r;
wire pc_plus_offset_aligned;
wire plus_4;
wire pc = o_ibus_adr[0];
wire new_pc;
wire offset_a;
wire offset_b;
assign plus_4 = i_cnt2;
assign o_bad_pc = pc_plus_offset_aligned;
assign {pc_plus_4_cy,pc_plus_4} = pc+plus_4+pc_plus_4_cy_r;
generate
if (WITH_CSR)
assign new_pc = i_trap ? (i_csr_pc & !i_cnt0) : i_jump ? pc_plus_offset_aligned : pc_plus_4;
else
assign new_pc = i_jump ? pc_plus_offset_aligned : pc_plus_4;
endgenerate
assign o_rd = (i_utype & pc_plus_offset_aligned) | (pc_plus_4 & i_jal_or_jalr);
assign offset_a = i_pc_rel & pc;
assign offset_b = i_utype ? (i_imm & i_cnt12to31): i_buf;
assign {pc_plus_offset_cy,pc_plus_offset} = offset_a+offset_b+pc_plus_offset_cy_r;
assign pc_plus_offset_aligned = pc_plus_offset & !i_cnt0;
initial if (RESET_STRATEGY == "NONE") o_ibus_adr = RESET_PC;
always @(posedge clk) begin
pc_plus_4_cy_r <= i_pc_en & pc_plus_4_cy;
pc_plus_offset_cy_r <= i_pc_en & pc_plus_offset_cy;
if (RESET_STRATEGY == "NONE") begin
if (i_pc_en)
o_ibus_adr <= {new_pc, o_ibus_adr[31:1]};
end else begin
if (i_pc_en | i_rst)
o_ibus_adr <= i_rst ? RESET_PC : {new_pc, o_ibus_adr[31:1]};
end
end
endmodule