Ring Oscillator in Verilog using generate - module

I'm looking to create a ring oscillator in Verilog, using inverters and generate.
Here's what I've tried so far:
module ringOsc(outclk);
parameter SIZE = 8; // This needs to be an even number
output outclk;
wire [SIZE : 0] w;
genvar i;
generate
for (i=0; i<SIZE; i=i+1) begin : notGates
not notGate(w[i+1], w[i]);
end
not notGateFirst(w[0], w[SIZE]);
endgenerate
assign outclk = w[0];
endmodule
This will be loaded onto an FPGA and the frequency of oscillation will be measured (of course with more than 9 inverters). Is this correct or am I missing something? Any help would be appreciated.

For a ring oscillator you need to have a delay. The not gates you are using have no such delay in simulation as they are ideal models.
Simplest is to add a delay to the gates:
not #(5,5) notGate(w[i+1], w[i]);
not #(5,5) notGateFirst(w[0], w[i]);
Also it is good practice to have en enable: one of the gates is a NAND gate.
You also need to tell the tool not to optimise your ring oscillator away. For that you have to look at the synthesis tool of your FPGA, especially the constraints settings to prevent logic optimization. Defining the intermediate nets as 'keep' might work.

Related

When I add memory clear logic Bram memory turn into distributed ram

I want to create a BRAM that has a data clear logic. With saying that I mean after a reset signal all the data inside of the BRAM needs to be 0.
I coded BRAM in verilog HDL.
(* ram_style = "block" *)
reg [7:0] mem [511:0];
reg [7:0] data_read = 8'b0;
always#(posedge clk) begin
if (write_i) begin
mem[addr_i] <= write_data_i;
end
else begin
data_read <= mem[addr_i];
end
end
assign read_data_o = data_read;
This code block successfully generates BRAM as netlist can be shown in the following image:
But when I add reset logic to BRAM to clear the data inside of it when reset rises, BRAM memory turns into distributed RAM.
This is the data clear logic I have added:
if (rst) begin
for(i=0; i<512 ; i= i+1) begin
mem[i] <= 8'b0;
end
end
Netlist after I added clear logic:
What is the reason of this? Why BRAM becomes distributed Ram? Isn't it possible to create a BRAM with data clear logic ?
The vendor BRAM macro/primitives/hardware do not support a global clear/write 0, or write anything else using a control signal.
See
https://docs.xilinx.com/v/u/2019.2-English/ug901-vivado-synthesis
section 4 for supported RAM inference coding styles.
There are two ways to accomplish some sort of BRAM initialization or global write.
Use a state machine controller to loop thru all the addresses
and assign the values needed (write to the ram in a controlled way using RTL to control the address, data, and wr_en)
Use Vivado IP catalog (or ISE Coregen) generated RAM and a .mif/.coe file. The contents of the .mif/.coe get loaded one time when the FPGA is configured.
More info on using .mif files here:
https://docs.xilinx.com/r/en-US/ug896-vivado-ip/IP-User-Files-ip_user_files-for-Core-Container
The memory generator GUI provides the opportunity to load a .coe file. The .coe is used for synthesis, .mif file for simulation.
If you want to use the generated IP method see:
https://docs.xilinx.com/v/u/en-US/pg058-blk-mem-gen
My preference is a state machine, so that external files and external IP are not needed.

timing issues: simulation (iverilog, gtkwave) works, hardware (yosys) does not

