Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

ncverilog compiling error with 'generate if' in verilog

Status
Not open for further replies.

iamyuchenjie

Junior Member level 1
Junior Member level 1
Joined
Aug 3, 2009
Messages
16
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
Germany
Visit site
Activity points
1,429
Hello everyone,

Following is my verilog codes (with some xilinx primitive, can be totally ignored or commented ).
When I try to use ncsim to compile it:
ncvlog async_fifo_ack.v
I got the following error about the generate part!
ncvlog: *E,UMGENE (async_fifo_ack.v,66|8): An 'endgenerate' is expected [12.1.3(IEEE 2001)].
I am sure my code is correct and I successfully used it in some other place serval months ago in other enivronment. But this time the ncvlog tell syntax error...
my ncvlog version is TOOL: ncvlog 05.10-p004

Is there anyone who meet such a problem?
Many thanks!


Code Verilog - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
module async_fifo_ack (wclk,
                       rclk,
                       wa_reset_h,
                       ra_reset_h,
                       write_en,
                       write_data,
                       read_en,
                       read_data,
                       full,
                       empty
                       );
 
   parameter DATA_WIDTH = 32;
   parameter ADDR_WIDTH = 4;
 
   input                     wclk;
   input                     rclk;
   input                     wa_reset_h;
   input                     ra_reset_h;
   input                     write_en;
   input  [DATA_WIDTH - 1:0] write_data;
   input                     read_en;
 
   output [DATA_WIDTH - 1:0] read_data;
   output                    full;
   output                    empty;
 
   reg    [DATA_WIDTH - 1:0] ram[0:( 1 << ADDR_WIDTH ) - 1];
   reg    [ADDR_WIDTH - 1:0] raddr_temp;
 
   reg    [ADDR_WIDTH - 1:0] int_waddr;
   (* ASYNC_REG = "TRUE" *)
   reg        [ADDR_WIDTH:0] waddr_sync_0;
   (* ASYNC_REG = "TRUE" *)
   reg        [ADDR_WIDTH:0] waddr_sync_1;
   reg        [ADDR_WIDTH:0] wbin;
 
   reg    [ADDR_WIDTH - 1:0] int_raddr;
   (* ASYNC_REG = "TRUE" *)
   reg        [ADDR_WIDTH:0] raddr_sync_0;
   (* ASYNC_REG = "TRUE" *)
   reg        [ADDR_WIDTH:0] raddr_sync_1;
   reg        [ADDR_WIDTH:0] rbin;
 
   wire                      int_write_en;
   wire       [ADDR_WIDTH:0] next_wbin;
   wire       [ADDR_WIDTH:0] next_rbin;
   wire       [ADDR_WIDTH:0] raddr;
   wire       [ADDR_WIDTH:0] waddr;
 
   // fifo memory
   generate
    begin
      if ( ( 1 << ADDR_WIDTH ) * DATA_WIDTH > 512 )
        begin : FifoBlockRAM_AddrGen
           always @(rbin or read_en or empty or next_rbin)
             begin
                raddr_temp = rbin[ADDR_WIDTH - 1:0];
             end
        end
      else
        begin : FifoDistributedRAM_AddrGen
           always @(posedge rclk)
             begin
                raddr_temp <= rbin[ADDR_WIDTH - 1:0];
             end
        end // else: !if( ( 1 << ADDR_WIDTH ) * DATA_WIDTH > 512 )
     end
   endgenerate
 
   generate
     begin
      if ( ( 1 << ADDR_WIDTH ) * DATA_WIDTH > 512 )
        begin : FifoBlockRAM_Mem
 
           reg    [ADDR_WIDTH - 1:0] raddr_reg;
 
           always @(posedge wclk)
             begin
                if ( int_write_en == 1'b1 )
                  ram[wbin[ADDR_WIDTH - 1:0]] <= write_data;
             end
 
           always @(posedge rclk)
             begin
                raddr_reg <= raddr_temp;
             end
 
           assign read_data = ram[raddr_reg];
 
        end // block: FifoBlockRAM
      else
        begin : FifoDistributedRAM_Mem
 
           always @(posedge wclk)
             begin
                if ( int_write_en == 1'b1 )
                  ram[wbin[ADDR_WIDTH - 1:0]] <= write_data;
             end
 
           assign read_data = ram[raddr_temp];
 
        end // block: FifoDistributedRAM
     end
   endgenerate
 
   // write address synchronizer
   always @(posedge rclk or posedge ra_reset_h)
     begin
        if ( ra_reset_h == 1'b1 )
          begin
             waddr_sync_0 <= {ADDR_WIDTH+1{1'b0}};
             waddr_sync_1 <= {ADDR_WIDTH+1{1'b0}};
          end
        else
          begin
             waddr_sync_0 <= waddr;
             waddr_sync_1 <= waddr_sync_0;
          end
     end // always @ (posedge rclk or posedge ra_reset_h)
 
   // read address synchronizer
   always @(posedge wclk or posedge wa_reset_h)
     begin
        if ( wa_reset_h == 1'b1 )
          begin
             raddr_sync_0 <= {ADDR_WIDTH+1{1'b0}};
             raddr_sync_1 <= {ADDR_WIDTH+1{1'b0}};
          end
        else
          begin
             raddr_sync_0 <= raddr;
             raddr_sync_1 <= raddr_sync_0;
          end
     end // always @ (posedge wclk or posedge wa_reset_h)
 
   assign next_rbin = rbin + {{ADDR_WIDTH{1'b0}}, 1'b1};
 
   // read address register
   always @(posedge rclk or posedge ra_reset_h)
     begin
        if ( ra_reset_h == 1'b1 )
          begin
             rbin       <= {ADDR_WIDTH+1{1'b0}};
             int_raddr  <= {ADDR_WIDTH{1'b0}};
          end
        else if ( read_en == 1'b1 && empty == 1'b0 )
          begin
             rbin       <= next_rbin;
             int_raddr  <= next_rbin[ADDR_WIDTH:1] ^
                           next_rbin[ADDR_WIDTH - 1:0];
          end
     end // always @ (posedge rclk or posedge ra_reset_h)
 
   assign int_write_en   = ~full & write_en;
   assign next_wbin      = wbin + {{ADDR_WIDTH{1'b0}}, 1'b1};
 
   // write address register
   always @(posedge wclk or posedge wa_reset_h)
     begin
        if ( wa_reset_h == 1'b1 )
          begin
             wbin       <= {ADDR_WIDTH+1{1'b0}};
             int_waddr  <= {ADDR_WIDTH{1'b0}};
          end
        else if ( int_write_en == 1'b1 )
          begin
             wbin       <= next_wbin;
             int_waddr  <= next_wbin[ADDR_WIDTH:1] ^
                           next_wbin[ADDR_WIDTH - 1:0];
          end
     end // always @ (posedge wclk or posedge wa_reset_h)
 
   // final gray-encoded read address
   assign raddr = {rbin[ADDR_WIDTH], int_raddr};
   // fifo empty indicator
   assign empty = ( raddr == waddr_sync_1 );
   // final gray-encoded write address
   assign waddr = {wbin[ADDR_WIDTH], int_waddr};
   // fifo full indicator
   assign full  = ( waddr[ADDR_WIDTH - 2:0] == raddr_sync_1[ADDR_WIDTH - 2:0] ) &&
                  ( waddr[ADDR_WIDTH] != raddr_sync_1[ADDR_WIDTH] ) && 
                  ( waddr[ADDR_WIDTH - 1] != raddr_sync_1[ADDR_WIDTH - 1] );
 
endmodule // async_fifo_ack

 
Last edited by a moderator:

It's difficult to read your code: it needs 'code'-tags and line-numbers to chase down the error.
BUT, it's possible that the 'generate' has too many clause beginning/endings between it and the 'endgenerate.' Match up all open/close pairs and see.
 

Thank you.
Here is the codes. What is strange is the codes can successfully compiled by modelsim... but in ncsim...it say error

Code:
module async_fifo_ack (wclk,
                       rclk,
                       wa_reset_h,
                       ra_reset_h,
                       write_en,
                       write_data,
                       read_en,
                       read_data,
                       full,
                       empty
                       );

   parameter DATA_WIDTH = 32;
   parameter ADDR_WIDTH = 4;

   input                     wclk;
   input                     rclk;
   input                     wa_reset_h;
   input                     ra_reset_h;
   input                     write_en;
   input  [DATA_WIDTH - 1:0] write_data;
   input                     read_en;

   output [DATA_WIDTH - 1:0] read_data;
   output                    full;
   output                    empty;

   reg    [DATA_WIDTH - 1:0] ram[0:( 1 << ADDR_WIDTH ) - 1];
   reg    [ADDR_WIDTH - 1:0] raddr_temp;

   reg    [ADDR_WIDTH - 1:0] int_waddr;
   (* ASYNC_REG = "TRUE" *)
   reg        [ADDR_WIDTH:0] waddr_sync_0;
   (* ASYNC_REG = "TRUE" *)
   reg        [ADDR_WIDTH:0] waddr_sync_1;
   reg        [ADDR_WIDTH:0] wbin;

   reg    [ADDR_WIDTH - 1:0] int_raddr;
   (* ASYNC_REG = "TRUE" *)
   reg        [ADDR_WIDTH:0] raddr_sync_0;
   (* ASYNC_REG = "TRUE" *)
   reg        [ADDR_WIDTH:0] raddr_sync_1;
   reg        [ADDR_WIDTH:0] rbin;

   wire                      int_write_en;
   wire       [ADDR_WIDTH:0] next_wbin;
   wire       [ADDR_WIDTH:0] next_rbin;
   wire       [ADDR_WIDTH:0] raddr;
   wire       [ADDR_WIDTH:0] waddr;

   // fifo memory
   generate
      if ( ( 1 << ADDR_WIDTH ) * DATA_WIDTH > 512 )
        begin : FifoBlockRAM_AddrGen
           always @(rbin or read_en or empty or next_rbin)
             begin
                raddr_temp = rbin[ADDR_WIDTH - 1:0];
             end
        end
      else
        begin : FifoDistributedRAM_AddrGen
           always @(posedge rclk)
             begin
                raddr_temp <= rbin[ADDR_WIDTH - 1:0];
             end
        end // else: !if( ( 1 << ADDR_WIDTH ) * DATA_WIDTH > 512 )
   endgenerate

   generate
      if ( ( 1 << ADDR_WIDTH ) * DATA_WIDTH > 512 )
        begin : FifoBlockRAM_Mem

           reg    [ADDR_WIDTH - 1:0] raddr_reg;

           always @(posedge wclk)
             begin
                if ( int_write_en == 1'b1 )
                  ram[wbin[ADDR_WIDTH - 1:0]] <= write_data;
             end

           always @(posedge rclk)
             begin
                raddr_reg <= raddr_temp;
             end

           assign read_data = ram[raddr_reg];

        end // block: FifoBlockRAM
      else
        begin : FifoDistributedRAM_Mem

           always @(posedge wclk)
             begin
                if ( int_write_en == 1'b1 )
                  ram[wbin[ADDR_WIDTH - 1:0]] <= write_data;
             end

           assign read_data = ram[raddr_temp];

        end // block: FifoDistributedRAM

   endgenerate

   // write address synchronizer
   always @(posedge rclk or posedge ra_reset_h)
     begin
        if ( ra_reset_h == 1'b1 )
          begin
             waddr_sync_0 <= {ADDR_WIDTH+1{1'b0}};
             waddr_sync_1 <= {ADDR_WIDTH+1{1'b0}};
          end
        else
          begin
             waddr_sync_0 <= waddr;
             waddr_sync_1 <= waddr_sync_0;
          end
     end // always @ (posedge rclk or posedge ra_reset_h)

   // read address synchronizer
   always @(posedge wclk or posedge wa_reset_h)
     begin
        if ( wa_reset_h == 1'b1 )
          begin
             raddr_sync_0 <= {ADDR_WIDTH+1{1'b0}};
             raddr_sync_1 <= {ADDR_WIDTH+1{1'b0}};
          end
        else
          begin
             raddr_sync_0 <= raddr;
             raddr_sync_1 <= raddr_sync_0;
          end
     end // always @ (posedge wclk or posedge wa_reset_h)

   assign next_rbin = rbin + {{ADDR_WIDTH{1'b0}}, 1'b1};

   // read address register
   always @(posedge rclk or posedge ra_reset_h)
     begin
        if ( ra_reset_h == 1'b1 )
          begin
             rbin       <= {ADDR_WIDTH+1{1'b0}};
             int_raddr  <= {ADDR_WIDTH{1'b0}};
          end
        else if ( read_en == 1'b1 && empty == 1'b0 )
          begin
             rbin       <= next_rbin;
             int_raddr  <= next_rbin[ADDR_WIDTH:1] ^
                           next_rbin[ADDR_WIDTH - 1:0];
          end
     end // always @ (posedge rclk or posedge ra_reset_h)

   assign int_write_en   = ~full & write_en;
   assign next_wbin      = wbin + {{ADDR_WIDTH{1'b0}}, 1'b1};

   // write address register
   always @(posedge wclk or posedge wa_reset_h)
     begin
        if ( wa_reset_h == 1'b1 )
          begin
             wbin       <= {ADDR_WIDTH+1{1'b0}};
             int_waddr  <= {ADDR_WIDTH{1'b0}};
          end
        else if ( int_write_en == 1'b1 )
          begin
             wbin       <= next_wbin;
             int_waddr  <= next_wbin[ADDR_WIDTH:1] ^
                           next_wbin[ADDR_WIDTH - 1:0];
          end
     end // always @ (posedge wclk or posedge wa_reset_h)

   // final gray-encoded read address
   assign raddr = {rbin[ADDR_WIDTH], int_raddr};
   // fifo empty indicator
   assign empty = ( raddr == waddr_sync_1 );
   // final gray-encoded write address
   assign waddr = {wbin[ADDR_WIDTH], int_waddr};
   // fifo full indicator
   assign full  = ( waddr[ADDR_WIDTH - 2:0] == raddr_sync_1[ADDR_WIDTH - 2:0] ) &&
				  ( waddr[ADDR_WIDTH] != raddr_sync_1[ADDR_WIDTH] ) && 
				  ( waddr[ADDR_WIDTH - 1] != raddr_sync_1[ADDR_WIDTH - 1] );

endmodule // async_fifo_ack
 

If statements cannot be used outside always blocks. I don't know how is modelsim supporting your code.
 

If statements cannot be used outside always blocks. I don't know how is modelsim supporting your code.
It's pretty legal Verilog code, using conditional generate statements. I don't recognize a syntax error at first sight.
 

There isn't any syntax error in the code. Have you checked that the ncsim you are using is Verilog 2001 compliant? If it's an older version it might not be entirely compliant or you may need to enable using Verilog 2001 with a command line switch. Or it may be having problems with the named blocks.

Try removing the named blocks and see if ncvlog works without them.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top