Add SAP-1 code
This commit is contained in:
parent
1ffabc4e7b
commit
7590cd0cf3
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
SRC_DIR=$(pwd)/src
|
||||
BUILD_DIR=$(pwd)/.build
|
||||
APIO_HOME_DIR=$(pwd)/.apio
|
||||
BIN_DIR=$APIO_HOME_DIR/packages/tools-oss-cad-suite/bin
|
||||
COMMAND=$1
|
||||
VERSION=$2
|
||||
|
||||
MODULES="
|
||||
$SRC_DIR/adder.v
|
||||
$SRC_DIR/clock.v
|
||||
$SRC_DIR/controller.v
|
||||
$SRC_DIR/ir.v
|
||||
$SRC_DIR/memory.v
|
||||
$SRC_DIR/pc.v
|
||||
$SRC_DIR/reg_a.v
|
||||
$SRC_DIR/reg_b.v"
|
||||
|
||||
TOP=$SRC_DIR/top.v
|
||||
TB=$SRC_DIR/top_tb.v
|
||||
|
||||
if [ -z "$COMMAND" ]; then
|
||||
mkdir -p $BUILD_DIR
|
||||
pushd $BUILD_DIR > /dev/null
|
||||
|
||||
$BIN_DIR/yosys -q -p "synth_ice40 -json hardware.json" $MODULES $TOP
|
||||
$BIN_DIR/nextpnr-ice40 --lp8k --package cm81 --json hardware.json --asc hardware.asc --pcf $SRC_DIR/pins.pcf -q
|
||||
$BIN_DIR/icepack hardware.asc hardware.bin
|
||||
|
||||
popd > /dev/null
|
||||
elif [ "$COMMAND" == "init" ]; then
|
||||
virtualenv .env
|
||||
source .env/bin/activate
|
||||
pip install apio tinyprog
|
||||
export APIO_HOME_DIR=$APIO_HOME_DIR
|
||||
apio install oss-cad-suite
|
||||
elif [ "$COMMAND" == "clean" ]; then
|
||||
rm -r $BUILD_DIR
|
||||
elif [ "$COMMAND" == "program" ]; then
|
||||
source .env/bin/activate
|
||||
sudo tinyprog -p $BUILD_DIR/hardware.bin
|
||||
elif [ "$COMMAND" == "sim" ]; then
|
||||
mkdir -p $BUILD_DIR
|
||||
|
||||
pushd $SRC_DIR > /dev/null
|
||||
$BIN_DIR/iverilog -o $BUILD_DIR/top_tb $MODULES $TB
|
||||
$BIN_DIR/vvp $BUILD_DIR/top_tb
|
||||
mv top_tb.vcd $BUILD_DIR/
|
||||
popd > /dev/null
|
||||
|
||||
gtkwave $BUILD_DIR/top_tb.vcd $BUILD_DIR/top_tb.gtkw
|
||||
else
|
||||
echo "Invalid arguments"
|
||||
fi
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
module adder(
|
||||
input[7:0] a,
|
||||
input[7:0] b,
|
||||
input sub,
|
||||
input en,
|
||||
output[7:0] bus);
|
||||
|
||||
assign bus =
|
||||
(en) ?
|
||||
((sub) ? a-b : a+b) :
|
||||
8'bz;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
module clock(
|
||||
input hlt,
|
||||
input clk_in,
|
||||
output clk_out);
|
||||
|
||||
assign clk_out = (hlt) ? 1'b0 : clk_in;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
module controller(
|
||||
input clk,
|
||||
input[3:0] instr,
|
||||
output reg[11:0] ctrl_word);
|
||||
|
||||
localparam SIG_HLT = 11;
|
||||
localparam SIG_PC_INC = 10;
|
||||
localparam SIG_PC_EN = 9;
|
||||
localparam SIG_MEM_LOAD = 8;
|
||||
localparam SIG_MEM_EN = 7;
|
||||
localparam SIG_IR_LOAD = 6;
|
||||
localparam SIG_IR_EN = 5;
|
||||
localparam SIG_A_LOAD = 4;
|
||||
localparam SIG_A_EN = 3;
|
||||
localparam SIG_B_LOAD = 2;
|
||||
localparam SIG_ADDER_SUB = 1;
|
||||
localparam SIG_ADDER_EN = 0;
|
||||
|
||||
localparam OP_LDA = 4'b0000;
|
||||
localparam OP_ADD = 4'b0001;
|
||||
localparam OP_SUB = 4'b0010;
|
||||
localparam OP_HLT = 4'b1111;
|
||||
|
||||
reg[2:0] stage = 0;
|
||||
|
||||
always @(negedge clk) begin
|
||||
if (stage == 6) begin
|
||||
stage <= 1;
|
||||
end else begin
|
||||
stage <= stage + 1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(*) begin
|
||||
case (stage)
|
||||
1: begin
|
||||
ctrl_word = 12'b0;
|
||||
ctrl_word[SIG_PC_EN] = 1;
|
||||
ctrl_word[SIG_MEM_LOAD] = 1;
|
||||
end
|
||||
2: begin
|
||||
ctrl_word = 12'b0;
|
||||
ctrl_word[SIG_PC_INC] = 1;
|
||||
end
|
||||
3: begin
|
||||
ctrl_word = 12'b0;
|
||||
ctrl_word[SIG_MEM_EN] = 1;
|
||||
ctrl_word[SIG_IR_LOAD] = 1;
|
||||
end
|
||||
4: begin
|
||||
case (instr)
|
||||
OP_LDA: begin
|
||||
ctrl_word = 12'b0;
|
||||
ctrl_word[SIG_IR_EN] = 1;
|
||||
ctrl_word[SIG_MEM_LOAD] = 1;
|
||||
end
|
||||
OP_ADD: begin
|
||||
ctrl_word = 12'b0;
|
||||
ctrl_word[SIG_IR_EN] = 1;
|
||||
ctrl_word[SIG_MEM_LOAD] = 1;
|
||||
end
|
||||
OP_SUB: begin
|
||||
ctrl_word = 12'b0;
|
||||
ctrl_word[SIG_IR_EN] = 1;
|
||||
ctrl_word[SIG_MEM_LOAD] = 1;
|
||||
end
|
||||
OP_HLT: begin
|
||||
ctrl_word = 12'b0;
|
||||
ctrl_word[SIG_HLT] = 1;
|
||||
end
|
||||
default: begin
|
||||
ctrl_word = 12'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
5: begin
|
||||
case (instr)
|
||||
OP_LDA: begin
|
||||
ctrl_word = 12'b0;
|
||||
ctrl_word[SIG_MEM_EN] = 1;
|
||||
ctrl_word[SIG_A_LOAD] = 1;
|
||||
end
|
||||
OP_ADD: begin
|
||||
ctrl_word = 12'b0;
|
||||
ctrl_word[SIG_MEM_EN] = 1;
|
||||
ctrl_word[SIG_B_LOAD] = 1;
|
||||
end
|
||||
OP_SUB: begin
|
||||
ctrl_word = 12'b0;
|
||||
ctrl_word[SIG_MEM_EN] = 1;
|
||||
ctrl_word[SIG_B_LOAD] = 1;
|
||||
end
|
||||
default: begin
|
||||
ctrl_word = 12'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
6: begin
|
||||
case (instr)
|
||||
OP_ADD: begin
|
||||
ctrl_word = 12'b0;
|
||||
ctrl_word[SIG_ADDER_EN] = 1;
|
||||
ctrl_word[SIG_A_LOAD] = 1;
|
||||
end
|
||||
OP_SUB: begin
|
||||
ctrl_word = 12'b0;
|
||||
ctrl_word[SIG_ADDER_SUB] = 1;
|
||||
ctrl_word[SIG_ADDER_EN] = 1;
|
||||
ctrl_word[SIG_A_LOAD] = 1;
|
||||
end
|
||||
default: begin
|
||||
ctrl_word = 12'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
default: begin
|
||||
ctrl_word = 12'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
module ir(
|
||||
input clk,
|
||||
input clr,
|
||||
input load,
|
||||
input en,
|
||||
inout[7:0] bus,
|
||||
output[3:0] instr);
|
||||
|
||||
reg[7:0] ir = 0;
|
||||
|
||||
always @(posedge clk or posedge clr) begin
|
||||
if (clr) begin
|
||||
ir <= 8'b0;
|
||||
end else if (load) begin
|
||||
ir <= bus;
|
||||
end
|
||||
end
|
||||
|
||||
assign instr = ir[7:4];
|
||||
assign bus = (en) ? ir[3:0] : 8'bz;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
module memory(
|
||||
input clk,
|
||||
input load,
|
||||
input en,
|
||||
inout[7:0] bus
|
||||
);
|
||||
|
||||
initial begin
|
||||
$readmemh("program.bin", ram);
|
||||
end
|
||||
|
||||
reg[3:0] mar = 0;
|
||||
reg[7:0] ram[0:15];
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (load) begin
|
||||
mar <= bus[3:0];
|
||||
end
|
||||
end
|
||||
|
||||
assign bus = (en) ? ram[mar] : 8'bz;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
module pc(
|
||||
input clk,
|
||||
input clr,
|
||||
input inc,
|
||||
input en,
|
||||
output[7:0] bus
|
||||
);
|
||||
|
||||
reg[3:0] pc = 0;
|
||||
|
||||
always @(posedge clk or posedge clr) begin
|
||||
if (clr) begin
|
||||
pc <= 4'b0;
|
||||
end else if (inc) begin
|
||||
pc <= pc + 1;
|
||||
end
|
||||
end
|
||||
|
||||
assign bus = (en) ? pc : 8'bz;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
set_io --warn-no-port CLK B2 # input
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
0D
|
||||
1E
|
||||
2F
|
||||
F0
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
00
|
||||
03
|
||||
04
|
||||
02
|
|
@ -0,0 +1,20 @@
|
|||
module reg_a(
|
||||
input clk,
|
||||
input load,
|
||||
input en,
|
||||
inout[7:0] bus,
|
||||
output[7:0] val);
|
||||
|
||||
reg[7:0] reg_a = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (load) begin
|
||||
reg_a <= bus;
|
||||
end
|
||||
end
|
||||
|
||||
assign bus = (en) ? reg_a : 8'bz;
|
||||
assign val = reg_a;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
module reg_b(
|
||||
input clk,
|
||||
input load,
|
||||
input[7:0] bus,
|
||||
output[7:0] val);
|
||||
|
||||
reg[7:0] reg_b = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (load) begin
|
||||
reg_b <= bus;
|
||||
end
|
||||
end
|
||||
|
||||
assign val = reg_b;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
module top(
|
||||
input CLK);
|
||||
|
||||
wire[7:0] bus;
|
||||
|
||||
wire clk;
|
||||
wire hlt;
|
||||
clock clock(
|
||||
.hlt(hlt),
|
||||
.clk_in(CLK),
|
||||
.clk_out(clk)
|
||||
);
|
||||
|
||||
wire clr;
|
||||
wire pc_en;
|
||||
wire pc_inc;
|
||||
pc pc(
|
||||
.clk(clk),
|
||||
.clr(clr),
|
||||
.inc(pc_inc),
|
||||
.en(pc_en),
|
||||
.bus(bus)
|
||||
);
|
||||
|
||||
wire a_load;
|
||||
wire a_en;
|
||||
wire[7:0] a_val;
|
||||
reg_a reg_a(
|
||||
.clk(clk),
|
||||
.load(a_load),
|
||||
.en(a_en),
|
||||
.bus(bus),
|
||||
.val(a_val)
|
||||
);
|
||||
|
||||
wire b_load;
|
||||
wire[7:0] b_val;
|
||||
reg_b reg_b(
|
||||
.clk(clk),
|
||||
.load(b_load),
|
||||
.bus(bus),
|
||||
.val(b_val)
|
||||
);
|
||||
|
||||
wire adder_sub;
|
||||
wire adder_en;
|
||||
adder adder(
|
||||
.a(a_val),
|
||||
.b(b_val),
|
||||
.sub(adder_sub),
|
||||
.en(adder_en),
|
||||
.bus(bus)
|
||||
);
|
||||
|
||||
wire mar_load;
|
||||
wire mem_en;
|
||||
memory mem(
|
||||
.clk(clk),
|
||||
.load(mar_load),
|
||||
.en(mem_en),
|
||||
.bus(bus)
|
||||
);
|
||||
|
||||
wire ir_load;
|
||||
wire ir_en;
|
||||
wire[3:0] ir_instr;
|
||||
ir ir(
|
||||
.clk(clk),
|
||||
.clr(clr),
|
||||
.load(ir_load),
|
||||
.en(ir_en),
|
||||
.bus(bus),
|
||||
.instr(ir_instr)
|
||||
);
|
||||
|
||||
controller controller(
|
||||
.clk(clk),
|
||||
.instr(ir_instr),
|
||||
.ctrl_word(
|
||||
{
|
||||
hlt,
|
||||
pc_inc,
|
||||
pc_en,
|
||||
mar_load,
|
||||
mem_en,
|
||||
ir_load,
|
||||
ir_en,
|
||||
a_load,
|
||||
a_en,
|
||||
b_load,
|
||||
adder_sub,
|
||||
adder_en
|
||||
})
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
module top_tb();
|
||||
|
||||
initial begin
|
||||
$dumpfile("top_tb.vcd");
|
||||
$dumpvars(0, top_tb);
|
||||
end
|
||||
|
||||
reg clk_in = 0;
|
||||
integer i;
|
||||
initial begin
|
||||
for (i = 0; i < 128; i++) begin
|
||||
#1 clk_in = ~clk_in;
|
||||
end
|
||||
end
|
||||
|
||||
wire clk;
|
||||
wire hlt;
|
||||
wire clr;
|
||||
wire[7:0] bus;
|
||||
|
||||
clock clock(
|
||||
.hlt(hlt),
|
||||
.clk_in(clk_in),
|
||||
.clk_out(clk)
|
||||
);
|
||||
|
||||
wire pc_en;
|
||||
wire pc_inc;
|
||||
pc pc(
|
||||
.clk(clk),
|
||||
.clr(clr),
|
||||
.inc(pc_inc),
|
||||
.en(pc_en),
|
||||
.bus(bus)
|
||||
);
|
||||
|
||||
wire a_load;
|
||||
wire a_en;
|
||||
wire[7:0] a_val;
|
||||
reg_a reg_a(
|
||||
.clk(clk),
|
||||
.load(a_load),
|
||||
.en(a_en),
|
||||
.bus(bus),
|
||||
.val(a_val)
|
||||
);
|
||||
|
||||
wire b_load;
|
||||
wire[7:0] b_val;
|
||||
reg_b reg_b(
|
||||
.clk(clk),
|
||||
.load(b_load),
|
||||
.bus(bus),
|
||||
.val(b_val)
|
||||
);
|
||||
|
||||
wire adder_sub;
|
||||
wire adder_en;
|
||||
adder adder(
|
||||
.a(a_val),
|
||||
.b(b_val),
|
||||
.sub(adder_sub),
|
||||
.en(adder_en),
|
||||
.bus(bus)
|
||||
);
|
||||
|
||||
wire mar_load;
|
||||
wire mem_en;
|
||||
memory mem(
|
||||
.clk(clk),
|
||||
.load(mar_load),
|
||||
.en(mem_en),
|
||||
.bus(bus)
|
||||
);
|
||||
|
||||
wire ir_load;
|
||||
wire ir_en;
|
||||
wire[3:0] ir_instr;
|
||||
ir ir(
|
||||
.clk(clk),
|
||||
.clr(clr),
|
||||
.load(ir_load),
|
||||
.en(ir_en),
|
||||
.bus(bus),
|
||||
.instr(ir_instr)
|
||||
);
|
||||
|
||||
controller controller(
|
||||
.clk(clk),
|
||||
.instr(ir_instr),
|
||||
.ctrl_word(
|
||||
{
|
||||
hlt,
|
||||
pc_inc,
|
||||
pc_en,
|
||||
mar_load,
|
||||
mem_en,
|
||||
ir_load,
|
||||
ir_en,
|
||||
a_load,
|
||||
a_en,
|
||||
b_load,
|
||||
adder_sub,
|
||||
adder_en
|
||||
})
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
Loading…
Reference in New Issue