summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Blake Kongslie2021-03-28 14:48:30 -0700
committerJulian Blake Kongslie2021-03-28 14:48:30 -0700
commit7a1311c16c36b18a66a5ee43511fb9ad5093ec3a (patch)
tree09df63644ac11dee4f2de25d476437e73fcdea84
downloadnoncpu-7a1311c16c36b18a66a5ee43511fb9ad5093ec3a.tar.xz
Initial commit.
-rw-r--r--.gitignore1
-rw-r--r--Makefile16
-rw-r--r--altera/clocks.sdc3
-rw-r--r--altera/jtag.cdf12
-rw-r--r--build.bat7
-rw-r--r--clean.bat1
-rw-r--r--hdl/jtag_uart.sv84
-rw-r--r--hdl/top.sv89
-rw-r--r--hdl/util.svh5
-rw-r--r--init.bat5
-rw-r--r--mem/jtag_uart.hex3
-rw-r--r--mem/mem.hex18
-rw-r--r--olamic-run12
-rw-r--r--sim/main.cpp56
-rw-r--r--tcl/clean.tcl3
-rw-r--r--tcl/init.tcl41
16 files changed, 356 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
/build
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..f4a0da8
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,16 @@
1SOURCES := $(shell find -name \*.sv -o -name \*.cpp)
2COLLATERAL := $(shell find -name \*.hex -o -name \*.svh)
3
4OPTS ?=
5
6sim: build/Vtop
7 $<
8.PHONY: sim
9
10build/Vtop: $(SOURCES) $(COLLATERAL)
11 @mkdir -p build
12 verilator +1800-2017ext+sv -Wall -Wno-BLKSEQ -Wno-UNUSED -O3 -Ihdl $(OPTS) --Mdir build --trace --cc --build -j --exe --top-module top $(SOURCES)
13
14clean:
15 rm -rf build
16.PHONY: clean
diff --git a/altera/clocks.sdc b/altera/clocks.sdc
new file mode 100644
index 0000000..239c91a
--- /dev/null
+++ b/altera/clocks.sdc
@@ -0,0 +1,3 @@
1# This is the clock for timing analysis, not timing-driven synthesis.
2# See init.tcl for the other clock.
3create_clock -period "50 MHz" clk
diff --git a/altera/jtag.cdf b/altera/jtag.cdf
new file mode 100644
index 0000000..ac80090
--- /dev/null
+++ b/altera/jtag.cdf
@@ -0,0 +1,12 @@
1JedecChain;
2 FileRevision(JESD32A);
3 DefaultMfr(6E);
4
5 P ActionCode(Ign)
6 Device PartName(10CL025Y) MfrSpec(OpMask(0));
7
8ChainEnd;
9
10AlteraBegin;
11 ChainType(JTAG);
12AlteraEnd;
diff --git a/build.bat b/build.bat
new file mode 100644
index 0000000..76cb8ff
--- /dev/null
+++ b/build.bat
@@ -0,0 +1,7 @@
1if not exist noncpu.qpf (
2 call init.bat
3) else (
4 call clean.bat
5)
6
7quartus_sh.exe --flow compile noncpu
diff --git a/clean.bat b/clean.bat
new file mode 100644
index 0000000..6b31ea1
--- /dev/null
+++ b/clean.bat
@@ -0,0 +1 @@
quartus_sh -t tcl/clean.tcl
diff --git a/hdl/jtag_uart.sv b/hdl/jtag_uart.sv
new file mode 100644
index 0000000..ad4665e
--- /dev/null
+++ b/hdl/jtag_uart.sv
@@ -0,0 +1,84 @@
1`include "util.svh"
2
3module jtag_uart
4 #( INSTANCE = 0
5
6 , RX_FIFO_BITS = 6
7 , TX_FIFO_BITS = 6
8 )
9 ( input bit clk
10 , input bit reset
11
12 , input bit rx_ready `define rx_ready `past(rx_ready)
13 , output bit rx_valid
14 , output bit [7:0] rx_data
15
16 , output bit tx_ready
17 , input bit tx_valid `define tx_valid `past(tx_valid)
18 , input bit [7:0] tx_data `define tx_data `past(tx_data)
19 );
20
21`ifdef SYNTHESIS
22
23alt_jtag_atlantic
24 #( .INSTANCE_ID(INSTANCE)
25 , .LOG2_RXFIFO_DEPTH(RX_FIFO_BITS)
26 , .LOG2_TXFIFO_DEPTH(TX_FIFO_BITS)
27 , .SLD_AUTO_INSTANCE_INDEX("NO")
28 ) real_jtag
29 ( .clk(clk)
30 , .rst_n(!reset)
31 , .r_dat(tx_data)
32 , .r_val(tx_valid)
33 , .r_ena(tx_ready)
34 , .t_dat(rx_data)
35 , .t_dav(rx_ready)
36 , .t_ena(rx_valid)
37 );
38
39`else
40
41bit [7:0] sim_rx_rom [0:(1<<16)-1];
42initial $readmemh("mem/jtag_uart.hex", sim_rx_rom);
43
44bit [15:0] sim_rx_addr;
45
46bit tx_b_valid;
47bit [7:0] tx_b_data;
48
49always_ff @(posedge clk) begin
50 if (reset) begin
51 rx_valid = 0;
52 tx_ready = 0;
53 sim_rx_addr = 0;
54 tx_b_valid = 0;
55 end else begin
56 automatic bit [7:0] sim_rx_data = sim_rx_rom[sim_rx_addr];
57
58 // RX logic
59 if (`rx_ready) rx_valid = 0;
60 if (!rx_valid && (sim_rx_data != 0)) begin
61`ifdef JTAG_UART_LOCAL_ECHO
62 $write("%s", sim_rx_data);
63`endif
64 rx_valid = 1;
65 rx_data = sim_rx_data;
66 ++sim_rx_addr;
67 end
68
69 // TX logic
70 if (tx_ready && `tx_valid) begin
71 tx_b_valid = 1;
72 tx_b_data = `tx_data;
73 end
74 if (tx_b_valid) begin
75 $write("%s", tx_b_data);
76 tx_b_valid = 0;
77 end
78 tx_ready = !tx_b_valid;
79 end
80end
81
82`endif
83
84endmodule
diff --git a/hdl/top.sv b/hdl/top.sv
new file mode 100644
index 0000000..8524b63
--- /dev/null
+++ b/hdl/top.sv
@@ -0,0 +1,89 @@
1`include "util.svh"
2
3module top
4 #( ADDR_BITS = 14
5 , DATA_BITS = 12
6 )
7 ( input bit clk // verilator public
8 , input bit reset_n // verilator public
9 );
10
11bit reset = 0;
12bit have_reset = 0;
13always_ff @(posedge clk) if (reset) have_reset <= 1;
14assign reset = !reset_n || !have_reset;
15
16bit [DATA_BITS-1:0] mem [0:(1<<ADDR_BITS)-1];
17initial $readmemh("mem/mem.hex", mem);
18
19bit rx_ready;
20bit rx_valid;
21bit [7:0] rx_data;
22
23bit tx_ready;
24bit tx_valid;
25bit [7:0] tx_data;
26
27jtag_uart
28 #( .INSTANCE(0)
29 ) uart0
30 ( .clk(clk)
31 , .reset(reset)
32
33 , .rx_ready(rx_ready)
34 , .rx_valid(rx_valid) `define rx_valid `past(rx_valid)
35 , .rx_data(rx_data) `define rx_data `past(rx_data)
36
37 , .tx_ready(tx_ready) `define tx_ready `past(tx_ready)
38 , .tx_valid(tx_valid)
39 , .tx_data(tx_data)
40 );
41
42bit [DATA_BITS-1:0] pc;
43bit [3:0] opcode;
44bit [7:0] operand;
45bit [DATA_BITS-1:0] acc;
46
47enum
48 { FETCH
49 , DECODE
50 } state;
51
52always_ff @(posedge clk) begin
53 if (reset) begin
54 rx_ready = 0;
55 tx_valid = 0;
56 tx_data = 0;
57 pc = 0;
58 acc = 0;
59 state = state.first;
60 end else begin
61 if (`tx_ready) tx_valid = 0;
62
63 case (state)
64 FETCH: begin
65 {opcode, operand} = mem[{2'b0, pc}];
66 ++pc;
67 state = DECODE;
68 end
69
70 DECODE: begin
71 state = FETCH;
72 case (opcode)
73 'b000: acc = {{4{operand[7]}}, operand};
74 'b001: begin
75 if (tx_valid) begin
76 state = DECODE;
77 end else begin
78 tx_valid = 1;
79 tx_data = acc[7:0];
80 end
81 end
82 'b111: state = DECODE;
83 endcase
84 end
85 endcase
86 end
87end
88
89endmodule
diff --git a/hdl/util.svh b/hdl/util.svh
new file mode 100644
index 0000000..ddba543
--- /dev/null
+++ b/hdl/util.svh
@@ -0,0 +1,5 @@
1`ifdef SYNTHESIS
2`define past(x) x
3`else
4`define past(x) $past(x)
5`endif
diff --git a/init.bat b/init.bat
new file mode 100644
index 0000000..6c76fa4
--- /dev/null
+++ b/init.bat
@@ -0,0 +1,5 @@
1if exist noncpu.qpf (
2 call clean.bat
3)
4
5quartus_sh.exe -t tcl/init.tcl
diff --git a/mem/jtag_uart.hex b/mem/jtag_uart.hex
new file mode 100644
index 0000000..7b08c66
--- /dev/null
+++ b/mem/jtag_uart.hex
@@ -0,0 +1,3 @@
1@0
2
300
diff --git a/mem/mem.hex b/mem/mem.hex
new file mode 100644
index 0000000..6d096bb
--- /dev/null
+++ b/mem/mem.hex
@@ -0,0 +1,18 @@
1@0
2
3048 100 // H
4065 100 // e
506c 100 // l
606c 100 // l
706f 100 // o
802c 100 // ,
9020 100 // ' '
10077 100 // w
1106f 100 // o
12072 100 // r
1306c 100 // l
14064 100 // d
15021 100 // !
1600a 100 // \n
17
18700
diff --git a/olamic-run b/olamic-run
new file mode 100644
index 0000000..24b72b1
--- /dev/null
+++ b/olamic-run
@@ -0,0 +1,12 @@
1# vim: set ft=bash :
2
3make
4
5if [[ $GIT_REF =~ ^refs/heads/(.+)$ ]]; then
6 INSTALL_DIR=/srv/olamic/artifacts/noncpu/"${BASH_REMATCH[1]}"
7fi
8
9if [[ "${INSTALL_DIR:-}" != "" ]]; then
10 mkdir -p "${INSTALL_DIR}"
11 git archive -o "${INSTALL_DIR}/noncpu.zip" @
12fi
diff --git a/sim/main.cpp b/sim/main.cpp
new file mode 100644
index 0000000..3f49cb6
--- /dev/null
+++ b/sim/main.cpp
@@ -0,0 +1,56 @@
1#include <cstdint>
2#include <iostream>
3#include <verilated.h>
4#include <verilated_vcd_c.h>
5
6#include "Vtop.h"
7
8int main(int argc, const char *argv[])
9{
10 Verilated::commandArgs(argc, argv);
11
12 Verilated::traceEverOn(true);
13 VerilatedVcdC vcd;
14
15 Vtop top;
16 top.trace(&vcd, 100 /* levels of hierarchy */);
17
18 vcd.set_time_unit("ns");
19 vcd.set_time_resolution("ns");
20 vcd.open("build/out.vcd");
21
22 std::cout << "*** RESET SEQUENCE ***\n";
23
24 std::uint64_t time = 0;
25
26 top.clk = 0;
27 top.reset_n = 0;
28 top.eval();
29 vcd.dump(++time);
30
31 top.clk = 1;
32 top.eval();
33 vcd.dump(++time);
34
35 top.clk = 0;
36 top.reset_n = 1;
37 top.eval();
38 vcd.dump(++time);
39
40 std::cout << "*** MAIN LOOP ***\n";
41
42 for (unsigned int i = 0; i < 500 && !Verilated::gotFinish(); ++i) {
43 top.clk = 1;
44 top.eval();
45 vcd.dump(++time);
46 top.clk = 0;
47 top.eval();
48 vcd.dump(++time);
49 }
50
51 std::cout << "\n";
52
53 vcd.close();
54
55 return 0;
56}
diff --git a/tcl/clean.tcl b/tcl/clean.tcl
new file mode 100644
index 0000000..49c9f65
--- /dev/null
+++ b/tcl/clean.tcl
@@ -0,0 +1,3 @@
1project_open noncpu -revision noncpu
2
3project_clean -revision noncpu
diff --git a/tcl/init.tcl b/tcl/init.tcl
new file mode 100644
index 0000000..039af91
--- /dev/null
+++ b/tcl/init.tcl
@@ -0,0 +1,41 @@
1project_new noncpu -revision noncpu -overwrite
2
3set_global_assignment -name DEVICE 10CL025YU256I7G
4
5set_global_assignment -name TOP_LEVEL_ENTITY top
6set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005
7set_global_assignment -name VERILOG_MACRO "SYNTHESIS=1"
8
9proc pin {loc net} {
10 set_location_assignment -to $net "PIN_$loc"
11 set_instance_assignment -name IO_STANDARD "3.3V LVTTL" -to $net
12}
13
14pin E1 clk
15pin J15 reset_n
16
17# This is the clock for timing-driven synthesis, not timing analysis.
18# See clocks.sdf for the other clock.
19create_base_clock -fmax "50 MHz" clk
20
21proc add_files {typ ext dir} {
22 foreach name [glob -nocomplain -directory $dir -type f "*.$ext"] {
23 set_global_assignment -name "${typ}_FILE" $name
24 }
25}
26
27proc add_dir {dir} {
28 add_files CDF cdf $dir
29 add_files HEX hex $dir
30 add_files SDC sdc $dir
31 add_files VERILOG sv $dir
32 add_files VERILOG svh $dir
33
34 foreach subdir [glob -nocomplain -directory $dir -type d *] {
35 add_dir $subdir
36 }
37}
38
39add_dir .
40
41project_close