Skip to content

Commit 84922e8

Browse files
committed
ol2/tt_autosel: add tt_autosel macro
allows selecting a design automatically by reading its the selected design id from an external I2C EEPROM
1 parent a4053e7 commit 84922e8

File tree

14 files changed

+1559
-5
lines changed

14 files changed

+1559
-5
lines changed

ol2/tt_autosel/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fpga/impl
2+
runs
3+
failures_report.json

ol2/tt_autosel/config.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"DESIGN_NAME": "tt_autosel",
3+
"VERILOG_FILES": ["dir::tt_autosel.v", "dir::i2c_eeprom.v", "dir::i2c_master.v"],
4+
"FP_SIZING": "absolute",
5+
"DIE_AREA": "0 0 250 80",
6+
7+
"FP_IO_HLENGTH": 2,
8+
"FP_IO_VLENGTH": 2,
9+
10+
"//": "use alternative efabless decap cells to solve LI density issue",
11+
"DECAP_CELL": "sky130_fd_sc_hd__decap_3 sky130_fd_sc_hd__decap_4 sky130_fd_sc_hd__decap_6 sky130_fd_sc_hd__decap_8 sky130_ef_sc_hd__decap_12",
12+
13+
"//": "period is in ns, so 20ns == 50mHz",
14+
"CLOCK_PERIOD": 20,
15+
"CLOCK_PORT": "clk",
16+
17+
"//": "don't use power rings or met5",
18+
"DESIGN_IS_CORE": false,
19+
"RT_MAX_LAYER": "met4",
20+
21+
"//": "make the PDN denser",
22+
"FP_PDN_VOFFSET": 20.355,
23+
"FP_PDN_VPITCH": 40.710,
24+
25+
"//": "save some time",
26+
"RUN_KLAYOUT_XOR": false,
27+
28+
"//": "reduce wasted space",
29+
"TOP_MARGIN_MULT": 1,
30+
"BOTTOM_MARGIN_MULT": 1,
31+
"LEFT_MARGIN_MULT": 8,
32+
"RIGHT_MARGIN_MULT": 8
33+
}

ol2/tt_autosel/fpga/Makefile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
SOURCE_FILES = project.v uart_tx.v ../i2c_master.v ../i2c_eeprom.v ../tt_autosel.v
2+
TARGET = impl/pnr/project.fs
3+
GW_SH = $(GOWIN_HOME)/IDE/bin/gw_sh
4+
5+
$(TARGET): $(SOURCE_FILES)
6+
$(GW_SH) project.tcl
7+
8+
.PHONY: all
9+
all: $(TARGET)
10+
11+
.PHONY: sram
12+
sram: $(TARGET)
13+
openFPGALoader $(TARGET)
14+
15+
.PHONY: flash
16+
flash: $(TARGET)
17+
openFPGALoader -f $(TARGET)
18+
19+
.PHONY: clean
20+
clean:
21+
rm -rf impl

