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.

problem with for loop in verilog

Status
Not open for further replies.

keremcant

Member level 5
Joined
Dec 25, 2009
Messages
87
Helped
6
Reputation
12
Reaction score
5
Trophy points
1,288
Activity points
1,910
hi,
we are trying to use this memory module on an FPGA. everything works but the reset. it does not reset the memory. the code is as following:

Code:
module tirtik_hafiza3( input [6:0] tirtik,
								input clock,
								input reset,
								input read_write,
								output reg read_write_led,
								output reg [6:0] mem_led
    );
	 
	 
	 reg [6:0] mem [100:0];
	 reg [7:0] address;
	 reg change; 	 
	 integer i;
	 
		always @ (posedge clock) begin
			if(reset) begin
				address <= 0;
				change <= 1;
				for(i=0;i<100;i=i+1)begin
					mem[i] <= 7'b0000000;
				end
			end else if(read_write) begin
				read_write_led <= 1;
				mem[address] <= tirtik;
				address <= address +1;
				change <= 1;
			end else if (!read_write) begin				
				if(!change)begin
					read_write_led <= 0;
					mem_led <= mem[address];
					address <= address +1;
				end else begin 
					address <= 0; 
					change <= 0;
				end
			end			
		end

endmodule

so we think that the problem is with the for loop, it this true? can you recommend us any way to reset the memory?
 

Hi,

Try following code

Code:
module tirtik_hafiza3
( 
   input  wire         clock
  ,input  wire         reset
  ,input  wire [06:00] tirtik
  ,input  wire         read_write
  ,output reg          read_write_led
  ,output reg  [06:00] mem_led
);
	 
	 
	 reg [6:0] mem [100:0];
	 reg [7:0] address;
	 reg change; 	 
//	 integer i;
reg  [06:00] rst_counter;
reg          rst, rst_f1;

  always @ (posedge clock)
    begin
      if (reset)
        rst <= 1'b1;
      else if (rst_counter == 7'h63)
        rst <= 1'b0;
    end

  always @ (posedge clock)
    begin
      rst_f1 <= rst;
    end

  always @ (posedge clock)
    begin
      if ((rst)&&(~rst_f1))
        begin
          rst_counter <= {7{1'b0}};
        end
      else
        begin
          if (rst_counter == 7'h64)
            rst_counter <= 7'h64;
          else
            rst_counter <= rst_counter + 1'b1;
        end
    end

  always @ (posedge clock) 
    begin
      if(rst) 
        begin
          address          <= 8'h0;
          change           <= 1;
          mem[rst_counter] <= 7'b0000000;
          mem_led          <= 7'b0000000;
        end
      else if(read_write) 
        begin
          read_write_led <= 1;          
          address        <= address +1;
          change         <= 1;
          mem[address]   <= tirtik;
        end 
      else if (!read_write) 
        begin				
          if(!change)
            begin
              read_write_led <= 0;
              mem_led        <= mem[address];
              address        <= address +1;
            end 
          else 
            begin 
              address <= 0; 
              change  <= 0;
            end
        end			
    end

endmodule

HTH
 

Hi keremcant,

I simulated your code and there is no problem with the for loop.

I only saw minor bug in your code so mem[100] is never being reset.
reg [6:0] mem [100:0]; // Here, you declare that memory depth is 101 words (address 0 to 100).
for(i=0;i<100;i=i+1)begin // But here you set initial value for address 0 to 99 only

Except that bug, reset for mem[0] to mem[99] work well in simulation.

Anyway, there is possibility that FPGA synthesis tool misinterpret those code. If your target is FPGA, it is better to use FPGA memory resource (can be generated using Altera megafunction wizard or Xilinx core generator, depends on your FPGA board).

They usually support memory initialization file for initializing memory bits.
 

For simulation there is no problem with any code, in behavioral code you can write any thing which allowed in syntex, but while it comes to synthesis I wrote one logic, there can be another solution for this.

Regards,
Shitansh Vaghela
 

Yes, many code can run in simulation but not synthesizable.

But as far as I know, for loop code should work in most synthesis tools right now. It is not behavioral code, unless we use non-constant value in the for loop.
 

But as far as I know, for loop code should work in most synthesis tools right now.
It's not the problem of for loop in general rather than of the attempt to reset all memory locations simultaneously in one clock cycle. It's not supported by the RAM unit of any FPGA family I know of. A solution as suggested by shitansh is required here, that resets one location per clock cycle.

The only curious thing is, that the compiler doesn't throw a warning or refuses to infer internal RAM for an unsupported construct. But that's a question about the particular synthesis tool.
 

its only 808 registers. I'd hope every FPGA would be able to fit that many.

There is also the case where you fat-fingered "reset" as "resrt" or something like that. Verilog has a default net-type of "net", instead of "none". Thus you don't have to declare signals that are 1b nets, the tools will add them for you. This means that what should be an error is now a warning -- reset connected to an undriven net.

And of course the case where reset goes to a package pin that is connected someplace other than where you expected. you can check the schematic and <design>_pad.txt file.
 

With those coding style, synthesis tools usually detect it as registers instead of RAM. The code is too complex for the tool to know that it is intended to be RAM. Auto detection as RAM needs separated code which follows particular coding style (can be read in tools documentation) or we can generate it using megafunction/code generator. Resource usage report can make us sure is it detected as registers or RAM.

If design size is small enough and fit in the FPGA, it is usually safe enough to let it as registers. Registers can be reseted simultaneously in one clock cycle. We can use "for" or "generate for" keyword in verilog to create registers.

But if the design occupies almost all of FPGA register resources, using FPGA RAM resources is preferred. It is also nearer to ASIC implementation which use generated RAM macros. In addition, synthesis time will be shorter if we set it as RAM instead of registers, especially if we generate memory with large number of bits. If we implement it as RAM, we must set initial value using memory initialization file (if FPGA supports it) or use shitansh solution which write one location per clock.
 

With those coding style, synthesis tools usually detect it as registers instead of RAM.
Yes, but apparently the synthesis tool behaved different with the originally posted code:
everything works but the reset
This behaviour (assuming it's been reported correctly) would be only understandable, if the tool inferred RAM and ignored the reset action.
 

Yes, you're right. It is understandable only if inferred RAM detected by the tool. Synthesis warnings log could make sure this.

I want to correct my statement in previous post also. Memory initialization file is loaded only after configuration, not after reset, so it can not be used to reset memory. Sequential reset must be used.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top