Start work on ALU
This commit is contained in:
parent
8c126980a6
commit
e9b8d44104
57
flake.nix
57
flake.nix
|
@ -11,38 +11,23 @@
|
||||||
|
|
||||||
verilator = import ./verilator.nix pkgs ;
|
verilator = import ./verilator.nix pkgs ;
|
||||||
|
|
||||||
rot-sim = pkgs.runCommandCC "rot-sim" {} ''
|
vflags = "-Wpedantic -Wwarn-lint -Wwarn-style";
|
||||||
cp "${./rot.v}" rot.v
|
verilate-src = cmd: ''
|
||||||
${verilator}/bin/verilator --cc -O3 --exe --build --trace ${./sim_main.cpp} rot.v
|
cp -r ${./verilog-src} ./verilog-src
|
||||||
|
cp -r ${./simulation} ./simulation
|
||||||
|
find ./verilog-src/ -name '*.v' -exec ${verilator}/bin/verilator ${vflags} ${cmd} {} +
|
||||||
|
'';
|
||||||
|
|
||||||
|
lint = pkgs.runCommand "lint" {} ''
|
||||||
|
${verilate-src "--lint-only"}
|
||||||
|
echo "compiler didn't get angry :3"
|
||||||
|
: 3 > $out
|
||||||
|
'';
|
||||||
|
|
||||||
|
alu-sim = pkgs.runCommandCC "alu-sim" {} ''
|
||||||
|
${verilate-src "--cc --build --exe ./simulation/test_alu.cpp"}
|
||||||
mv obj_dir "$out"
|
mv obj_dir "$out"
|
||||||
'';
|
mkdir "$out/bin" && cp "$out/Valu" "$out/bin/alu-sim"
|
||||||
|
|
||||||
rot-trace = pkgs.runCommand "rot-trace" {} ''
|
|
||||||
mkdir "$out"
|
|
||||||
${rot-sim}/Vrot $out/trace.vcd
|
|
||||||
'';
|
|
||||||
|
|
||||||
rot-trace-view = pkgs.writeScriptBin "rot-view" ''
|
|
||||||
${pkgs.gtkwave}/bin/gtkwave ${rot-trace}/trace.vcd
|
|
||||||
'';
|
|
||||||
|
|
||||||
rot-synth = pkgs.runCommand "rot-synth" {} ''
|
|
||||||
mkdir "$out"
|
|
||||||
${pkgs.yosys}/bin/yosys -p "read -vlog95 ${./rot.v} ; synth_ice40 -json $out/synth.json"
|
|
||||||
'';
|
|
||||||
|
|
||||||
rot-route = pkgs.runCommand "rot-route" {} ''
|
|
||||||
mkdir "$out"
|
|
||||||
${pkgs.nextpnr}/bin/nextpnr-ice40 --pcf ${./rot.pcf} --json ${rot-synth}/synth.json --asc $out/routed.asc --up5k --top rot --freq 12
|
|
||||||
'';
|
|
||||||
|
|
||||||
rot-pack = pkgs.runCommand "rot-pack" {} ''
|
|
||||||
mkdir "$out"
|
|
||||||
${pkgs.icestorm}/bin/icepack ${rot-route}/routed.asc $out/packed.bin
|
|
||||||
'';
|
|
||||||
|
|
||||||
rot-upload = pkgs.writeScriptBin "rot-upload" ''
|
|
||||||
${pkgs.icestorm}/bin/iceprog ${rot-pack}/packed.bin
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
deps = with pkgs; [
|
deps = with pkgs; [
|
||||||
|
@ -51,15 +36,9 @@
|
||||||
in rec {
|
in rec {
|
||||||
packages.verilator = verilator;
|
packages.verilator = verilator;
|
||||||
|
|
||||||
packages.rot-sim = rot-sim;
|
packages.lint = lint;
|
||||||
packages.rot-trace = rot-trace;
|
|
||||||
packages.rot-trace-view = rot-trace-view;
|
|
||||||
|
|
||||||
packages.rot-synth = rot-synth;
|
|
||||||
packages.rot-route = rot-route;
|
|
||||||
packages.rot-pack = rot-pack;
|
|
||||||
packages.rot-upload = rot-upload;
|
|
||||||
|
|
||||||
|
packages.alu-sim = alu-sim;
|
||||||
devShells.default = pkgs.mkShell {
|
devShells.default = pkgs.mkShell {
|
||||||
packages = deps;
|
packages = deps;
|
||||||
};
|
};
|
||||||
|
|
30
rot.v
30
rot.v
|
@ -1,30 +0,0 @@
|
||||||
module rot (input clk, output D0, output D1, output D2, output D3);
|
|
||||||
|
|
||||||
reg ready = 0;
|
|
||||||
reg [23:0] divider;
|
|
||||||
reg [3:0] rot;
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
|
||||||
if (ready)
|
|
||||||
begin
|
|
||||||
if (divider == 12_000_000)
|
|
||||||
begin
|
|
||||||
divider <= 0;
|
|
||||||
rot <= {rot[2], rot[1], rot[0], rot[3]};
|
|
||||||
end
|
|
||||||
else
|
|
||||||
divider <= divider + 1;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
ready <= 1;
|
|
||||||
rot <= 4'b1;
|
|
||||||
divider <= 0;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assign D0 = rot[0];
|
|
||||||
assign D1 = rot[1];
|
|
||||||
assign D2 = rot[2];
|
|
||||||
assign D3 = rot[3];
|
|
||||||
|
|
||||||
endmodule
|
|
18
simulation/test_alu.cpp
Normal file
18
simulation/test_alu.cpp
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#include "Valu.h"
|
||||||
|
#include "verilated.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
VerilatedContext *vctx = new VerilatedContext;
|
||||||
|
|
||||||
|
Valu *valu = new Valu(vctx);
|
||||||
|
valu->A = 0x2137;
|
||||||
|
valu->B = 0x1234;
|
||||||
|
|
||||||
|
valu->op = 0b000;
|
||||||
|
valu->eval();
|
||||||
|
printf("A = %04x + B = %04x = O = %04x\n", valu->A, valu->B, valu->O);
|
||||||
|
valu->op = 0b001;
|
||||||
|
valu->eval();
|
||||||
|
printf("A = %04x - B = %04x = O = %04x\n", valu->A, valu->B, valu->O);
|
||||||
|
}
|
28
verilog-src/alu.v
Normal file
28
verilog-src/alu.v
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
A and B are inputs, O is out
|
||||||
|
OP is the operation to perform:
|
||||||
|
000 = add
|
||||||
|
001 = sub
|
||||||
|
010 = mul
|
||||||
|
(011)
|
||||||
|
100 = and
|
||||||
|
101 = or
|
||||||
|
110 = xor
|
||||||
|
111 = not A
|
||||||
|
*/
|
||||||
|
module alu(
|
||||||
|
input [31:0] A,
|
||||||
|
input [31:0] B,
|
||||||
|
input [2:0] op,
|
||||||
|
output [31:0] O,
|
||||||
|
output Cout,
|
||||||
|
output Fzero
|
||||||
|
);
|
||||||
|
|
||||||
|
wire subtraction = op == 3'b001;
|
||||||
|
wire [31:0] adder_B = subtraction ? ~B : B;
|
||||||
|
|
||||||
|
carry_select_adder a(A, adder_B, subtraction, O, Cout);
|
||||||
|
assign Fzero = & O;
|
||||||
|
|
||||||
|
endmodule
|
29
verilog-src/alu/carry_select_adder.v
Normal file
29
verilog-src/alu/carry_select_adder.v
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
// 5 blocks of size 6, final block of size 2
|
||||||
|
module carry_select_adder(
|
||||||
|
input [31:0] A,
|
||||||
|
input [31:0] B,
|
||||||
|
input Cin,
|
||||||
|
output [31:0] O,
|
||||||
|
output Cout
|
||||||
|
);
|
||||||
|
|
||||||
|
// TODO: First block should not be carry_select, a normal RCA is better
|
||||||
|
// i think?
|
||||||
|
wire Cout_5;
|
||||||
|
carry_select_block#(6) B0 (A[5:0], B[5:0], Cin, O[5:0], Cout_5);
|
||||||
|
|
||||||
|
wire Cout_11;
|
||||||
|
carry_select_block#(6) B1 (A[11:6], B[11:6], Cout_5, O[11:6], Cout_11);
|
||||||
|
|
||||||
|
wire Cout_17;
|
||||||
|
carry_select_block#(6) B2 (A[17:12], B[17:12], Cout_11, O[17:12], Cout_17);
|
||||||
|
|
||||||
|
wire Cout_23;
|
||||||
|
carry_select_block#(6) B3 (A[23:18], B[23:18], Cout_17, O[23:18], Cout_23);
|
||||||
|
|
||||||
|
wire Cout_29;
|
||||||
|
carry_select_block#(6) B4 (A[29:24], B[29:24], Cout_23, O[29:24], Cout_29);
|
||||||
|
|
||||||
|
carry_select_block#(2) B6 (A[31:30], B[31:30], Cout_29, O[31:30], Cout);
|
||||||
|
|
||||||
|
endmodule
|
39
verilog-src/alu/carry_select_block.v
Normal file
39
verilog-src/alu/carry_select_block.v
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
module carry_select_block#(
|
||||||
|
parameter N = 4
|
||||||
|
) (
|
||||||
|
input [N-1:0] A,
|
||||||
|
input [N-1:0] B,
|
||||||
|
input Cin,
|
||||||
|
output [N-1:0] O,
|
||||||
|
output Cout
|
||||||
|
);
|
||||||
|
|
||||||
|
// Case for Cin = 0
|
||||||
|
wire [N-1:0] O_C0;
|
||||||
|
wire Cout_C0;
|
||||||
|
|
||||||
|
begin
|
||||||
|
wire [N-1:1] carry;
|
||||||
|
fa fa0(A[0], B[0], 0, O_C0[0], carry[1]);
|
||||||
|
genvar i; for (i = 1; i <= N - 1; i = i + 1) begin
|
||||||
|
fa fai(A[i], B[i], carry[i], O_C0[i], carry[i+1]);
|
||||||
|
end
|
||||||
|
assign Cout_C0 = carry[N-1];
|
||||||
|
end
|
||||||
|
|
||||||
|
// Case for Cin = 1
|
||||||
|
wire [N-1:0] O_C1;
|
||||||
|
wire Cout_C1;
|
||||||
|
begin
|
||||||
|
wire [N-1:1] carry;
|
||||||
|
fa fa0(A[0], B[0], 1, O_C1[0], carry[1]);
|
||||||
|
genvar i; for (i = 1; i <= N - 1; i = i + 1) begin
|
||||||
|
fa fai(A[i], B[i], carry[i], O_C1[i], carry[i+1]);
|
||||||
|
end
|
||||||
|
assign Cout_C1 = carry[N-1];
|
||||||
|
end
|
||||||
|
|
||||||
|
assign O = Cin == 0 ? O_C0 : O_C1;
|
||||||
|
assign Cout = Cin == 0 ? Cout_C0 : Cout_C1;
|
||||||
|
|
||||||
|
endmodule
|
7
verilog-src/alu/fa.v
Normal file
7
verilog-src/alu/fa.v
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// One bit full-adder
|
||||||
|
module fa(input A, input B, input Cin, output O, output Cout);
|
||||||
|
|
||||||
|
assign O = A ^ B ^ Cin;
|
||||||
|
assign Cout = (A & B) | (B & Cin) | (Cin & A);
|
||||||
|
|
||||||
|
endmodule
|
Loading…
Reference in New Issue
Block a user