I'm having issues getting the my interface program to work. The
simulation looks perfect, but when I synthesis and run it, some parts of
it work and others don't. It kinda seems useless to have a simulator if
it doesn't tell you what's actually happening, otherwise I'm just
guessing.
It's supposed to take a button input and send a parallel packet on
MIOSIO, but when I press the button, all I see on my scope is a little
blip where CSn goes low for a few nano seconds. If I put start_f <= 0 in
the "else if (done)" section, it actually works but it just repeats over
and over like it gets stuck in the loop.
My code is probably very sloppy, but here it is:
1 module top ( pushbutton , MIOSIO_w , CLK_w , CSn_w , dev_clk , LEDS_OUT );
2
3 input wire pushbutton ;
4 output wire [ 7 : 0 ] MIOSIO_w ;
5 output wire CLK_w ;
6 output wire CSn_w ;
7 output wire dev_clk ;
8
9 wire fpga_clock ;
10 reg [ 7 : 0 ] tx_data ;
11 reg [ 7 : 0 ] data_array [ 0 : 15 ];
12 wire [ 3 : 0 ] i ;
13
14 reg [ 3 : 0 ] dat_size ;
15 reg start_pulse ;
16
17 output wire [ 7 : 0 ] LEDS_OUT ;
18 wire [ 7 : 0 ] MIOSIO ;
19 wire CLK ;
20 wire CSn ;
21
22 // assign MIOSIO_w = MIOSIO;
23 //assign CLK_w = CLK;
24 //assign CSn_w = CSn;
25
26 always @ ( posedge fpga_clock )
27 begin
28 start_pulse <= ~ pushbutton ;
29 end
30
31 always @ ( i )
32 begin
33 tx_data <= data_array [ i ];
34 end
35
36 initial
37 begin
38 start_pulse <= 0 ;
39 dat_size <= 1 ;
40 data_array [ 0 ] <= 8 ' h2A ;
41 data_array [ 1 ] <= 8 ' h3B ;
42 end
43
44 OSCH # (. NOM_FREQ ( "133.00" )) rc_oscillator (. STDBY ( 1 ' b0 ), . OSC ( fpga_clock ));
45 ft221x_write test (. sys_clk ( fpga_clock ), . tx_data ( tx_data ), . dat_size ( dat_size ), . dat_index ( i ), . start ( start_pulse ), . MIOSIO ( MIOSIO_w ), . CLK ( CLK_w ), . CSn ( CSn_w ), . dev_clk ( dev_clk ), . LEDS ( LEDS_OUT ));
46
47 endmodule
48
49
50 module ft221x_write ( sys_clk , tx_data , dat_size , dat_index , start , MIOSIO , CLK , CSn , dev_clk , LEDS );
51 // Set CPOL = 0 in FTPROG
52
53 // Input wires from internal regs
54 input wire start ;
55 input wire sys_clk ;
56 input wire [ 3 : 0 ] dat_size ;
57 input wire [ 7 : 0 ] tx_data ;
58 output reg [ 3 : 0 ] dat_index ;
59
60 output reg [ 7 : 0 ] MIOSIO ; // Wired to MIOSIO - TEST - might not be necessary
61 output reg CSn ; // Wired to CSn - TEST - might not be necessary
62 output reg CLK ; // Wired to CLK - TEST - might not be necessary
63 reg [ 7 : 0 ] leds_r ;
64 output wire [ 7 : 0 ] LEDS ;
65
66 // Used for clock divider timing
67 reg [ 7 : 0 ] clk_div ;
68 reg [ 7 : 0 ] clk_count ;
69 output reg dev_clk ;
70 reg [ 1 : 0 ] turnaround_counter ;
71 reg [ 3 : 0 ] packet_count ;
72 reg done ;
73 wire T , C , R ;
74 wire Q , Qn ;
75 reg start_f ;
76
77 pulse_latch start_l ( T , C , R , Q , Qn );
78 assign LEDS = ~ leds_r ;
79
80 initial
81 begin
82 start_f <= 1 ' b0 ;
83 done <= 1 ' b1 ;
84 dat_index <= 4 ' h0 ;
85 MIOSIO <= 8 ' bzzzzzzzz ;
86 turnaround_counter <= 2 ' b10 ;
87 CSn <= 1 ' b1 ;
88 dev_clk <= 1 ' b1 ;
89 clk_count <= 8 ' h0 ;
90 clk_div <= 8 ' h5 ;
91 CLK <= 1 ' b0 ;
92 leds_r <= 8 ' h0 ;
93 end
94
95 //*************************** START PULSE ****************************
96 assign T = start ;
97 assign R = start_f ;
98 assign C = sys_clk ;
99
100 // ************************** DEV_CLOCK ******************************
101 always @ ( posedge sys_clk )
102 begin
103 if ( clk_count < clk_div )
104 clk_count <= clk_count + 8 ' b1 ; // For each system clock pulse, increment clock counter by
105 else
106 begin
107 clk_count <= 8 ' h0 ; // When counter = clock divider, reset clock divider and flip device clock
108 dev_clk <= ~ dev_clk ;
109 end
110 end
111 //********************************************************************
112
113
114 always @ ( dev_clk )
115 begin
116 if ( Q && ! dev_clk ) //Initialize
117 begin
118 dat_index <= 4 ' h0 ;
119 MIOSIO <= 8 ' b0 ;
120 CSn <= 1 ' b0 ;
121 CLK <= 1 ' b0 ;
122 packet_count [ 3 : 0 ] <= dat_size [ 3 : 0 ];
123 turnaround_counter <= 2 ' b10 ;
124 done <= 1 ' b0 ;
125 leds_r <= 8 ' h1 ;
126 start_f <= 1 ' b1 ;
127 end
128
129 else if ( ! done )
130 begin
131 CSn <= 1 ' b0 ;
132 leds_r <= 8 ' h2 ;
133 if ( dev_clk )
134 begin
135 CLK <= 1 ' b1 ;
136 if ( turnaround_counter == 2 ' b10 )
137 begin
138 MIOSIO <= 8 ' b0 ; // Load WRITE Command
139 turnaround_counter <= turnaround_counter - 1 ' b1 ;
140 end
141
142 else if ( turnaround_counter == 2 ' b01 )
143 begin
144 MIOSIO <= 8 ' bzzzzzzzz ;
145 turnaround_counter <= turnaround_counter - 1 ' b1 ;
146 end
147
148 else if (( turnaround_counter == 2 ' b00 ) && ( packet_count != 1 ' b0 ))
149 begin
150 MIOSIO <= tx_data ; // Put data into MIOSIO
151 packet_count <= packet_count - 1 ' b1 ; // Decrement packet_count
152 dat_index <= dat_index + 1 ' b1 ; // Index data by 1
153 end
154 end
155
156 else if ( ! dev_clk )
157 begin
158 if ( packet_count == 0 )
159 begin
160 CLK <= 1 ' b0 ;
161 done <= 1 ' b1 ;
162 end
163
164 else
165 CLK <= 1 ' b0 ;
166 end
167 end
168
169 else if ( done )
170 begin
171 leds_r <= 8 ' h4 ;
172 CSn <= 1 ' b1 ;
173 MIOSIO <= 8 ' bzzzzzzzz ;
174 if ( ! start )
175 start_f <= 1 ' b0 ;
176 end
177 end
178 endmodule
179
180
181 module pulse_latch ( T , C , R , Q , Qn );
182
183 input wire T ;
184 input wire R ;
185 input wire C ;
186 wire set ;
187 wire res ;
188 output wire Q ;
189 output wire Qn ;
190
191 wire sn ;
192 wire rn ;
193
194 assign res = ~ set ;
195 assign set = T & ~ R ;
196 nand n1 ( sn , set , C );
197 nand n2 ( rn , res , C );
198 nand n3 ( Q , sn , Qn );
199 nand n4 ( Qn , Q , rn );
200
201 endmodule
von
Lothar M.
(Company: Titel)
(lkmiller )
(Moderator )
2018-02-19 23:06
Kyle G. wrote:
> some parts of it work and others don't.
Sounds very similar to "I'm using some unsynchronized asynchronous input
signals in a FSM"....
But beside that its much more tricky. I usually do no Verilog, but this
here looks badly wrong:1 always @ ( dev_clk ) // some signals are missing here...
2 // and no posedge and no negedge...
3 // where did you find this coding style?
4 begin
5 if ( Q && ! dev_clk )
6
7 else if ( ! done )
8 :
9 turnaround_counter <= turnaround_counter - 1 ' b1 ; // This seems to be a combinatorial loop
10 :
11 else if ( done )
12 :
13 :
14 end
15 end
16 endmodule
To keep things short: you cannot control synthesis results with the
sensitivity list. Instead in this list you MUST add all of the signals
leading to a change of another signal. That much I know from VHDL. And
it seems to be much the same with Verilog...
https://www.hdlworks.com/hdl_corner/verilog_ref/items/SensitivityList.htm
So try your simulation again with 1 always @ * // this is a combinatoral block, inclue all singals to the sensitivity list
2 begin
3 if ( Q && ! dev_clk )
4 :
2018-02-19 23:06 :
Edited by Moderator
Yes, but I want the following to be evaluated on 'any' change of
dev_clk.
Maybe my problems are from triggering on either edge? But this is how I
was generating the CLK signal to drive the interface chip. I could
divide this by two and trigger on 'posedge' only.
von
Lothar M.
(Company: Titel)
(lkmiller )
(Moderator )
2018-02-19 23:41
Kyle G. wrote:
> Yes, but I want the following to be evaluated on 'any' change of dev_clk.
Thats not possible!
> Maybe my problems are from triggering on either edge?
There is no "double edge triggered flipflop" inside an FPGA. You must
multiply your clock by two with a PLL and work with only one clock edge
(either rising or falling).
> But this is how I was generating the CLK signal to drive the interface
> chip. I could divide this by two and trigger on 'posedge' only.
Do that. And have a look what flipflops your FPGA contains...
> dev_clk <= ~dev_clk;
This is no good design practice. To get derived clocks (for bigger parts
of the design) inside a FPGA you must use a clock manager and a clock
net. Such derived clocks cannot be calculated reliably an they have big
skew and jitter.
2018-02-20 06:23 :
Edited by Moderator
I tried to fix things but now something very strange is happening. If I
leave at the end, it evaluates Which doesn't make sense. I'm supposedly setting it to 0 (when it is
already 0). It does this even if 'st' is high or low. If I remove it does not do this.
1 module top ( pushbutton , MIOSIO_w , CLK_w , CSn_w , dev_clk , LEDS_OUT , pb , tp );
2 output wire tp ;
3 input wire pushbutton ;
4 output wire [ 7 : 0 ] MIOSIO_w ;
5 output wire CLK_w ;
6 output wire CSn_w ;
7 output wire dev_clk ;
8 output wire pb ;
9 wire fpga_clock ;
10 reg [ 7 : 0 ] tx_data ;
11 reg [ 7 : 0 ] data_array [ 0 : 15 ];
12 wire [ 3 : 0 ] i ;
13
14 reg [ 3 : 0 ] dat_size ;
15 wire st_pulse ;
16
17 output wire [ 7 : 0 ] LEDS_OUT ;
18
19 assign st_pulse = ~ pushbutton ;
20 assign pb = st_pulse ;
21
22 always @ ( posedge fpga_clock )
23 begin
24 tx_data <= data_array [ i ];
25 end
26
27 initial
28 begin
29 dat_size = 2 ;
30 data_array [ 0 ] = 8 ' h2A ;
31 data_array [ 1 ] = 8 ' h3B ;
32 end
33
34 OSCH # (. NOM_FREQ ( "133.00" )) rc_oscillator (. STDBY ( 1 ' b0 ), . OSC ( fpga_clock ));
35 ft221x_write test (. sys_clk ( fpga_clock ), . tx_data ( tx_data ), . dat_size ( dat_size ), . dat_index ( i ), . st ( st_pulse ), . MIOSIO ( MIOSIO_w ), . CLK ( CLK_w ), . CSn ( CSn_w ), . dev_clk ( dev_clk ), . LEDS ( LEDS_OUT ), . test_pulse ( tp ));
36
37 endmodule
38
39
40 module ft221x_write ( sys_clk , tx_data , dat_size , dat_index , st , MIOSIO , CLK , CSn , dev_clk , LEDS , test_pulse );
41 // Set CPOL = 0 in FTPROG
42
43 // Input wires from internal regs
44 input wire st ;
45 input wire sys_clk ;
46 input wire [ 3 : 0 ] dat_size ;
47 input wire [ 7 : 0 ] tx_data ;
48 output reg [ 3 : 0 ] dat_index ;
49
50 output reg [ 7 : 0 ] MIOSIO ; // Wired to MIOSIO - TEST - might not be necessary
51 output reg CSn ; // Wired to CSn - TEST - might not be necessary
52 output reg CLK ; // Wired to CLK - TEST - might not be necessary
53
54
55 reg [ 7 : 0 ] leds_r ;
56 output wire [ 7 : 0 ] LEDS ;
57 output reg test_pulse ;
58 // Used for clock divider timing
59 reg [ 7 : 0 ] clk_div ;
60 reg [ 7 : 0 ] clk_count ;
61 output reg dev_clk ;
62 reg [ 1 : 0 ] turnaround_counter ;
63 reg [ 3 : 0 ] packet_count ;
64
65 reg done ;
66
67 reg st_f ;
68
69 assign LEDS = ~ leds_r ;
70
71 initial
72 begin
73 st_f = 1 ' b0 ;
74 done = 1 ' b1 ;
75 dat_index = 4 ' h0 ;
76 MIOSIO = 8 ' bzzzzzzzz ;
77 turnaround_counter = 2 ' b10 ;
78 CSn = 1 ' b1 ;
79 dev_clk = 1 ' b1 ;
80 clk_count = 8 ' h0 ;
81 clk_div = 8 ' h20 ;
82 CLK = 1 ' b0 ;
83 leds_r = 8 ' h0 ;
84 test_pulse = 1 ' b0 ;
85 end
86
87 // ************************** DEV_CLOCK ******************************
88 always @ ( posedge sys_clk )
89 begin
90 if ( clk_count < clk_div )
91 clk_count <= clk_count + 8 ' b1 ; // For each system clock pulse, increment clock counter by
92 else
93 begin
94 clk_count <= 8 ' h0 ; // When counter = clock divider, reset clock divider and flip device clock
95 dev_clk <= ~ dev_clk ;
96 end
97 end
98 //********************************************************************
99
100
101 always @ ( posedge dev_clk )
102 begin
103 if ( st_f == 1 ' b1 ) //Initialize
104 begin
105 dat_index <= 4 ' h0 ;
106 MIOSIO <= 8 ' b0 ;
107 CSn <= 1 ' b0 ;
108 CLK <= 1 ' b0 ;
109 packet_count [ 3 : 0 ] <= dat_size [ 3 : 0 ];
110 turnaround_counter <= 2 ' b10 ;
111 done <= 1 ' b0 ;
112 leds_r <= 8 ' h1 ;
113 st_f <= 1 ' b1 ;
114 test_pulse <= 1 ' b1 ;
115 end
116
117 else if ( ! done )
118 begin
119 CSn <= 1 ' b0 ;
120 leds_r <= 8 ' h2 ;
121
122 if ( dev_clk && ( packet_count != 4 ' b0 ))
123 begin
124
125 CLK <= ~ CLK ;
126
127 if ( ! CLK && ( turnaround_counter == 2 ' b10 ))
128 begin
129 MIOSIO <= 8 ' b0 ; // Load WRITE Command
130 turnaround_counter <= turnaround_counter - 1 ' b1 ;
131 end
132
133 else if ( ! CLK && ( turnaround_counter == 2 ' b01 ))
134 begin
135 MIOSIO <= 8 ' bzzzzzzzz ;
136 turnaround_counter <= turnaround_counter - 1 ' b1 ;
137 end
138
139 else if ( ! CLK && ( turnaround_counter == 2 ' b00 ) && ( packet_count != 4 ' b0 ))
140 begin
141 MIOSIO <= tx_data ; // Put data into MIOSIO
142 packet_count <= packet_count - 4 ' b1 ; // Decrement packet_count
143 dat_index <= dat_index + 1 ' b1 ; // Index data by 1
144 end
145 end
146
147 else if ( CLK && packet_count == 4 ' h0 )
148 begin
149 CLK <= 1 ' b0 ;
150 done <= 1 ' b1 ;
151 end
152 end
153
154 else if ( done )
155 begin
156 leds_r <= 8 ' h4 ;
157 CSn <= 1 ' b1 ;
158 MIOSIO <= 8 ' bzzzzzzzz ;
159 if ( ! st )
160 st_f <= 1 ' b0 ;
161 end
162 end
163
164 endmodule
Please log in before posting. Registration is free and takes only a minute.