192 lines
4.6 KiB
Verilog
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
|