mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-12-27 21:41:55 +01:00
96 lines
3.0 KiB
Verilog
Vendored
96 lines
3.0 KiB
Verilog
Vendored
`default_nettype none
|
|
module serv_immdec
|
|
#(parameter SHARED_RFADDR_IMM_REGS = 1)
|
|
(
|
|
input wire i_clk,
|
|
//State
|
|
input wire i_cnt_en,
|
|
input wire i_cnt_done,
|
|
//Control
|
|
input wire [3:0] i_immdec_en,
|
|
input wire i_csr_imm_en,
|
|
input wire [3:0] i_ctrl,
|
|
output wire [4:0] o_rd_addr,
|
|
output wire [4:0] o_rs1_addr,
|
|
output wire [4:0] o_rs2_addr,
|
|
//Data
|
|
output wire o_csr_imm,
|
|
output wire o_imm,
|
|
//External
|
|
input wire i_wb_en,
|
|
input wire [31:7] i_wb_rdt);
|
|
|
|
reg imm31;
|
|
|
|
reg [8:0] imm19_12_20;
|
|
reg imm7;
|
|
reg [5:0] imm30_25;
|
|
reg [4:0] imm24_20;
|
|
reg [4:0] imm11_7;
|
|
|
|
assign o_csr_imm = imm19_12_20[4];
|
|
|
|
wire signbit = imm31 & !i_csr_imm_en;
|
|
|
|
generate
|
|
if (SHARED_RFADDR_IMM_REGS) begin : gen_shared_imm_regs
|
|
assign o_rs1_addr = imm19_12_20[8:4];
|
|
assign o_rs2_addr = imm24_20;
|
|
assign o_rd_addr = imm11_7;
|
|
|
|
always @(posedge i_clk) begin
|
|
if (i_wb_en) begin
|
|
/* CSR immediates are always zero-extended, hence clear the signbit */
|
|
imm31 <= i_wb_rdt[31];
|
|
end
|
|
if (i_wb_en | (i_cnt_en & i_immdec_en[1]))
|
|
imm19_12_20 <= i_wb_en ? {i_wb_rdt[19:12],i_wb_rdt[20]} : {i_ctrl[3] ? signbit : imm24_20[0], imm19_12_20[8:1]};
|
|
if (i_wb_en | (i_cnt_en))
|
|
imm7 <= i_wb_en ? i_wb_rdt[7] : signbit;
|
|
|
|
if (i_wb_en | (i_cnt_en & i_immdec_en[3]))
|
|
imm30_25 <= i_wb_en ? i_wb_rdt[30:25] : {i_ctrl[2] ? imm7 : i_ctrl[1] ? signbit : imm19_12_20[0], imm30_25[5:1]};
|
|
|
|
if (i_wb_en | (i_cnt_en & i_immdec_en[2]))
|
|
imm24_20 <= i_wb_en ? i_wb_rdt[24:20] : {imm30_25[0], imm24_20[4:1]};
|
|
|
|
if (i_wb_en | (i_cnt_en & i_immdec_en[0]))
|
|
imm11_7 <= i_wb_en ? i_wb_rdt[11:7] : {imm30_25[0], imm11_7[4:1]};
|
|
end
|
|
end else begin : gen_separate_imm_regs
|
|
reg [4:0] rd_addr;
|
|
reg [4:0] rs1_addr;
|
|
reg [4:0] rs2_addr;
|
|
|
|
assign o_rd_addr = rd_addr;
|
|
assign o_rs1_addr = rs1_addr;
|
|
assign o_rs2_addr = rs2_addr;
|
|
always @(posedge i_clk) begin
|
|
if (i_wb_en) begin
|
|
/* CSR immediates are always zero-extended, hence clear the signbit */
|
|
imm31 <= i_wb_rdt[31];
|
|
imm19_12_20 <= {i_wb_rdt[19:12],i_wb_rdt[20]};
|
|
imm7 <= i_wb_rdt[7];
|
|
imm30_25 <= i_wb_rdt[30:25];
|
|
imm24_20 <= i_wb_rdt[24:20];
|
|
imm11_7 <= i_wb_rdt[11:7];
|
|
|
|
rd_addr <= i_wb_rdt[11:7];
|
|
rs1_addr <= i_wb_rdt[19:15];
|
|
rs2_addr <= i_wb_rdt[24:20];
|
|
end
|
|
if (i_cnt_en) begin
|
|
imm19_12_20 <= {i_ctrl[3] ? signbit : imm24_20[0], imm19_12_20[8:1]};
|
|
imm7 <= signbit;
|
|
imm30_25 <= {i_ctrl[2] ? imm7 : i_ctrl[1] ? signbit : imm19_12_20[0], imm30_25[5:1]};
|
|
imm24_20 <= {imm30_25[0], imm24_20[4:1]};
|
|
imm11_7 <= {imm30_25[0], imm11_7[4:1]};
|
|
end
|
|
end
|
|
end
|
|
endgenerate
|
|
|
|
assign o_imm = i_cnt_done ? signbit : i_ctrl[0] ? imm11_7[0] : imm24_20[0];
|
|
|
|
endmodule
|