I am learning verilog, trying do make the "hello world" in the VGA world (a bouncing ball) on a ice40LX1K board (olimex ice40HX1K + VGA I/O board).
I have a strange problem: when I simulate my design using iverilog + GTKWave, it seams to work good. But the implementation in hardware does not work.
What is strange is that in the hardware implemention, the ball is doesn't move .. and its position is all zero (0,0) althou the verilog code never should set it overthere.
It looks like changing the value of xpos_ball or ypos_ball does not actually change these values. (a hardware issue? a yosys issue)? In the iverilog simulation, location of the ball does change as expected.
I have no idea if this is a error in my own verilog code (as I am new in this, this is very well possible), an issue in yosys, or a problem in the hardware (speed issue, is the 100 Mhz clock to fast?) or something else?
Any proposals on how to troubleshoot this, or next steps for this kind of issue? Are there other debugging-tricks I can use?
(edit: link to the actual verilog-code removed as not relevant anymore)
Kristoff
is the 100 Mhz clock to fast?
Yes. That design is good for 39.67 MHz:
$ make vga_bounceball.rpt
icetime -d hx1k -mtr vga_bounceball.rpt vga_bounceball.asc
// Reading input .asc file..
// Reading 1k chipdb file..
// Creating timing netlist..
// Timing estimate: 25.21 ns (39.67 MHz)
Edit re comment:
You can always safely divide a clock by a power of two by using FFs as clock dividers:
input clk_100MHz;
reg clk_50MHz = 0; // initialization needed for simulation
reg clk_25MHz = 0;
always #(posedge clk_100MHz) clk_50MHz <= !clk_50MHz;
always #(posedge clk_50MHz) clk_25MHz <= !clk_25MHz;
(A non-power-of-two prescaler is not always safe without making sure with timing analysis that the prescaler itself can run in the high frequency domain.)

How to declare a global variable in Verilog?

I am writing to ask how to declare a global variable in Verilog. What declared by parameter and define keywords are essentially constants, not variables.
What I need is the following:
`define Glitch
module Cell ( Shift_In, Shift_Out_Screwed, Clk );
input Clk, Shift_In;
output Shift_Out_Screwed;
wire Shift_Out_Screwed;
wire Shift_Out;
Inverter INV1 ( Shift_In, Shift_Out, Clk );
assign Shift_Out_Screwed = Glitch ? ~Shift_Out : Shift_Out
endmodule
This is a very simple glitch insertion. When Glitch==1, the original output is reversed; when Glitch==0, the original output is kept unchanged. I want the signal Glitch to be defined in an external simulation testbench.v file although it is declared and used here, and I don't want to add the signal Glitch to the input port list of the module cell. This is because that my real circuit is a very complicated one, and if I add an input port to a certain cell, there will be many other cells affected.
Does anyone know how to declare a global variable in Verilog?
The problem you are wrestling with sounds like error injection. You want the ability to inject a bit error on an output port from within a testbench. You can do it like this:
module Cell ( Shift_In, Shift_Out_Screwed, Clk );
input Clk, Shift_In;
output Shift_Out_Screwed;
wire Shift_Out_Screwed;
wire Shift_Out;
Inverter INV1 ( Shift_In, Shift_Out, Clk );
`ifdef SIMULATION
// This logic is used in simulation, but not synthesis. Use care.
logic Glitch = 1'b0;
assign Shift_Out_Screwed = Glitch ? ~Shift_Out : Shift_Out
`else
// This logic is used in synthesis, but not simulation. Use care.
assign Shift_out_Screwed = Shift_out;
`endif
endmodule
Note that I use the "SIMULATION" preprocessor switch to hide the "Glitch" error injection from synthesis. Use this technique with care to avoid creating simulation/synthesis mismatches.
In your testbench, you can induce a glitch in a specific instance of your cell by referencing the "Glitch" signal in the design hierarchy, like this:
initial begin
...
#(posedge Clk); #1;
$top.u_foo.u_bar.u_cell.Glitch = 1'b1;
#(posedge Clk); #1;
$top.u_foo.u_bar.u_cell.Glitch = 1'b1;
...
end
The above code snippet will inject one cycle of "Glitch".
As an alternative: a more traditional way of injecting errors is to use the "force" statement in the testbench to override a driven in a device under test.

Verilog module for a smoke detector and a buzzer

