Skip to content

Commit fba3c86

Browse files
Implement support for async fifo that doesnt use manufacturer ip, thanks Alex
1 parent 8e3798b commit fba3c86

File tree

4 files changed

+287
-23
lines changed

4 files changed

+287
-23
lines changed

examples/async_clock_crossing.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
// Similar to clock_crossing.c except that instead of
22
// data width integer ratioed clock crossing stream,
33
// this uses same size read and write ports on an async fifo
4-
4+
//#pragma PART "xc7a35ticsg324-1l" // Artix 7 35T (Arty)
5+
#pragma PART "LFE5U-85F-6BG381C"
56
#include "uintN_t.h"
67
#include "leds/led0_3_ports.c"
78

8-
#pragma MAIN_MHZ fast 166.66
9+
#pragma MAIN_MHZ fast 40.0
910
#pragma MAIN_MHZ slow 25.0
1011

1112
// Write+read 2 'datas' in/out the fifo at a time
@@ -28,8 +29,9 @@ ASYNC_CLK_CROSSING_WIDTH_DEPTH(data_t, fast_to_slow, DATAS_PER_ITER, 4)
2829
//#include "clock_crossing/slow_to_fast.h" // Auto generated
2930
ASYNC_CLK_CROSSING_WIDTH_DEPTH(data_t, slow_to_fast, DATAS_PER_ITER, 4)
3031

31-
void fast(uint1_t reset)
32+
void fast()
3233
{
34+
uint1_t reset = 0; // No reset for now
3335
// Drive leds with state, default lit
3436
static uint1_t test_failed = 0;
3537
uint1_t led = 1;
@@ -57,7 +59,7 @@ void fast(uint1_t reset)
5759
}
5860
fast_to_slow_write_t write = fast_to_slow_WRITE_N(wr_data, wr_en);
5961
// Did the write go through?
60-
if(write.ready)
62+
if(wr_en & write.ready)
6163
{
6264
// Next test data
6365
test_data += DATAS_PER_ITER;
@@ -77,7 +79,7 @@ void fast(uint1_t reset)
7779
{
7880
rd_en = 0;
7981
}
80-
// Try to read 1 data element from the fifo
82+
// Try to read N data elements from the fifo
8183
slow_to_fast_read_t read = slow_to_fast_READ_N(rd_en);
8284
// Did the read go through
8385
if(rd_en & read.valid)
@@ -104,8 +106,9 @@ void fast(uint1_t reset)
104106
}
105107
}
106108

