50 lines
1.4 KiB
Verilog
50 lines
1.4 KiB
Verilog
module register_file
|
|
(input i_clk,
|
|
input i_rst,
|
|
input i_halt,
|
|
input [2:0] i_rs1_addr,
|
|
input [1:0] i_rs2_addr,
|
|
input [1:0] i_rma_addr,
|
|
input [2:0] i_rd_addr,
|
|
input [31:0] i_rd_data,
|
|
input i_rd_we,
|
|
input i_mdr_we,
|
|
input [31:0] i_mdr_data,
|
|
input [8:0] i_imm,
|
|
output [31:0] o_rs1_data,
|
|
output [31:0] o_rs2_data,
|
|
output [23:0] o_rma_data,
|
|
output [31:0] o_mdr_data);
|
|
|
|
reg [23:0] addr_registers [0:3]; // PCP DSP RSP TMP
|
|
reg [31:0] data_registers [0:2]; // MDR TOS ACC (IMM)
|
|
integer i;
|
|
|
|
assign o_mdr_data = data_registers[0];
|
|
assign o_rma_data = addr_registers[i_rma_addr];
|
|
assign o_rs1_data = (i_rs1_addr != 3'b111) ? (i_rs1_addr[2] ? data_registers[i_rs1_addr[1:0]] : {8'd0, addr_registers[i_rs1_addr[1:0]]}) : i_imm;
|
|
assign o_rs2_data = (i_rs2_addr != 2'b11) ? data_registers[i_rs2_addr[1:0]] : i_imm;
|
|
|
|
always @(posedge i_clk, posedge i_rst) begin
|
|
if (i_rst) begin
|
|
for (i = 0; i < 4; i = i + 1) begin
|
|
addr_registers[i] <= 0;
|
|
if (i != 3) data_registers[i] <= 0;
|
|
end
|
|
end else begin
|
|
if (i_rd_we && !i_halt && i_rd_addr != 3'b111) begin
|
|
if (i_rd_addr != 3'd4 || !i_mdr_we) begin
|
|
if (i_rd_addr[2])
|
|
data_registers[i_rd_addr[1:0]] <= i_rd_data;
|
|
else
|
|
addr_registers[i_rd_addr[1:0]] <= i_rd_data[23:0];
|
|
end
|
|
end
|
|
|
|
if (i_mdr_we)
|
|
data_registers[0] <= i_mdr_data;
|
|
end
|
|
end
|
|
|
|
endmodule // register_file
|