Initial commit. Working CPU!
This commit is contained in:
commit
6bceee5e68
26
alu.sv
Normal file
26
alu.sv
Normal file
|
@ -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
|
89
cpu.sv
Normal file
89
cpu.sv
Normal file
|
@ -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
|
15
memory.sv
Executable file
15
memory.sv
Executable file
|
@ -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
|
6
mux2.sv
Executable file
6
mux2.sv
Executable file
|
@ -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
|
24
mux4.sv
Executable file
24
mux4.sv
Executable file
|
@ -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
|
18
register.sv
Executable file
18
register.sv
Executable file
|
@ -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
|
Loading…
Reference in New Issue
Block a user