I have Altera DE2-115 FPGA and I try to self-learn Verilog. I decided to make a smoke detector and whenever it smells smoke the buzzer rings (the smoke detector outputs a digital signal).
Here is my trial :
module fire(flag,clock,reset,fire,fire_state,firealarm);
input clock, reset, flag, fire;
output [2:0] fire_state;
output firealarm;
wire fire;
reg [2:0] fire_state;
assign firealarm = (fire_state == 1) ? (flag ? 0 : 1) : 0;
always # (posedge clock)
fire_state<= fire ? 1: 0;
end module
But it doesn't run and I think there are a lot of logic errors in this code, any help please? :)
endmodule is one word, you need to remove the space.
Almost all simulators these days support verilog-2001 or greater so I would encourage the use of the modern port style (ANSI) and not the old verilog 1995 style.
Your port list goes from:
module fire(flag,clock,reset,fire,fire_state,firealarm);
input clock, reset, flag, fire;
output [2:0] fire_state;
output firealarm; wire fire;reg[2:0] fire_state;
to :
module fire(
input clock,
input reset,
input flag,
input fire,
output reg [2:0] fire_state,
output firealarm
);
I have placed each port on a new line with it direction, this makes it much easier to maintain code, it also make it a lot more readable and therefore minimises the chance of typos in connections.
You have used this syntax a lot (flag?0:1), where you using a boolean to select a boolean there is no need to do this and makes it more difficult to read. If you need to invert it then is a bitwise invert (~). However it is not clear what you are using flag for.
for comparrisons and assignments you should be including the width.
assign firealarm = (fire_state == 3'b1)? (~flag) : 1'b0;
This could also be written out in a combinatorial always block:
always #* begin
if (fire_state==3'b001) begin
firealaram = ~flag;
else begin
firealaram = 1'b0;
end
end
fire is 1 bit, fire_state is 3 bits.
always # (posedge clock) begin
fire_state <= {2'b0, fire};
end

XOR outputs one because of propagaton delay in (basic) counter (FPGA)

I have a basic counter example, counter is 6-bits wide.
reg[5:0] currcounterval_reg;
always #(posedge clk_g0)
currcounterval_reg <= currcounterval_reg+ 1'b1;
My constraints
Clock is running at 83 Mhz 912ns period) on Virtex 7 chip. The counter has no reset and the output is connected to board pins. When I run the circuit, I see switching in the signals as shown in the attached (hardware run) o/p. In the attached screenshot, if you look at the counter, after 7(seven), I should get '8'...but it first switches to '12' as bit-2 goes to zero later than the others. I have an xor gate downstream where I compare o/p of two counters. How to I avoid getting into this problem?
Whatever I do for constraining, it doesn't go away. Please help me with some strategies to remove the switching.
Please feel free to ask me if you have more questions.
You can find a my waveform here
http://i.imgur.com/btEMiFD.png?1
Thanks.
I am guessing that it is an improper constraint issue. But try wiring a synchronous counter explicitly to solve the issue.
reg[5:0] counter;
always #(posedge clk_g0)
begin
counter[0] <= ~counter[0] ;
counter[1] <= (counter[0] ) ? ~counter[1] : counter[1];
counter[2] <= (&counter[1:0] ) ? ~counter[2] : counter[2];
counter[3] <= (&counter[2:0] ) ? ~counter[3] : counter[3];
counter[4] <= (&counter[3:0] ) ? ~counter[4] : counter[4];
counter[5] <= (&counter[4:0] ) ? ~counter[5] : counter[5];
end
You need to make the XOR output synchronous. The XOR output should go to the D input of a FF that is clocked on the same rising edge that increments the counters. Bring the Q output of the FF to an FPGA pin rather than the XOR output.
You shouldn't try to match the combinational logic delays and routing delays of the two counters. The delay paths from two counters to your XOR gates will almost certainly be different so a fast XOR (like on a Virtex 7) will generate glitches. In a good synchronous design that doesn't matter, because you only care that the combinational logic outputs are valid before the next clock edge.