From 6bceee5e68e4f55949dcfbd1ebf5a138c50a9e07 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Tue, 5 Jun 2018 00:06:45 -0700 Subject: [PATCH] Initial commit. Working CPU! --- alu.sv | 26 ++++++++++++++++ cpu.sv | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++ memory.sv | 15 +++++++++ mux2.sv | 6 ++++ mux4.sv | 24 +++++++++++++++ register.sv | 18 +++++++++++ 6 files changed, 178 insertions(+) create mode 100644 alu.sv create mode 100644 cpu.sv create mode 100755 memory.sv create mode 100755 mux2.sv create mode 100755 mux4.sv create mode 100755 register.sv diff --git a/alu.sv b/alu.sv new file mode 100644 index 0000000..7993963 --- /dev/null +++ b/alu.sv @@ -0,0 +1,26 @@ +module alu #(width=32) + (input logic [width-1:0] left, right, + input logic [2:0] op, + output logic [width-1:0] out); + logic [width-1:0] selected_right, not_right; + assign not_right = ~right; + mux2 #(width) right_mux( + .left(right), + .right(not_right), + .select(op[2]), + .out(selected_right)); + + logic [width-1:0] op_and, op_or, op_sum, op_slt; + assign op_and = left & selected_right; + assign op_or = left | selected_right; + assign op_sum = left + selected_right + op[2]; + assign op_slt = op_sum[width-1]; + + mux4 output_mux( + .first(op_and), + .second(op_or), + .third(op_sum), + .fourth(op_slt), + .select(op[1:0]), + .out(out)); +endmodule \ No newline at end of file diff --git a/cpu.sv b/cpu.sv new file mode 100644 index 0000000..826ab97 --- /dev/null +++ b/cpu.sv @@ -0,0 +1,89 @@ +module cpu (input logic clk, reset, + input logic prog, + input logic[31:0] pinst, + input logic[7:0] paddr, + output logic [31:0] disp); + logic [7:0] pc; + logic [7:0] pc_next, pc_compute; + logic [31:0] inst; + logic [5:0] op; + logic [2:0] rd, rs, rt; + logic [31:0] rd_val, rs_val, rt_val; + logic [15:0] const_val; + logic [31:0] const_extend; + logic [31:0] cpu_disp; + logic [31:0] reg_alu_out, const_alu_out; + logic should_jump, should_write, use_const; + + assign op = inst[31:26]; + assign rd = inst[25:23]; + assign rs = inst[22:20]; + assign rt = inst[19:17]; + assign const_val = inst[15:0]; + + assign should_write = inst[31]; + assign use_const = inst[30]; + assign should_jump = inst[29]; + + assign const_extend = const_val; + + registers #(32) regs( + .raddr1(rs), + .raddr2(rt), + .waddr(rd), + .in(rd_val), + .wen(should_write), + .clk(clk), + .reset(reset), + .out1(rs_val), + .out2(rt_val)); + + memory #(32) insts( + .raddr(pc), + .waddr(paddr), + .wen(prog), + .in(pinst), + .clk(clk), + .out(inst), + .reset(reset)); + + alu #(32) reg_alu( + .left(rs_val), + .right(rt_val), + .op(inst[28:26]), + .out(reg_alu_out)); + + alu #(32) const_alu( + .left(rs_val), + .right(const_extend), + .op(inst[28:26]), + .out(const_alu_out)); + + mux2 #(32) out_mux( + .left(reg_alu_out), + .right(const_alu_out), + .select(use_const), + .out(rd_val)); + + assign pc_compute = rt_val + const_val; + + mux2 #(8) pc_mux( + .left(pc + 1), + .right(pc_compute), + .select(should_jump & (inst[28] | (inst[26] ^ (rs_val == 0)))), + .out(pc_next)); + + always_ff@(posedge clk) + if(reset) begin + pc <= 0; + cpu_disp <= 0; + end else if(!prog) begin + case(op) + 6'b0000000: cpu_disp <= rs_val; + endcase + pc <= pc_next; + end + + assign disp = cpu_disp; + +endmodule \ No newline at end of file diff --git a/memory.sv b/memory.sv new file mode 100755 index 0000000..2f18366 --- /dev/null +++ b/memory.sv @@ -0,0 +1,15 @@ +module memory #(width=32) + (input logic [7:0] raddr, waddr, + input logic [width-1:0] in, + input logic clk, wen, reset, + output logic [width-1:0] out); + logic [width-1:0] data [0:255]; + always_ff@(posedge clk) + if(reset) begin + data <= '{default: 0}; + end else begin + if(wen) data[waddr] <= in; + end + + assign out = data[raddr]; +endmodule \ No newline at end of file diff --git a/mux2.sv b/mux2.sv new file mode 100755 index 0000000..8cbfea5 --- /dev/null +++ b/mux2.sv @@ -0,0 +1,6 @@ +module mux2 #(width=32) + (input logic [width-1:0] left, right, + input logic select, + output logic [width-1:0] out); + assign out = select ? right : left; +endmodule \ No newline at end of file diff --git a/mux4.sv b/mux4.sv new file mode 100755 index 0000000..98b3e92 --- /dev/null +++ b/mux4.sv @@ -0,0 +1,24 @@ +module mux4 #(width=32) + (input logic [width-1:0] first, second, third, fourth, + input logic [1:0] select, + output logic [width-1:0] out); + + logic [width-1:0] lower, upper; + + mux2 lower_mux( + .left(first), + .right(second), + .select(select[0]), + .out(lower)); + mux2 upper_mux( + .left(third), + .right(fourth), + .select(select[0]), + .out(upper)); + + mux2 final_mux( + .left(lower), + .right(upper), + .select(select[1]), + .out(out)); +endmodule \ No newline at end of file diff --git a/register.sv b/register.sv new file mode 100755 index 0000000..d317d79 --- /dev/null +++ b/register.sv @@ -0,0 +1,18 @@ +module registers #(width=32) + (input logic [2:0] raddr1, raddr2, waddr, + input clk, wen, reset, + input logic [width-1:0] in, + output logic [width-1:0] out1, out2); + logic [width-1:0] data [0:7]; + + always_ff@(posedge clk) + if (reset) begin + data <= '{default: 0}; + end else begin + if(wen) data[waddr] <= in; + end + + assign out1 = data[raddr1]; + assign out2 = data[raddr2]; + +endmodule \ No newline at end of file