EmbDev.net

Forum: FPGA, VHDL & Verilog Synthesis doesn't match simulation


von Kyle G. (kyle_g)


Rate this post
useful
not useful
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)


Rate this post
useful
not useful
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
     :

: Edited by Moderator
von Kyle G. (kyle_g)


Rate this post
useful
not useful
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)


Rate this post
useful
not useful
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.

: Edited by Moderator
von Kyle G. (kyle_g)


Rate this post
useful
not useful
I tried to fix things but now something very strange is happening. If I 
leave
1
if(!st) st_f <= 1'b0;
 at the end, it evaluates
1
if (st_f == 1'b1)
 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
1
if(!st) st_f <= 1'b0;
 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.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.