ol2/tt_autosel/fpga/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Tang Nano 20K Testbench
2+
3+
FPGA Board: [Tang Nano 20K](https://wiki.sipeed.com/hardware/en/tang/tang-nano-20k/nano-20k.html).
4+
5+
You need to connect a 1 kbit or 2 kbit I2C EEPROM (e.g. 24C01 or 24C02), program the selected design id into the first two bytes of the EEPROM memory, and connect the EEPROM to the Tang Nano 20K board. After connecting the EEPROM, press the reset button (S1), and observe the ctrl output pins to see if the design id is correctly read from the EEPROM:
6+
7+
- `ctrl_sel_rst_n` should go low, and then high
8+
- `ctrl_sel_inc` should pulse high according to the lowest 10 bits of the number stored in the EEPROM
9+
- `ctrl_ena` should go high
10+
11+
## Pinout
12+
13+
| Tang Nano 20K | Function |
14+
|---------------|----------------|
15+
| 74 | SDA |
16+
| 77 | SCL |
17+
| 27 | ctrl_sel_rst_n |
18+
| 28 | ctrl_sel_inc |
19+
| 25 | ctrl_ena |
20+
21+
## Debug interface
22+
23+
The test project also implements a UART debug interface (115200 baud, connected through the BL616). The debug interface will print the two bytes read from the EEPROM as a 16-bit hex number (big endian) once per second.

ol2/tt_autosel/fpga/project.cst

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Clock & Reset
2+
IO_LOC "clk" 4;
3+
IO_PORT "clk" PULL_MODE=UP BANK_VCCIO=1.8;
4+
IO_LOC "rst" 88;
5+
IO_PORT "rst" IO_TYPE=LVCMOS33 PULL_MODE=UP;
6+
7+
# Debug
8+
IO_LOC "led" 15;
9+
IO_PORT "led" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8;
10+
IO_LOC "uart_tx" 69;
11+
IO_PORT "uart_tx" IO_TYPE=LVCMOS33;
12+
13+
# I2C
14+
IO_LOC "i2c_sda" 74;
15+
IO_PORT "i2c_sda" IO_TYPE=LVCMOS33 PULL_MODE=UP;
16+
IO_LOC "i2c_scl" 77;
17+
IO_PORT "i2c_scl" IO_TYPE=LVCMOS33 PULL_MODE=UP;
18+
19+
# Mux controller
20+
IO_LOC "ctrl_sel_rst_n" 27;
21+
IO_PORT "ctrl_sel_rst_n" IO_TYPE=LVCMOS33;
22+
IO_LOC "ctrl_sel_inc" 28;
23+
IO_PORT "ctrl_sel_inc" IO_TYPE=LVCMOS33;
24+
IO_LOC "ctrl_ena" 25;
25+
IO_PORT "ctrl_ena" IO_TYPE=LVCMOS33;

ol2/tt_autosel/fpga/project.sdc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
create_clock -name clk -period 37.037 -waveform {0 18.518} [get_ports {clk}]

ol2/tt_autosel/fpga/project.tcl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
add_file -type verilog project.v
2+
add_file -type verilog ../i2c_master.v
3+
add_file -type verilog ../i2c_eeprom.v
4+
add_file -type verilog ../tt_autosel.v
5+
add_file -type verilog uart_tx.v
6+
add_file -type cst project.cst
7+
add_file -type sdc project.sdc
8+
set_device GW2AR-LV18QN88C8/I7
9+
set_option -synthesis_tool gowinsynthesis
10+
set_option -output_base_name project
11+
set_option -verilog_std sysv2017
12+
set_option -top_module fpga_top
13+
run all

ol2/tt_autosel/fpga/project.v

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
`default_nettype none
2+
3+
// Enables the eeprom_data debug output of tt_autosel:
4+
`define DEBUG_AUTOSEL
5+
6+
module fpga_top (
7+
input wire clk,
8+
input wire rst,
9+
output reg led,
10+
output wire uart_tx,
11+
inout wire i2c_scl,
12+
inout wire i2c_sda,
13+
output wire ctrl_sel_rst_n,
14+
output wire ctrl_sel_inc,
15+
output wire ctrl_ena
16+
);
17+
18+
parameter CLK_FREQ = 27; // Mhz
19+
parameter UART_BAUD = 115200; // Khz
20+
21+
reg [31:0] counter = 0;
22+
23+
wire scl_i;
24+
wire scl_o;
25+
wire scl_oe_n;
26+
27+
IOBUF scl_buf (
28+
.O (scl_i),
29+
.IO (i2c_scl),
30+
.I (scl_o),
31+
.OEN(scl_oe_n)
32+
);
33+
34+
wire sda_i;
35+
wire sda_o;
36+
wire sda_oe_n;
37+
38+
IOBUF sda_buf (
39+
.O (sda_i),
40+
.IO (i2c_sda),
41+
.I (sda_o),
42+
.OEN(sda_oe_n)
43+
);
44+
45+
// --
46+
47+
wire [15:0] eeprom_data;
48+
49+
tt_autosel autosel (
50+
.clk (clk),
51+
.rst_n(rst_n),
52+
53+
.eeprom_data(eeprom_data),
54+
55+
// I2C master interface
56+
.scl_i(scl_i),
57+
.sda_i(sda_i),
58+
.scl_o(scl_o),
59+
.scl_oe_n(scl_oe_n),
60+
.sda_o(sda_o),
61+
.sda_oe_n(sda_oe_n),
62+
63+
// Mux ctrl interface
64+
.ctrl_sel_rst_n(ctrl_sel_rst_n),
65+
.ctrl_sel_inc(ctrl_sel_inc),
66+
.ctrl_ena(ctrl_ena)
67+
);
68+
69+
// --
70+
71+
wire rst_n = ~rst;
72+
wire tx_ready;
73+
reg [7:0] tx_byte;
74+
reg tx_valid;
75+
76+
uart_tx #(
77+
.CLK_FRE (CLK_FREQ),
78+
.BAUD_RATE(UART_BAUD)
79+
) uart_tx_inst (
80+
.clk(clk),
81+
.rst_n(rst_n),
82+
.tx_pin(uart_tx),
83+
.tx_data(tx_byte),
84+
.tx_data_valid(tx_valid),
85+
.tx_data_ready(tx_ready)
86+
);
87+
88+
reg [2:0] send_index = 0;
89+
90+
function [7:0] hexchar(input [3:0] value);
91+
case (value)
92+
0: hexchar = "0";
93+
1: hexchar = "1";
94+
2: hexchar = "2";
95+
3: hexchar = "3";
96+
4: hexchar = "4";
97+
5: hexchar = "5";
98+
6: hexchar = "6";
99+
7: hexchar = "7";
100+
8: hexchar = "8";
101+
9: hexchar = "9";
102+
10: hexchar = "A";
103+
11: hexchar = "B";
104+
12: hexchar = "C";
105+
13: hexchar = "D";
106+
14: hexchar = "E";
107+
15: hexchar = "F";
108+
endcase
109+
endfunction
110+
111+
/* Send a byte every 1 second */
112+
always @(posedge clk) begin
113+
if (counter == 27000000) begin
114+
send_index <= 0;
115+
end else if (tx_ready) begin
116+
case (send_index)
117+
0: tx_byte <= hexchar(eeprom_data[15:12]);
118+
1: tx_byte <= hexchar(eeprom_data[11:8]);
119+
2: tx_byte <= hexchar(eeprom_data[7:4]);
120+
3: tx_byte <= hexchar(eeprom_data[3:0]);
121+
4: tx_byte <= 13; // CR
122+
5: tx_byte <= 10; // LF
123+
endcase
124+
if (send_index < 6) begin
125+
tx_valid <= 1;
126+
send_index <= send_index + 1;
127+
end else begin
128+
tx_valid <= 0;
129+
end
130+
end
131+
end
132+
133+
always @(posedge clk) begin
134+
counter <= counter + 1;
135+
if (counter == 27000000) begin
136+
counter <= 0;
137+
led <= ~led;
138+
end
139+
end
140+
141+
endmodule

0 commit comments

Comments
 (0)