diff options
| author | Julian Blake Kongslie | 2021-03-28 14:48:30 -0700 |
|---|---|---|
| committer | Julian Blake Kongslie | 2021-03-28 14:48:30 -0700 |
| commit | 7a1311c16c36b18a66a5ee43511fb9ad5093ec3a (patch) | |
| tree | 09df63644ac11dee4f2de25d476437e73fcdea84 | |
| download | noncpu-7a1311c16c36b18a66a5ee43511fb9ad5093ec3a.tar.xz | |
Initial commit.
Diffstat (limited to '')
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Makefile | 16 | ||||
| -rw-r--r-- | altera/clocks.sdc | 3 | ||||
| -rw-r--r-- | altera/jtag.cdf | 12 | ||||
| -rw-r--r-- | build.bat | 7 | ||||
| -rw-r--r-- | clean.bat | 1 | ||||
| -rw-r--r-- | hdl/jtag_uart.sv | 84 | ||||
| -rw-r--r-- | hdl/top.sv | 89 | ||||
| -rw-r--r-- | hdl/util.svh | 5 | ||||
| -rw-r--r-- | init.bat | 5 | ||||
| -rw-r--r-- | mem/jtag_uart.hex | 3 | ||||
| -rw-r--r-- | mem/mem.hex | 18 | ||||
| -rw-r--r-- | olamic-run | 12 | ||||
| -rw-r--r-- | sim/main.cpp | 56 | ||||
| -rw-r--r-- | tcl/clean.tcl | 3 | ||||
| -rw-r--r-- | tcl/init.tcl | 41 |
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 @@ | |||
| 1 | SOURCES := $(shell find -name \*.sv -o -name \*.cpp) | ||
| 2 | COLLATERAL := $(shell find -name \*.hex -o -name \*.svh) | ||
| 3 | |||
| 4 | OPTS ?= | ||
| 5 | |||
| 6 | sim: build/Vtop | ||
| 7 | $< | ||
| 8 | .PHONY: sim | ||
| 9 | |||
| 10 | build/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 | |||
| 14 | clean: | ||
| 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. | ||
| 3 | create_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 @@ | |||
| 1 | JedecChain; | ||
| 2 | FileRevision(JESD32A); | ||
| 3 | DefaultMfr(6E); | ||
| 4 | |||
| 5 | P ActionCode(Ign) | ||
| 6 | Device PartName(10CL025Y) MfrSpec(OpMask(0)); | ||
| 7 | |||
| 8 | ChainEnd; | ||
| 9 | |||
| 10 | AlteraBegin; | ||
| 11 | ChainType(JTAG); | ||
| 12 | AlteraEnd; | ||
diff --git a/build.bat b/build.bat new file mode 100644 index 0000000..76cb8ff --- /dev/null +++ b/build.bat | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | if not exist noncpu.qpf ( | ||
| 2 | call init.bat | ||
| 3 | ) else ( | ||
| 4 | call clean.bat | ||
| 5 | ) | ||
| 6 | |||
| 7 | quartus_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 | |||
| 3 | module 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 | |||
| 23 | alt_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 | |||
| 41 | bit [7:0] sim_rx_rom [0:(1<<16)-1]; | ||
| 42 | initial $readmemh("mem/jtag_uart.hex", sim_rx_rom); | ||
| 43 | |||
| 44 | bit [15:0] sim_rx_addr; | ||
| 45 | |||
| 46 | bit tx_b_valid; | ||
| 47 | bit [7:0] tx_b_data; | ||
| 48 | |||
| 49 | always_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 | ||
| 80 | end | ||
| 81 | |||
| 82 | `endif | ||
| 83 | |||
| 84 | endmodule | ||
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 | |||
| 3 | module 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 | |||
| 11 | bit reset = 0; | ||
| 12 | bit have_reset = 0; | ||
| 13 | always_ff @(posedge clk) if (reset) have_reset <= 1; | ||
| 14 | assign reset = !reset_n || !have_reset; | ||
| 15 | |||
| 16 | bit [DATA_BITS-1:0] mem [0:(1<<ADDR_BITS)-1]; | ||
| 17 | initial $readmemh("mem/mem.hex", mem); | ||
| 18 | |||
| 19 | bit rx_ready; | ||
| 20 | bit rx_valid; | ||
| 21 | bit [7:0] rx_data; | ||
| 22 | |||
| 23 | bit tx_ready; | ||
| 24 | bit tx_valid; | ||
| 25 | bit [7:0] tx_data; | ||
| 26 | |||
| 27 | jtag_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 | |||
| 42 | bit [DATA_BITS-1:0] pc; | ||
| 43 | bit [3:0] opcode; | ||
| 44 | bit [7:0] operand; | ||
| 45 | bit [DATA_BITS-1:0] acc; | ||
| 46 | |||
| 47 | enum | ||
| 48 | { FETCH | ||
| 49 | , DECODE | ||
| 50 | } state; | ||
| 51 | |||
| 52 | always_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 | ||
| 87 | end | ||
| 88 | |||
| 89 | endmodule | ||
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 @@ | |||
| 1 | if exist noncpu.qpf ( | ||
| 2 | call clean.bat | ||
| 3 | ) | ||
| 4 | |||
| 5 | quartus_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 | |||
| 3 | 00 | ||
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 | |||
| 3 | 048 100 // H | ||
| 4 | 065 100 // e | ||
| 5 | 06c 100 // l | ||
| 6 | 06c 100 // l | ||
| 7 | 06f 100 // o | ||
| 8 | 02c 100 // , | ||
| 9 | 020 100 // ' ' | ||
| 10 | 077 100 // w | ||
| 11 | 06f 100 // o | ||
| 12 | 072 100 // r | ||
| 13 | 06c 100 // l | ||
| 14 | 064 100 // d | ||
| 15 | 021 100 // ! | ||
| 16 | 00a 100 // \n | ||
| 17 | |||
| 18 | 700 | ||
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 | |||
| 3 | make | ||
| 4 | |||
| 5 | if [[ $GIT_REF =~ ^refs/heads/(.+)$ ]]; then | ||
| 6 | INSTALL_DIR=/srv/olamic/artifacts/noncpu/"${BASH_REMATCH[1]}" | ||
| 7 | fi | ||
| 8 | |||
| 9 | if [[ "${INSTALL_DIR:-}" != "" ]]; then | ||
| 10 | mkdir -p "${INSTALL_DIR}" | ||
| 11 | git archive -o "${INSTALL_DIR}/noncpu.zip" @ | ||
| 12 | fi | ||
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 | |||
| 8 | int 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 @@ | |||
| 1 | project_open noncpu -revision noncpu | ||
| 2 | |||
| 3 | project_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 @@ | |||
| 1 | project_new noncpu -revision noncpu -overwrite | ||
| 2 | |||
| 3 | set_global_assignment -name DEVICE 10CL025YU256I7G | ||
| 4 | |||
| 5 | set_global_assignment -name TOP_LEVEL_ENTITY top | ||
| 6 | set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005 | ||
| 7 | set_global_assignment -name VERILOG_MACRO "SYNTHESIS=1" | ||
| 8 | |||
| 9 | proc 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 | |||
| 14 | pin E1 clk | ||
| 15 | pin J15 reset_n | ||
| 16 | |||
| 17 | # This is the clock for timing-driven synthesis, not timing analysis. | ||
| 18 | # See clocks.sdf for the other clock. | ||
| 19 | create_base_clock -fmax "50 MHz" clk | ||
| 20 | |||
| 21 | proc 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 | |||
| 27 | proc 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 | |||
| 39 | add_dir . | ||
| 40 | |||
| 41 | project_close | ||
