|
|
@@ -1,95 +1,41 @@
|
|
|
import project_pkg::*;
|
|
|
|
|
|
-module cpu(clk, rst, in_data, out_data);
|
|
|
+module cpu(clk, rst, instr, imm, pc, mem_addr, mem_wr_en, mem_wr_data, mem_rd_data);
|
|
|
input logic clk, rst;
|
|
|
- input logic [7:0]in_data;
|
|
|
- output logic [7:0]out_data;
|
|
|
-
|
|
|
- // ==================
|
|
|
- // Program counter
|
|
|
- // ==================
|
|
|
- word pc; // Program counter
|
|
|
- word pcn; // Next PC
|
|
|
+ input word instr, imm, mem_rd_data;
|
|
|
+ output logic mem_wr_en;
|
|
|
+ output word pc, mem_addr, mem_wr_data;
|
|
|
|
|
|
- always_ff@(posedge clk, negedge rst) begin
|
|
|
- if (!rst) pc <= '0;
|
|
|
- else pc <= pcn;
|
|
|
- end
|
|
|
-
|
|
|
- // ==================
|
|
|
- // Instruction memory
|
|
|
- // ==================
|
|
|
- word instr, imm;
|
|
|
+ // Controller
|
|
|
+ logic alu_zero, pc_src, reg_wr, alu_src, mem_to_reg;
|
|
|
e_instr instr_op;
|
|
|
- regAddr rs, rt;
|
|
|
-
|
|
|
- instr_mem IMEM(pc, instr, imm);
|
|
|
- // Instruction decoding
|
|
|
- assign instr_op = e_instr'(instr[7:4]);
|
|
|
- assign rs = regAddr'(instr[3:2]);
|
|
|
- assign rt = regAddr'(instr[1:0]);
|
|
|
+ e_reg rs, rt;
|
|
|
+ e_alu_op alu_op;
|
|
|
|
|
|
- // =====================
|
|
|
- // ALU
|
|
|
- // =====================
|
|
|
- e_alu_op alu_op;
|
|
|
- word alu_result;
|
|
|
- word alu_srcA;
|
|
|
- word alu_srcB;
|
|
|
- logic alu_zero;
|
|
|
- alu ALU(alu_op, alu_srcA, alu_srcB, alu_result, alu_zero);
|
|
|
-
|
|
|
- // =====================
|
|
|
- // Register File
|
|
|
- // =====================
|
|
|
- logic reg_wr_en;
|
|
|
- regAddr reg_wr_addr;
|
|
|
- word reg_wr_data;
|
|
|
- regAddr reg_rd_addr_1;
|
|
|
- regAddr reg_rd_addr_2;
|
|
|
- word reg_rd_data_1;
|
|
|
- word reg_rd_data_2;
|
|
|
- reg_file RFILE(clk, reg_rd_addr_1, reg_rd_addr_2, reg_rd_data_1, reg_rd_data_2, reg_wr_addr, reg_wr_data, reg_wr_en);
|
|
|
-
|
|
|
- // =====================
|
|
|
+ controller CTRL(instr, alu_zero, alu_op, mem_wr_en, reg_wr, pc_src, alu_src, mem_to_reg, instr_op, rs, rt);
|
|
|
+
|
|
|
+ // Datapath
|
|
|
+ datapath DPATH(clk, rst, rs, rt, imm, alu_op, reg_wr, pc_src, alu_src, mem_to_reg, pc, mem_addr, mem_rd_data, alu_zero, mem_wr_data);
|
|
|
+endmodule
|
|
|
+
|
|
|
+module cpu_tb;
|
|
|
+ logic clk, rst, mem_wr;
|
|
|
+ word pc, instr, imm, mem_addr, mem_data, mem_rd_data;
|
|
|
+ cpu CPU(clk, rst, instr, imm, pc, mem_addr, mem_wr, mem_data, mem_rd_data);
|
|
|
+ // Instruction memory
|
|
|
+ instr_mem #("/home/min/devel/fpga/ucl_project_y3/memory/rom_test.mem") IMEM(pc, instr, imm);
|
|
|
// System memory
|
|
|
- // =====================
|
|
|
- logic mem_wr_en;
|
|
|
- word mem_rd_data;
|
|
|
- memory RAM(clk, alu_result, mem_rd_data, reg_rd_data_2, mem_wr_en);
|
|
|
-
|
|
|
- // =====================
|
|
|
- // Control unit
|
|
|
- // =====================
|
|
|
- logic reg_dst;
|
|
|
- logic alu_src;
|
|
|
- logic mem_to_reg;
|
|
|
-
|
|
|
- assign alu_srcA = reg_rd_data_1;
|
|
|
- assign alu_src = (instr_op == ADDI);
|
|
|
- assign alu_srcB = (alu_src) ? reg_rd_data_2 : imm;
|
|
|
- assign reg_wr_data = (mem_to_reg) ? mem_rd_data : alu_result;
|
|
|
-
|
|
|
- assign reg_wr_addr = rs;
|
|
|
- assign reg_rd_addr_1 = rs;
|
|
|
- assign reg_rd_addr_2 = rt;
|
|
|
-
|
|
|
- always_comb begin
|
|
|
- case(instr_op)
|
|
|
- ADD: alu_op = ALU_ADD;
|
|
|
- ADDI: alu_op = ALU_ADD;
|
|
|
- SUB: alu_op = ALU_SUB;
|
|
|
- AND: alu_op = ALU_AND;
|
|
|
- OR: alu_op = ALU_OR;
|
|
|
- NOT: alu_op = ALU_NOT;
|
|
|
- JEQ: alu_op = ALU_SUB;
|
|
|
- default: alu_op = ALU_NOP;
|
|
|
- endcase
|
|
|
+ memory RAM(clk, mem_addr, mem_data, mem_rd_data, mem_wr);
|
|
|
+ initial begin
|
|
|
+ clk = 0;
|
|
|
+ forever #5ns clk = ~clk;
|
|
|
end
|
|
|
-
|
|
|
- assign mem_wr_en = instr_op == SW;
|
|
|
- assign mem_to_reg = instr_op == LW;
|
|
|
- assign pcn = (alu_zero && instr_op == JEQ) ? imm : pc + 1;
|
|
|
-
|
|
|
-endmodule
|
|
|
|
|
|
+ initial begin
|
|
|
+ rst = 1;
|
|
|
+ #10ns;
|
|
|
+ rst = 0;
|
|
|
+ #100ns;
|
|
|
+ $stop;
|
|
|
+ end
|
|
|
+endmodule
|