Skip to content

Commit 35bb1b1

Browse files
committed
adds new buart, works at 921600
1 parent 60872cd commit 35bb1b1

File tree

9 files changed

+90
-15
lines changed

9 files changed

+90
-15
lines changed

j1a/Makefile

+7-1
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,10 @@ mackextload:
5555

5656
endif
5757

58-
.PHONY: connect clean bootstrap mackextload mackextunload macconnect
58+
pcon:
59+
$(info Use C-a C-t to toggle reset line as necessary)
60+
$(info Use C-a C-x to exit. No shell.py features are available)
61+
picocom -b 921600 /dev/ttyUSB1 --imap lfcrlf,crcrlf --omap delbs,crlf --send-cmd "ascii-xfr -s -l 30 -n"
62+
63+
64+
.PHONY: connect sim_connect j4a_sim_connect clean bootstrap mackextload mackextunload macconnect linmodload pcon

j1a/icestorm/Makefile

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
VERILOGS = j1a.v uart.v ../verilog/j1.v ../verilog/stack2.v
1+
VERILOGS = j1a.v ../verilog/async_in_filter.v uart3.v ../verilog/j1.v ../verilog/stack2.v
22

3-
VERILOGS8k = j1a8k.v uart.v ../verilog/j1.v ../verilog/stack2.v
3+
VERILOGS8k = j1a8k.v uart3.v ../verilog/async_in_filter.v ../verilog/j1.v ../verilog/stack2.v
44

