From 6e39b7c16fbad9ddffc0f4eacd1799ca1b995492 Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Wed, 16 Feb 2022 12:41:28 -0800 Subject: Initial commit. --- .gitignore | 3 + Makefile | 33 ++++++++++ altera/clocks.sdc | 3 + altera/jtag.cdf | 12 ++++ hdl/top.sv | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tcl/clean.tcl | 3 + tcl/init.tcl | 104 +++++++++++++++++++++++++++++ 7 files changed, 351 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 altera/clocks.sdc create mode 100644 altera/jtag.cdf create mode 100644 hdl/top.sv create mode 100644 tcl/clean.tcl create mode 100644 tcl/init.tcl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..44c81fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/db +/incremental_db +/memctrl.* diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..3467cfb --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +SOURCES := $(wildcard hdl/**.sv) +QUARTUS := $(shell find altera tcl -name \*.cdf -o -name \*.sdc -o -name \*.tcl) + +fpga: memctrl.sof + quartus_pgm -c 1 -m JTAG -o "P;$<@1" + nios2-terminal +.PHONY: fpga + +build/p8bin2hex: tool/p8bin2hex.c + @mkdir -p build + gcc -Wall -Werror -o $@ $< + +build/%.hex: build/%.bin build/p8bin2hex + build/p8bin2hex $< > $@ + +build/%.hex: %.bin build/p8bin2hex + build/p8bin2hex $< > $@ + +build/%.bin: %.pal + @mkdir -p $(dir $@) + palbart $< + mv -f $*.bin $*.lst $(dir $@) + +memctrl.sof: $(SOURCES) $(QUARTUS) + [ ! -e memctrl.qpf ] || quartus_sh -t tcl/clean.tcl + quartus_sh -t tcl/init.tcl + quartus_sh --flow compile memctrl.qpf + +clean: + git clean -dfX +.PHONY: clean + +.SECONDARY: diff --git a/altera/clocks.sdc b/altera/clocks.sdc new file mode 100644 index 0000000..c08f897 --- /dev/null +++ b/altera/clocks.sdc @@ -0,0 +1,3 @@ +# This is the clock for timing analysis, not timing-driven synthesis. +# See init.tcl for the other clock. +create_clock -period "50 MHz" clock 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 @@ +JedecChain; + FileRevision(JESD32A); + DefaultMfr(6E); + + P ActionCode(Ign) + Device PartName(10CL025Y) MfrSpec(OpMask(0)); + +ChainEnd; + +AlteraBegin; + ChainType(JTAG); +AlteraEnd; diff --git a/hdl/top.sv b/hdl/top.sv new file mode 100644 index 0000000..babdc95 --- /dev/null +++ b/hdl/top.sv @@ -0,0 +1,193 @@ +module top + ( input bit clock + , input bit resetn + + , output bit ramresetn + , output bit [1:0] ramcsn + , output bit ramclkp + , output bit ramclkn + , input bit ramrwds + , inout bit [7:0] ramdata + ); + +assign ramresetn = resetn; +assign ramclkn = !ramclkp; + +bit ram_data_oe; +bit [7:0] ram_send_data; + +assign ramdata = ram_data_oe ? ram_send_data : 8'bZ; + +bit rx_ready; +bit rx_valid; +bit [7:0] rx_data; + +bit tx_ready; +bit tx_valid; +bit [7:0] tx_data; + +alt_jtag_atlantic + #( .INSTANCE_ID(0) + , .LOG2_RXFIFO_DEPTH(6) + , .LOG2_TXFIFO_DEPTH(6) + , .SLD_AUTO_INSTANCE_INDEX("NO") + ) jtag + ( .clk(clock) + , .rst_n(resetn) + , .r_dat(tx_data) + , .r_val(tx_valid) + , .r_ena(tx_ready) + , .t_dat(rx_data) + , .t_dav(rx_ready) + , .t_ena(rx_valid) + ); + +bit input_byte_valid; +bit [7:0] input_byte; + +bit [22:0] address; +bit [7:0] data; +bit write; + +bit [47:0] command; + +enum + { UART_READ_ADDRESS_OR_COMMAND + , UART_READ_DATA_1 + , UART_READ_DATA_0 + , RAM_WAIT_READY + , RAM_SEND_COMMAND_5 + , RAM_SEND_COMMAND_4 + , RAM_SEND_COMMAND_3 + , RAM_SEND_COMMAND_2 + , RAM_SEND_COMMAND_1 + , RAM_SEND_COMMAND_0 + , RAM_INIT_WAIT_DATA + , RAM_WAIT_DATA + , RAM_SENDRECV_DATA + , UART_WRITE_DATA_1 + , UART_WRITE_DATA_0 + } state; + +always @(posedge clock) begin + if (!resetn) begin + ramcsn[0] = 1; + ramcsn[1] = 1; + ramclkp = 0; + ram_data_oe = 0; + rx_ready = 0; + tx_valid = 0; + input_byte_valid = 0; + address = 0; + state = state.first; + end else begin + if (tx_ready) tx_valid = 0; + if (rx_valid && !input_byte_valid && !tx_valid) begin + tx_valid = 1; + tx_data = rx_data; + input_byte_valid = 1; + input_byte = rx_data; + end + case (state) + UART_READ_ADDRESS_OR_COMMAND: + if (input_byte_valid) begin + if (input_byte >= "0" && input_byte <= "9") begin + address = address << 4; + address[3:0] = input_byte - "0"; + end else if (input_byte >= "a" && input_byte <= "f") begin + address = address << 4; + address[3:0] = input_byte - "a" + 10; + end else if (input_byte >= "A" && input_byte <= "F") begin + address = address << 4; + address[3:0] = input_byte - "A" + 10; + end else if (input_byte == "?") begin + write = 0; + command = {12'b100000000000, address[22:3], 13'b0, address[2:0]}; + address = 0; + data = 0; + state = RAM_SEND_COMMAND_5; + end else if (input_byte == "=") begin + write = 1; + command = {12'b000000000000, address[22:3], 13'b0, address[2:0]}; + address = 0; + data = 0; + state = UART_READ_DATA_1; + end + input_byte_valid = 0; + end + UART_READ_DATA_1, UART_READ_DATA_0: + if (input_byte_valid) begin + if (input_byte >= "0" && input_byte <= "9") begin + data = data << 4; + data[3:0] = input_byte - "0"; + state = state.next; + end else if (input_byte >= "a" && input_byte <= "f") begin + data = data << 4; + data[3:0] = input_byte - "a" + 10; + state = state.next; + end else if (input_byte >= "A" && input_byte <= "F") begin + data = data << 4; + data[3:0] = input_byte - "A" + 10; + state = state.next; + end + input_byte_valid = 0; + end + RAM_WAIT_READY: + begin + ramcsn[0] = 0; + if (ramrwds) state = state.next; + end + RAM_SEND_COMMAND_5, RAM_SEND_COMMAND_4, RAM_SEND_COMMAND_3, RAM_SEND_COMMAND_2, RAM_SEND_COMMAND_1, RAM_SEND_COMMAND_0: + begin + ramclkp = ~ramclkp; + ram_data_oe = 1; + ram_send_data = command[47:40]; + command = command << 8; + state = state.next; + end + RAM_INIT_WAIT_DATA: + begin + ramclkp = ~ramclkp; + ram_data_oe = 0; + state = state.next; + end + RAM_WAIT_DATA: + begin + ramclkp = ~ramclkp; + if (ramrwds) begin + if (write) begin + ram_data_oe = 1; + ram_send_data = data; + end + state = state.next; + end + end + RAM_SENDRECV_DATA: + begin + ramclkp = ~ramclkp; + ramcsn[0] = 1; + ram_data_oe = 0; + if (write) begin + state = state.first; + end else begin + data = ramdata; + state = UART_WRITE_DATA_1; + end + end + UART_WRITE_DATA_1, UART_WRITE_DATA_0: + if (!tx_valid) begin + tx_valid = 1; + if (data[7:4] < 10) begin + tx_data = data[7:4] + "0"; + end else begin + tx_data = data[7:4] + "A" - 10; + end + data = data << 4; + state = state.next; + end + endcase + rx_ready = !input_byte_valid && !tx_valid; + end +end + +endmodule diff --git a/tcl/clean.tcl b/tcl/clean.tcl new file mode 100644 index 0000000..17de924 --- /dev/null +++ b/tcl/clean.tcl @@ -0,0 +1,3 @@ +project_open memctrl -revision memctrl + +project_clean -revision memctrl diff --git a/tcl/init.tcl b/tcl/init.tcl new file mode 100644 index 0000000..13c08ec --- /dev/null +++ b/tcl/init.tcl @@ -0,0 +1,104 @@ +project_new memctrl -revision memctrl -overwrite + +set_global_assignment -name DEVICE 10CL025YU256I7G + +set_global_assignment -name TOP_LEVEL_ENTITY top +set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2005 +set_global_assignment -name VERILOG_MACRO "SYNTHESIS=1" + +proc pin {net loc} { + set_location_assignment -to $net "PIN_$loc" + set_instance_assignment -name IO_STANDARD "3.3V LVTTL" -to $net +} + +proc iopin {net loc} { + pin $net $loc + set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to $net +} + +proc rampin {net loc} { + set_location_assignment -to $net "PIN_$loc" + set_instance_assignment -name IO_STANDARD "1.8V" -to $net +} + +pin clock E1 + +iopin resetn J15 + +iopin gpioa[1] L13 +iopin gpioa[2] L16 +iopin gpioa[3] L15 +iopin gpioa[4] K16 +iopin gpioa[5] P16 +iopin gpioa[6] R16 +iopin gpioa[7] N16 +iopin gpioa[8] N15 +iopin gpioa[9] N14 +iopin gpioa[10] P15 +iopin gpiob[13] N8 +iopin gpiob[14] P8 +iopin gpiob[15] M8 +iopin gpiob[16] L8 +iopin gpiob[17] R7 +iopin gpiob[18] T7 +iopin gpiob[19] L7 +iopin gpiob[20] M7 +iopin gpiob[21] R6 +iopin gpiob[22] T6 +iopin gpiob[23] T2 +iopin gpiob[24] M6 +iopin gpiob[25] R5 +iopin gpiob[26] T5 +iopin gpiob[27] N5 +iopin gpiob[28] N6 +iopin gpioc[31] R4 +iopin gpioc[32] T4 +iopin gpioc[33] N3 +iopin gpioc[34] P3 +iopin gpioc[35] R3 +iopin gpioc[36] T3 +iopin gpioc[37] P6 +iopin gpioc[38] P2 +iopin gpioc[39] P1 +iopin gpioc[40] R1 + +rampin ramdata[0] T12 +rampin ramdata[1] T13 +rampin ramdata[2] T11 +rampin ramdata[3] R10 +rampin ramdata[4] T10 +rampin ramdata[5] R11 +rampin ramdata[6] R12 +rampin ramdata[7] R13 +rampin ramcsn[0] N12 +rampin ramcsn[1] P9 +rampin ramrwds T14 +rampin ramclkp P14 +rampin ramclkn R14 +rampin ramresetn N9 + +# This is the clock for timing-driven synthesis, not timing analysis. +# See clocks.sdf for the other clock. +create_base_clock -fmax "50 MHz" clk + +proc add_files {typ ext dir} { + foreach name [glob -nocomplain -directory $dir -type f "*.$ext"] { + set_global_assignment -name "${typ}_FILE" $name + } +} + +proc add_dir {dir} { + add_files CDF cdf $dir + add_files HEX hex $dir + add_files SDC sdc $dir + add_files VERILOG sv $dir + add_files VERILOG svh $dir + + foreach subdir [glob -nocomplain -directory $dir -type d *] { + add_dir $subdir + } +} + +add_dir . + +project_close -- cgit v1.2.3