diff --git a/j1a/Makefile b/j1a/Makefile index 13b72be..b3c7cc7 100644 --- a/j1a/Makefile +++ b/j1a/Makefile @@ -55,4 +55,10 @@ mackextload: endif -.PHONY: connect clean bootstrap mackextload mackextunload macconnect +pcon: + $(info Use C-a C-t to toggle reset line as necessary) + $(info Use C-a C-x to exit. No shell.py features are available) + picocom -b 921600 /dev/ttyUSB1 --imap lfcrlf,crcrlf --omap delbs,crlf --send-cmd "ascii-xfr -s -l 30 -n" + + +.PHONY: connect sim_connect j4a_sim_connect clean bootstrap mackextload mackextunload macconnect linmodload pcon diff --git a/j1a/icestorm/.gitignore b/j1a/icestorm/.gitignore index 495bb6a..6546f9b 100644 --- a/j1a/icestorm/.gitignore +++ b/j1a/icestorm/.gitignore @@ -1,3 +1,4 @@ *.blif *.txt *.ex +pll.v diff --git a/j1a/icestorm/Makefile b/j1a/icestorm/Makefile index 2864872..2d5dcf4 100644 --- a/j1a/icestorm/Makefile +++ b/j1a/icestorm/Makefile @@ -1,29 +1,37 @@ -VERILOGS = j1a.v uart.v ../verilog/j1.v ../verilog/stack2.v +VERILOGS = j1a.v async_in_filter.v uart.v ../verilog/j1.v ../verilog/stack2.v -VERILOGS8k = j1a8k.v uart.v ../verilog/j1.v ../verilog/stack2.v +VERILOGS8k = j1a8k.v uart.v async_in_filter.v ../verilog/j1.v ../verilog/stack2.v -VERILOGS8k4 = j4a.v uart.v ../verilog/j1.v ../verilog/stack2.v ../verilog/j4.v ../verilog/stack2pipe4.v ../verilog/greycount.v +VERILOGS8k4 = j4a.v uart.v async_in_filter.v ../verilog/*.v SUBDIRS = .. +MHZ = 48 + all: $(SUBDIRS) j1a.bin j1a.bin: $(VERILOGS) j1a.pcf Makefile ../build/ram.v - yosys -q -p "synth_ice40 -top top -abc2 -blif j1a.blif" $(VERILOGS) + icepll -o $(MHZ) -mf pll.v + yosys -q -p "synth_ice40 -top top -abc2 -blif j1a.blif" $(VERILOGS) pll.v + rm pll.v arachne-pnr -p j1a.pcf j1a.blif -o j1a.txt #skipped:# icebox_explain j1a.txt > j1a.ex icepack j1a.txt j1a0.bin icemulti -p0 j1a0.bin > j1a.bin && rm j1a0.bin j1a8k.bin: $(VERILOGS8k) j1a8k.pcf Makefile ../build/ram.v - yosys -q -p "synth_ice40 -top top -abc2 -blif j1a8k.blif" $(VERILOGS8k) + icepll -o $(MHZ) -mf pll.v + yosys -q -p "synth_ice40 -top top -abc2 -blif j1a8k.blif" $(VERILOGS8k) pll.v + rm pll.v arachne-pnr -d 8k -p j1a8k.pcf j1a8k.blif -o j1a8k.txt #skipped:# icebox_explain j1a8k.txt > j1a8k.ex icepack j1a8k.txt j1a8k0.bin icemulti -p0 j1a8k0.bin > j1a8k.bin && rm j1a8k0.bin j4a.bin: $(VERILOGS8k4) j1a8k.pcf Makefile ../build/ram.v - yosys -q -p "synth_ice40 -top top -abc2 -blif j4a.blif" $(VERILOGS8k4) + icepll -o $(MHZ) -mf pll.v + yosys -q -p "synth_ice40 -top top -abc2 -blif j4a.blif" $(VERILOGS8k4) pll.v + rm pll.v arachne-pnr -d 8k -p j1a8k.pcf j4a.blif -o j4a.txt #skipped:# icebox_explain j4a.txt > j4a.ex icepack j4a.txt j4a0.bin @@ -38,7 +46,6 @@ j1a: j1a.bin j4a: j4a.bin sudo iceprog j4a.bin - $(SUBDIRS): $(MAKE) -C $@ @@ -46,6 +53,7 @@ clean: rm -f j1a.blif j1a.txt j1a.bin rm -f j1a8k.blif j1a8k.txt j1a8k.bin rm -f j1a.blif j4a.txt j4a.bin + rm -f pll.v .PHONY: subdirs .PHONY: subdirs $(SUBDIRS) diff --git a/j1a/icestorm/async_in_filter.v b/j1a/icestorm/async_in_filter.v new file mode 100644 index 0000000..3714ec8 --- /dev/null +++ b/j1a/icestorm/async_in_filter.v @@ -0,0 +1,46 @@ +module async_in_filter ( + input wire clk, + input wire pin, + output reg rd); +// This module is intended to accept up to a maximum 750 kHz async signal, +// and synchronise it safely to a 48 MHz clock. +// It will add at least 27 clks of latency, and may not respond reliably to a 1MHz signal. +wire onereg; +SB_IO #(.PIN_TYPE(6'b0000_00)) inpin ( + .PACKAGE_PIN(pin), + .CLOCK_ENABLE(1'b1), + .INPUT_CLK(clk), + .D_IN_0(onereg)); +reg threereg, tworeg; always @(posedge clk) {threereg,tworeg} <= {tworeg,onereg}; +// triple registering helps prevent metastability when synchronising an undefined signal into a clock domain. +parameter FILTERBITS = 5; +// Final part is somewhat of a digital moving average glitch filter, with a digital Schmidt trigger output. +// this one takes 24 ticks to set rd on. +// saturates after 31 sequential highs. +// Then will take 24 sequential lows to turn off. +// Saturating back on zero after the 31st. +reg [FILTERBITS-1:0] fltr; +wire [1:0] tops = fltr[FILTERBITS-1:FILTERBITS-2]; // top two bits are used to decide whether to change output state. +// change the two above to change the timing. +// (increase fltr size for slower signals, +// decrease for faster. should be no less than three bits.) +wire incr = ~&fltr & threereg; +wire decr = |fltr & ~threereg; +wire setr = &tops; +wire clrr = ~|tops; +always @(posedge clk) +begin + case({incr,decr}) + 10: fltr <= fltr + 1; + 01: fltr <= fltr - 1; + default: fltr <= fltr; + endcase + case({setr,clrr}) + 10: rd <= 1'b1; + 01: rd <= 1'b0; + default: rd <= rd; + endcase +end + +endmodule + diff --git a/j1a/icestorm/j1a.bin b/j1a/icestorm/j1a.bin index 0453a85..e511358 100644 Binary files a/j1a/icestorm/j1a.bin and b/j1a/icestorm/j1a.bin differ diff --git a/j1a/icestorm/j1a.v b/j1a/icestorm/j1a.v index 08a71ce..2bcc612 100644 --- a/j1a/icestorm/j1a.v +++ b/j1a/icestorm/j1a.v @@ -156,24 +156,10 @@ module top(input pclk, output D1, output D2, output D3, output D4, output D5, input resetq, ); - localparam MHZ = 12; - + wire clk; - SB_PLL40_CORE #(.FEEDBACK_PATH("SIMPLE"), - .PLLOUT_SELECT("GENCLK"), - .DIVR(4'b0000), - .DIVF(7'd3), - .DIVQ(3'b000), - .FILTER_RANGE(3'b001), - ) uut ( - .REFERENCECLK(pclk), - .PLLOUTCORE(clk), - //.PLLOUTGLOBAL(clk), - // .LOCK(D5), - .RESETB(1'b1), - .BYPASS(1'b0) - ); - + pll _icepll_generated(.clock_in(pclk), .clock_out(clk)); + wire io_rd, io_wr; wire [15:0] mem_addr; wire mem_wr; @@ -266,7 +252,7 @@ module top(input pclk, output D1, output D2, output D3, output D4, output D5, wire uart0_wr = io_wr_ & io_addr_[12]; wire uart0_rd = io_rd_ & io_addr_[12]; wire uart_RXD; - inpin _rcxd(.clk(clk), .pin(RXD), .rd(uart_RXD)); + async_in_filter _rcxd(.clk(clk), .pin(RXD), .rd(uart_RXD)); buart _uart0 ( .clk(clk), .resetq(1'b1), diff --git a/j1a/icestorm/j1a8k.bin b/j1a/icestorm/j1a8k.bin index 99b2cdc..92c4519 100644 Binary files a/j1a/icestorm/j1a8k.bin and b/j1a/icestorm/j1a8k.bin differ diff --git a/j1a/icestorm/j1a8k.v b/j1a/icestorm/j1a8k.v index a6f190c..60f0b25 100644 --- a/j1a/icestorm/j1a8k.v +++ b/j1a/icestorm/j1a8k.v @@ -308,7 +308,7 @@ module top(input pclk, wire uart0_wr = io_wr_ & io_addr_[12]; wire uart0_rd = io_rd_ & io_addr_[12]; wire uart_RXD; - inpin _rcxd(.clk(clk), .pin(RXD), .rd(uart_RXD)); + async_in_filter _rcxd(.clk(clk), .pin(RXD), .rd(uart_RXD)); buart _uart0 ( .clk(clk), .resetq(1'b1), diff --git a/j1a/icestorm/j4a.bin b/j1a/icestorm/j4a.bin index 91e56da..7bd900d 100644 Binary files a/j1a/icestorm/j4a.bin and b/j1a/icestorm/j4a.bin differ diff --git a/j1a/icestorm/j4a.v b/j1a/icestorm/j4a.v index 1483c63..e215b2e 100644 --- a/j1a/icestorm/j4a.v +++ b/j1a/icestorm/j4a.v @@ -164,58 +164,16 @@ module top(input pclk, input reset ); - localparam MHZ = 12; -/* - wire clk, pll_lock; - - wire pll_reset; - assign pll_reset = !reset; - wire resetq; // note port changed, .pcf needs update too. - assign resetq = reset & !pll_lock; - - SB_PLL40_CORE #(.FEEDBACK_PATH("PHASE_AND_DELAY"), - .DELAY_ADJUSTMENT_MODE_FEEDBACK("FIXED"), - .DELAY_ADJUSTMENT_MODE_RELATIVE("FIXED"), - .PLLOUT_SELECT("SHIFTREG_0deg"), - .SHIFTREG_DIV_MODE(1'b0), - .FDA_FEEDBACK(4'b0000), - .FDA_RELATIVE(4'b0000), - .DIVR(4'b1111), - .DIVF(7'b0110001), - .DIVQ(3'b011), // 1..6 - .FILTER_RANGE(3'b001), - ) uut ( - .REFERENCECLK(pclk), - //.PLLOUTCORE(clk), - .PLLOUTGLOBAL(clk), - .LOCK(pll_lock), - .RESETB(pll_reset), - .BYPASS(1'b0) - ); // 37.5 MHz, fout = [ fin * (DIVF+1) ] / [ DIVR+1 ], fout must be 16 ..275MHz, fVCO from 533..1066 MHz (!! we're 600 here I think), and phase detector / input clock from 10 .. 133 MH (ok, we're 75 because DIVQ divides by 2^DIVQ, but doesn't affect output otherwise, and input is 12 MHz) - // for some reason this crashes arachne-pnr now. - - */ wire clk; - wire resetq; - // assign resetq = reset; // now passed through PLL to keep design in reset until lock. note active low resets. - - SB_PLL40_CORE #(.FEEDBACK_PATH("SIMPLE"), - .PLLOUT_SELECT("GENCLK"), - .DIVR(4'b0000), - .DIVF(7'd3), - .DIVQ(3'b000), - .FILTER_RANGE(3'b001), - ) uut ( - .REFERENCECLK(pclk), - .PLLOUTCORE(clk), - //.PLLOUTGLOBAL(clk), - .LOCK(resetq), - .RESETB(reset), - .BYPASS(1'b0) - ); + wire uresetq; + + pll _icepll_generated(.clock_in(pclk), .clock_out(clk), .locked(uresetq)); + + reg [2:0] resets; always @(posedge clk) resets <= {resets[1:0],reset}; + + reg [1:0] syncreset; reg resetq; always @(posedge clk) {resetq, syncreset} <= {syncreset,uresetq&resets[2]}; - wire io_rd, io_wr; wire [15:0] mem_addr; wire mem_wr; @@ -337,7 +295,7 @@ module top(input pclk, wire uart0_wr = io_wr_ & io_addr_[12]; wire uart0_rd = io_rd_ & io_addr_[12]; wire uart_RXD; - inpin _rcxd(.clk(clk), .pin(RXD), .rd(uart_RXD)); + async_in_filter _rcxd(.clk(clk), .pin(RXD), .rd(uart_RXD)); buart _uart0 ( .clk(clk), .resetq(1'b1), diff --git a/j1a/icestorm/uart.v b/j1a/icestorm/uart.v index 5c521b3..9621b36 100644 --- a/j1a/icestorm/uart.v +++ b/j1a/icestorm/uart.v @@ -1,7 +1,7 @@ `default_nettype none -`define CLKFREQ 12000000 // frequency of incoming signal 'clk' -`define BAUD 115200 +`define CLKFREQ 48000000 // frequency of incoming signal 'clk' +`define BAUD 921600 // Simple baud generator for transmitter // ser_clk pulses at 115200 Hz diff --git a/j1a/shell.py b/j1a/shell.py index 97e6576..b809d63 100644 --- a/j1a/shell.py +++ b/j1a/shell.py @@ -18,7 +18,7 @@ def open_ser(self, port, speed): except: print("This tool needs PySerial, but it was not found") sys.exit(1) - self.ser = serial.Serial(port, 4 * 115200, timeout=None, rtscts=0) + self.ser = serial.Serial(port, 921600, timeout=None, rtscts=0) def reset(self, fullreset = True): ser = self.ser