Files
stack/cpu.v
2026-03-07 23:45:11 -05:00

192 lines
4.6 KiB
Verilog

module cpu
(input i_clk,
input i_rst_n,
input i_uart_rx,
output o_uart_tx,
/*
input i_ack,
input [31:0] i_dat,
output [31:0] o_dat,
output [31:0] o_adr,
output [3:0] o_sel,
output o_we,
output o_stb,
output o_cyc,
*/
output reg [5:0] o_led);
wire i_rst;
wire halt;
wire [8:0] seq_a;
wire [8:0] seq_y;
wire seq_cc;
wire alu_zero;
wire [3:0] alu_op;
wire [31:0] alu_a;
wire [31:0] alu_b;
wire [31:0] alu_y;
wire [2:0] rf_rd_addr;
wire rf_mdr_we;
wire [23:0] rf_rma_data;
wire [31:0] rf_mdr_data_r;
wire [31:0] rf_mdr_data_w;
wire [31:0] rf_rs2_data;
wire rf_we;
wire mem_rwait;
wire mem_wwait;
wire [1:0] mem_act;
wire srr_we;
wire srr_stb;
wire [31:0] srr_data;
wire [8:0] u_imm;
wire [1:0] u_seq_op;
wire u_seq_src;
wire u_seq_cce;
wire u_seq_cci;
wire u_alu_src;
wire [3:0] u_alu_op;
wire [2:0] u_rf_rs1;
wire [1:0] u_rf_rs2;
wire [2:0] u_rf_rd;
wire [1:0] u_rf_rma;
wire u_rf_we;
wire [1:0] u_mem_act;
wire u_mem_actsrc;
wire u_mem_dir;
reg [35:0] uinst;
reg phalt;
reg strobe;
(* ram_style = "block" *) reg [35:0] microcode_rom [511:0];
reg [11:0] mapping_rom [63:0];
initial begin
$readmemh("/Users/car/Projects/hope/ucode.hex", microcode_rom);
$readmemh("/Users/car/Projects/hope/umap.hex", mapping_rom);
end
assign i_rst = ~i_rst_n;
assign mem_rwait = 0;
assign mem_wwait = 0;
assign rf_we = u_rf_we; //&((u_mem_act != 2'b00)?~strobe:1);
assign {u_imm[8:0], u_seq_op[1:0], u_seq_src, u_seq_cce, u_seq_cci, u_alu_src, u_alu_op[3:0],
u_rf_rs1[2:0], u_rf_rs2[1:0], u_rf_rd[2:0], u_rf_rma[1:0], u_rf_we,
u_mem_act[1:0], u_mem_actsrc, u_mem_dir} = uinst;
/*
assign halt = (mem_wwait && u_rf_rd == 3'd4) ||
(mem_rwait && (u_seq_src || u_rf_rs1 == 3'd4 || u_rf_rs2 == 3'd4)) ||
((mem_wwait | mem_rwait) & (u_mem_act[0] | u_mem_act[1]));
*/
assign halt = (u_mem_act != 2'b00 && !strobe);
assign seq_cc = ~u_seq_cce | (u_seq_cce & (u_seq_cci ^ alu_zero));
assign seq_a = u_seq_src ? mapping_rom[rf_mdr_data_r[7:2]][8:0] : u_imm;
assign alu_b = rf_rs2_data;
assign rf_mdr_we = (rf_rma_data < 24'h008000) ? srr_we : 0;
assign rf_mdr_data_w = (rf_rma_data < 24'h008000) ? srr_data : 0;
assign alu_op = u_alu_src ? rf_rma_data[3:0] : u_alu_op;
assign mem_act = u_mem_actsrc ? rf_rma_data[1:0] : u_mem_act;
always @(posedge i_clk, posedge i_rst) begin
if (i_rst) begin
uinst <= 0;
strobe <= 0;
phalt <= 0;
end else begin
phalt <= halt;
if (u_mem_act != 2'b00 && !strobe) begin
strobe <= 1;
uinst <= uinst;
end else begin
strobe <= 0;
uinst <= microcode_rom[seq_y];
end
end
end
always @(posedge i_clk, posedge i_rst) begin
if (i_rst) o_led <= 0;
else if (rf_rma_data == 28'h00F000 && u_mem_dir) o_led <= rf_mdr_data_w[7:0];
else o_led <= o_led;
end
register_file register_file_inst
(.i_clk(i_clk),
.i_rst(i_rst),
.i_halt(halt),
.i_rs1_addr(u_rf_rs1),
.i_rs2_addr(u_rf_rs2),
.i_rd_addr(u_rf_rd),
.i_rma_addr(u_rf_rma),
.i_rd_data(alu_y),
.i_rd_we(rf_we),
.i_mdr_we(rf_mdr_we),
.i_mdr_data(rf_mdr_data_w),
.i_imm(u_imm),
.o_rs1_data(alu_a),
.o_rs2_data(rf_rs2_data),
.o_rma_data(rf_rma_data),
.o_mdr_data(rf_mdr_data_r));
alu alu_inst
(.i_a(alu_a),
.i_b(alu_b),
.i_op(alu_op),
.o_zero(alu_zero),
.o_y(alu_y));
sequencer sequencer_inst
(.i_clk(i_clk),
.i_rst(i_rst),
.i_halt(halt),
.i_a(seq_a),
.i_op(u_seq_op),
.i_cc(seq_cc),
.o_y(seq_y));
sram_srom sram_srom_inst
(.i_clk(i_clk),
.i_rst(i_rst),
.i_dir(u_mem_dir),
.i_act(mem_act),
.i_addr(rf_rma_data),
.i_data(rf_mdr_data_r),
.o_data(srr_data),
.o_we(srr_we),
.o_stb(srr_stb));
/*
bus_interface bus_interface_inst
(.i_clk(i_clk),
.i_rst(i_rst),
.i_act(u_mem_act),
.i_dir(u_mem_dir),
.i_cpu_data(rf_mdr_data_r),
.i_cpu_addr(rf_rma_data),
.o_cpu_data(rf_mdr_data_w),
.o_cpu_we(rf_mdr_we),
.o_rwait(mem_rwait),
.o_wwait(mem_wwait),
.i_ack(i_ack),
.i_dat(i_dat),
.o_dat(o_dat),
.o_adr(o_adr),
.o_we(o_we),
.o_cyc(o_cyc),
.o_stb(o_stb),
.o_sel(o_sel));
*/
endmodule