5-
VERILOGS8k4 = j4a.v uart.v ../verilog/j1.v ../verilog/stack2.v ../verilog/j4.v ../verilog/stack2pipe4.v ../verilog/greycount.v
5+
VERILOGS8k4 = j4a.v uart3.v ../verilog/*.v
66

77
SUBDIRS = ..
88

j1a/icestorm/j1a.v

+2-2
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,8 @@ module top(input pclk, output D1, output D2, output D3, output D4, output D5,
266266
wire uart0_wr = io_wr_ & io_addr_[12];
267267
wire uart0_rd = io_rd_ & io_addr_[12];
268268
wire uart_RXD;
269-
inpin _rcxd(.clk(clk), .pin(RXD), .rd(uart_RXD));
270-
buart _uart0 (
269+
async_in_filter _rcxd(.clk(clk), .pin(RXD), .rd(uart_RXD));
270+
buart #(.BAUD(921600)) _uart0 (
271271
.clk(clk),
272272
.resetq(1'b1),
273273
.rx(uart_RXD),

j1a/icestorm/j1a8k.v

+2-2
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,8 @@ module top(input pclk,
308308
wire uart0_wr = io_wr_ & io_addr_[12];
309309
wire uart0_rd = io_rd_ & io_addr_[12];
310310
wire uart_RXD;
311-
inpin _rcxd(.clk(clk), .pin(RXD), .rd(uart_RXD));
312-
buart _uart0 (
311+
async_in_filter _rcxd(.clk(clk), .pin(RXD), .rd(uart_RXD));
312+
buart #(.BAUD(921600)) _uart0 (
313313
.clk(clk),
314314
.resetq(1'b1),
315315
.rx(uart_RXD),

j1a/icestorm/j4a.bin

-96 Bytes
Binary file not shown.

j1a/icestorm/j4a.v

+1-1
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ module top(input pclk,
338338
wire uart0_rd = io_rd_ & io_addr_[12];
339339
wire uart_RXD;
340340
async_in_filter _rcxd(.clk(clk), .pin(RXD), .rd(uart_RXD));
341-
buart #(.CLOCK_DIVIDE(313)) _uart0 (
341+
buart #(.BAUD(921600)) _uart0 (
342342
.clk(clk),
343343
.resetq(1'b1),
344344
.rx(uart_RXD),

j1a/icestorm/uart3.v

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
`default_nettype none
2+
3+
module buart(
4+
input clk, // The master clock for this module
5+
input resetq, // Synchronous reset, active low
6+
input rx, // Incoming serial line
7+
output tx, // Outgoing serial line
8+
input rd, // read strobe -- used only to clear valid flag.
9+
input wr, // write strobe
10+
output reg valid, // Indicates a new byte is available. clears on read.
11+
output reg busy, // Low when transmit line is idle.
12+
input [7:0] tx_data, // Byte to transmit
13+
output reg [7:0] rx_data, // *Most recent* byte received -- whether or not the last was collected.
14+
output reg error // reception error
15+
);
16+
// you can override these on a per-port basis, looks like:
17+
// buart #(.BAUD(115200)) _youruart (.clk(clk)...etc);
18+
// or
19+
// buart #(.CLOCK_DIVIDE(312)) _uart1 (...
20+
// The latter might be better for designs with non-48MHz clocks.
21+
parameter BAUD = 9600;
22+
parameter CLKFREQ = 48000000; // frequency of incoming signal 'clk'
23+
parameter CLOCK_DIVIDE = (CLKFREQ / (BAUD * 4)); // clock rate (48Mhz) / (baud rate (460800) * 4)
24+
// will probably want to support at least down to 9600 baud, which will require a CLOCK_DIVIDE == 1250
25+
26+
localparam CDSIZE = $clog2(CLOCK_DIVIDE)+1; // one more to accomodate assumed signed arithmatic
27+
reg [5:0] bytephase;
28+
reg [CDSIZE-1:0] rxclkcounter;
29+
wire rxqtick = rxclkcounter == CLOCK_DIVIDE; // strobes high one clk every 1/4 bit time
30+
wire rxrst = rx & (~|bytephase); // rx goes low with the beginning of the start bit. synchronous to system clk, not sample clk.
31+
always @(posedge clk) rxclkcounter <= rxrst | rxqtick ? 1 : rxclkcounter + 1; // initially held in reset
32+
// very important: idle rx line holds rxrst asserted,
33+
// this goes on *until* the start edge is found.
34+
// thus synchronising further sampling to that edge, rather than remaining in phase with however it was reset.
35+
36+
wire rxstop = bytephase == 6'd40; // 11th sample 'tick' would have been at 42.
37+
wire nonstarter;
38+
always @(posedge clk) bytephase <= rxstop|nonstarter ? 0 : rxqtick ? bytephase + 1 : bytephase;
39+
wire sample = (bytephase[1:0] == 2'b10) & rxqtick; // one clk for each of ten bits
40+
// note sample is false while rxrst is true.
41+
assign nonstarter = (bytephase == 6'd2) & rx; // start bit should still be low when sample strobes first.
42+
// if it isn't, then it will go back to a rxrst state.
43+
44+
// after this point, we have a sample strobe, a rxstop strobe
45+
reg [9:0] capture; always @(posedge clk) capture <= sample ? {rx, capture[9:1]} : capture;
46+
// note bits are sent least-significant first.
47+
wire startbit = capture[0]; // valid when rxstop strobes, and until rxrst releases for the next byte.
48+
wire stopbit = capture[9];
49+
wire good = stopbit&~startbit; // valid when rxstop is asserted. stop bit should be 1, start bit should have been zero.
50+
always @(posedge clk)
51+
begin
52+
valid <= rd ? 1'b0 : rxstop & good ? 1'b1 : valid;
53+
rx_data <= rxstop & good ? capture[8:1] : rx_data;
54+
error <= nonstarter ? 1'b1 : rxstop ? ~good : error ;
55+
end
56+
// tx parts
57+
reg [CDSIZE+1:0] txclkcounter; // note, two extra bits to accomodate a limit 4x as large.
58+
wire txtick = txclkcounter == 4*CLOCK_DIVIDE; // ticks for a clk once every bit, not every quarter bit.
59+
always @(posedge clk) txclkcounter <= txtick ? 1 : txclkcounter + 1;
60+
// note txclkcounter never needs to be reset out-of-phase with itself.
61+
reg [3:0] sentbits;
62+
wire done = sentbits == 4'd10; // eventually stays 'done'. Reset to zero again when wr strobes.
63+
always @(posedge clk) sentbits <= txtick & ~done ? sentbits + 1 : wr ? 4'd0 : sentbits ;
64+
reg [9:0] sender;
65+
// wr strobe might come any clk, not synchronous to txtick. No real need to force txtick to be synchronous to it either.
66+
always @(posedge clk) sender <= wr ? {tx_data, 1'b0, 1'b1} : txtick ? {1'b1, sender[9:1]} : sender;
67+
assign tx = sender[0]; // wr loads this 1, because tranmission doesn't start until the next txtick, whenever it arrives.
68+
assign busy = ~done;
69+
endmodule

j1a/shell.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def open_ser(self, port, speed):
1818
except:
1919
print("This tool needs PySerial, but it was not found")
2020
sys.exit(1)
21-
self.ser = serial.Serial(port, 4 * 115200, timeout=None, rtscts=0)
21+
self.ser = serial.Serial(port, 921600, timeout=None, rtscts=0)
2222

2323
def reset(self, fullreset = True):
2424
ser = self.ser

j1a/verilog/async_in_filter.v

+5-5
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,16 @@ wire [1:0] tops = fltr[4:3]; // top two bits are used to decide whether to chang
2424
// change the two above to change the timing.
2525
// (increase fltr size for slower signals,
2626
// decrease for faster. should be no less than three bits.)
27-
wire incr = ~&flrt & threereg;
28-
wire decr = |flrt & ~threereg;
27+
wire incr = ~&fltr & threereg;
28+
wire decr = |fltr & ~threereg;
2929
wire setr = &tops;
3030
wire clrr = ~tops[1] & ~tops[0];
3131
always @(posedge clk)
3232
begin
3333
case({incr,decr})
34-
10: flrt <= flrt + 1;
35-
01: flrt <= flrt - 1;
36-
default: flrt <= flrt;
34+
10: fltr <= fltr + 1;
35+
01: fltr <= fltr - 1;
36+
default: fltr <= fltr;
3737
endcase
3838
case({setr,clrr})
3939
10: rd <= 1'b1;

0 commit comments

Comments
 (0)