107-
void slow(uint1_t reset)
109+
void slow()
108110
{
111+
uint1_t reset = 0; // No reset for now
109112
// Drive leds with state, default lit
110113
static uint1_t test_failed = 0;
111114
uint1_t led = 1;
@@ -133,7 +136,7 @@ void slow(uint1_t reset)
133136
}
134137
slow_to_fast_write_t write = slow_to_fast_WRITE_N(wr_data, wr_en);
135138
// Did the write go through?
136-
if(write.ready)
139+
if(wr_en & write.ready)
137140
{
138141
// Next test data
139142
test_data += DATAS_PER_ITER;
@@ -153,7 +156,7 @@ void slow(uint1_t reset)
153156
{
154157
rd_en = 0;
155158
}
156-
// Try to read 1 data element from the fifo
159+
// Try to read N data elements from the fifo
157160
fast_to_slow_read_t read = fast_to_slow_READ_N(rd_en);
158161
// Did the read go through
159162
if(rd_en & read.valid)

src/SYN.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4985,6 +4985,7 @@ def GET_VHDL_FILES_TCL_TEXT_AND_TOP(
49854985

49864986
# Built in src/vhdl #TODO just auto add every file in dir
49874987
files_txt += SYN_OUTPUT_DIRECTORY + "/" + "built_in/pipelinec_fifo_fwft.vhd" + " "
4988+
files_txt += SYN_OUTPUT_DIRECTORY + "/" + "built_in/pipelinec_async_fifo_fwft.vhd" + " "
49884989

49894990
# C defined structs
49904991
files_txt += SYN_OUTPUT_DIRECTORY + "/" + "c_structs_pkg" + VHDL.VHDL_PKG_EXT + " "

src/VHDL.py

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2673,6 +2673,9 @@ def WRITE_CLK_CROSS_ENTITIES(parser_state, multimain_timing_params):
26732673
clk_ext_strs.add(clk_ext_str_i)
26742674
if len(clk_ext_strs) > 1:
26752675
flow_control_is_async = True
2676+
# Need to know syn tool for what type of CDC to render
2677+
if SYN.SYN_TOOL is None:
2678+
SYN.PART_SET_TOOL(parser_state.part)
26762679
write_size, read_size = parser_state.clk_cross_var_info[
26772680
var_name
26782681
].write_read_sizes
@@ -2688,13 +2691,6 @@ def WRITE_CLK_CROSS_ENTITIES(parser_state, multimain_timing_params):
26882691

26892692
# TODO OTHER SIZES
26902693
if flow_control:
2691-
if SYN.SYN_TOOL is None:
2692-
SYN.PART_SET_TOOL(parser_state.part)
2693-
if flow_control_is_async and SYN.SYN_TOOL is not VIVADO:
2694-
raise Exception(
2695-
"Async fifos are only implemented for Xilinx parts, TODO!", var_name
2696-
)
2697-
26982694
if write_size != read_size:
26992695
raise Exception(
27002696
"Only equal read and write sizes for async fifos for now, TODO!",
@@ -2729,7 +2725,7 @@ def WRITE_CLK_CROSS_ENTITIES(parser_state, multimain_timing_params):
27292725
print("More than 1 dim for async flow control!?", var_name)
27302726
sys.exit(-1)
27312727
depth = dims[0]
2732-
if flow_control_is_async and depth < 16:
2728+
if flow_control_is_async and SYN.SYN_TOOL is VIVADO and depth < 16:
27332729
depth = 16
27342730
print(
27352731
"WARNING:",
@@ -2749,7 +2745,7 @@ def WRITE_CLK_CROSS_ENTITIES(parser_state, multimain_timing_params):
27492745
use work.c_structs_pkg.all; -- User types
27502746
"""
27512747

2752-
if flow_control and flow_control_is_async:
2748+
if flow_control and flow_control_is_async and SYN.SYN_TOOL is VIVADO:
27532749
text += """
27542750
library xpm;
27552751
use xpm.vcomponents.all;
@@ -2938,7 +2934,7 @@ def WRITE_CLK_CROSS_ENTITIES(parser_state, multimain_timing_params):
29382934
+ """dout_slv"""
29392935
+ from_slv_toks[1]
29402936
+ """;""")
2941-
if flow_control and flow_control_is_async:
2937+
if flow_control and flow_control_is_async and SYN.SYN_TOOL is VIVADO:
29422938
text += (
29432939
"""
29442940
wr_power_on_reset <= '0' when rising_edge(in_clk);
@@ -3079,21 +3075,34 @@ def WRITE_CLK_CROSS_ENTITIES(parser_state, multimain_timing_params):
30793075
-- End of xpm_fifo_async_inst instantiation
30803076
"""
30813077
)
3082-
3083-
# Sync built in fifo
3084-
elif flow_control and not flow_control_is_async:
3078+
# Built in fifo sync or async looks similar
3079+
elif flow_control:
3080+
text += """
3081+
pipelinec_fifo_fwft_inst : entity work."""
3082+
if not flow_control_is_async:
3083+
text += "pipelinec_fifo_fwft"
3084+
else:
3085+
text += "pipelinec_async_fifo_fwft"
30853086
text += """
3086-
pipelinec_fifo_fwft_inst : entity work.pipelinec_fifo_fwft
30873087
generic map (
30883088
DEPTH_LOG2 => """ + str(math.ceil(math.log(depth, 2))) + """,
30893089
DATA_WIDTH => """ + C_TYPE_STR_TO_VHDL_SLV_LEN_STR(in_t, parser_state) + """
30903090
)
30913091
port map
30923092
(
3093-
clk => in_clk,
3093+
"""
3094+
if flow_control_is_async:
3095+
text += " in_clk => in_clk,\n"
3096+
else:
3097+
text += " clk => in_clk,\n"
3098+
text += """
30943099
valid_in => write_enable(0) and in_clk_en(0),
30953100
ready_out => wr_return_output.ready(0),
30963101
data_in => din_slv,
3102+
"""
3103+
if flow_control_is_async:
3104+
text += " out_clk => out_clk,\n"
3105+
text += """
30973106
valid_out => rd_return_output.valid(0),
30983107
ready_in => read_enable(0) and out_clk_en(0),
30993108
data_out => dout_slv

0 commit comments

Comments
 (0)