verilog output stuck on last if statement - verilog

Problem: I'm synthesizing my code, which reads 1200 16 bit binary vectors, analyzes them and sets a 2 bit register named classe depending on the behavior of 4 if statements. The problem seems to be that classe is stuck on the last if statement - where classe is set to bit 11, or 3.
My code worked fine in when I was using a testbench.
I'm thinking it is stuck because somehow the always block is reading all 1200 vectors at once, as seen in the simulation, instead of one every clock edge?
I've attached a simulation screenshot here: https://imgur.com/a/No2E9cq
module final_final_code
(
output reg [ 0:1] classe
);
reg [0:15] memory [0:1199];
reg[0:15] vect:
integer i;
//// Internal Oscillator
defparam OSCH_inst.NOM_FREQ = "2.08";
OSCH OSCH_inst
(
.STDBY(1'b0), // 0=Enabled, 1=Disabled also Disabled with Bandgap=OFF
.OSC(osc_clk),
.SEDSTDBY() // this signal is not required if not using SED
);
initial begin
$readmemb("C:/Users/KP/Desktop/data.txt", memory, 0, 1199);
i = 0;
end
always #(posedge osc_clk) begin
vect = memory[i];
if ((memory[i][3] == 1'b0)) begin
classe = 2'b10;
end
if ((memory[i][11] == 1'b0)) begin
classe = 2'b01;
end
if ((memory[i][8] == 1'b1 && memory[i][4] + memory[i][5] + memory[i][6] + memory[i][7] >= 4'b0100)) begin
classe = 2'b00;
end
if ((memory[i][0] + memory[i][1] + memory[i][2] + memory[i][3] + memory[i][4] + memory[i][5] + memory[i][6] + memory[i][7] + memory[i][8] + memory[i][9] + memory[i][10] + memory[i][11] + memory[i][12] + memory[i][13] + memory[i][14] + memory[i][15] <= 1'b1)) begin
classe = 2'b11;
end
i = i + 1'd1;
if (i == 4'd1199) begin
i = 0;
end
end
endmodule

Apart from what john_log says:
Your last if statement is always TRUE. You are adding 1-bit operands and comparing against a 1-bit result thus the results is 1'b1 or 1'b0 which is always <= 1'b1.
You should check if your FPGA tool supports this:
initial begin
$readmemb("C:/Users/KP/Desktop/data.txt", memory, 0, 1199);
i = 0;
end
Especially the loading of a memory from a file by the synthesis tool. It was not possible the last time I used an FPGA.

Related

reg instantiate with 1 in verilog

I'm making a simple project with leds blinking every second. Led 1 and 3 blink alternating to led 2 and 4. I've written the following Verilog code:
module leds_blinking(input i_Clk,
output o_LED_1,
output o_LED_2,
output o_LED_3,
output o_LED_4);
parameter c_CYCLESINSECOND = 50_000_000;
reg r_LED_1 = 1;
reg r_LED_2 = 0;
reg r_LED_3 = 1;
reg r_LED_4 = 0;
reg [32:0] r_Count = 0;
always #(posedge i_Clk)
begin
if (r_Count < c_CYCLESINSECOND)
r_Count <= r_Count + 1;
else if (r_Count == c_CYCLESINSECOND)
begin
r_LED_1 <= ~r_LED_1;
r_LED_2 <= ~r_LED_2;
r_LED_3 <= ~r_LED_3;
r_LED_4 <= ~r_LED_4;
r_Count <= 0;
end
else
r_Count <= 0;
end
assign o_LED_1 = r_LED_1;
assign o_LED_2 = r_LED_2;
assign o_LED_3 = r_LED_3;
assign o_LED_4 = r_LED_4;
endmodule
All LEDs are active at the same time, though I instantiated 1,3 other than 2,4.
I’m assuming you are synthesizing and not running simulation on the RTL first. Synthesizer that target for ASIC typically ignore default values and initial blocks. Synthesizer that target for FPGA often do. Not knowing which synthesizer you are using it is hard to guess your root causes issue.
However, you can simplify your code and solve your problem by using one registers instead of four. Notice how the o_LED_# are driven.
always #(posedge i_Clk)
begin
if (r_Count < c_CYCLESINSECOND)
r_Count <= r_Count + 1;
else
begin
r_LED <= ~r_LED;
r_Count <= 0;
end
end
assign o_LED_1 = r_LED;
assign o_LED_2 = ~r_LED;
assign o_LED_3 = r_LED;
assign o_LED_4 = ~r_LED;

How to assign variable pins to a port in verilog?

I have a 32-bit input port pins and a 32-bit input enable pin_en, and want to generate a 16-bit output selected by the enables. I wrote verilog like this, but seems there are some errors.
How can I fix it or any other way to achive? Thanks!
ps: No more than 16 pins selected by en, but maybe less.
input [31:0] pins;
input [31:0] pin_en;
output [15:0] actual_pins;
generate
genvar i;
localparam cnt = 0;
for(i = 0; (i < 'd32) & (cnt < 'd16); i = i + 'd1) begin : b1
if(pin_en[i]) begin
assign actual_pins[i] = pins[cnt];
cnt = cnt + 'd1;
end
end
if(cnt < 16)
assign actual_pins[16 : cnt] = 'b0;
endgenerate
I think that there are several errors in you code:
in generate blocks you cannot do any generation, based on the actual values of variables. The blocks are for the constant expressions only which could be resolved at compilation time, not at the run time. Also, you cannot modify anything in the generated blocks besides genvars. Paremeters (localparams) cannot be modified, so the cnt = cnt + 1 is just illegal there.
you messed up actual_pins and pins. by logic there should be actual_pins[cnt];
you use binary & operator, but you should have used logical && instead.
So, all your code should have been implemented in a run-time constructs, i.e., always blocks. You also need a trigger which will cause the always block to be evaluated. I created a small example where the always block is to be triggered by a clock.
module top (
input clk,
input [31:0] pins,
input [31:0] pin_en,
output reg [15:0] actual_pins
);
always #(posedge clk) begin
int cnt = 0;
int i;
for(i = 0; (i < 'd32) && (cnt < 'd16); i = i + 'd1) begin
if(pin_en[i]) begin
actual_pins[cnt] = pins[i];
cnt = cnt + 'd1;
end
end
for(; cnt < 16; cnt = cnt + 1)
actual_pins[j] = 1'b0;
end
endmodule

Reading file in Icarus Verilog

I have a file data.txt that has 1200 lines, each representing a 16 bit binary string such as the following.
"0001111111000000"
I'm trying to write a testbench using Icarus Verilog that reads in each line of the file and sends each line to a .v file that will run some simple if statements on each line of the file (a simple classification algorithm).
My code is below.
// Verilog test bench for generate.v
`timescale 1ns/100ps
`include "generate.v"
module generate_tb;
$display('running test bench')
integer data_file ; // file handler
integer scan_file ; // file handler
logic signed [21:0] captured_data;
`define NULL 0
initial begin
$dumpfile("generate.vcd");
$dumpvars(0, generate_tb);
data_file = $fopen("./data.txt", "r");
if (data_file == `NULL) begin
$display("data_file handle was NULL");
$finish;
end
end
always #(posedge clk) begin
scan_file = $fscanf(data_file, "%b\n", captured_data);
if (!$feof(data_file)) begin
generate the_circuit(output, captured_data); // HERE
end
end
$finish;
endmodule
and my generate.v file:
module generate(actual_class, data_row);
output actual_class;
input data_row;
wire stby_flag ;
wire [0:15] vect;
reg [0:1] classe;
assign vect = data_row;
always #(posedge clk) begin
if (vect[3] == 0) begin
classe = 2'b10;
end
if (vect[11] == 0) begin
classe = 2'b01;
end
if (vect[8] == 1 && vect[4] + vect[5] + vect[6] + vect[7] >= 3) begin
classe = 2'b00;
end
if (vect[0] + vect[1] + vect[2] + vect[3] + vect[4] + vect[5] + vect[6] + vect[7] + vect[8] + vect[9] + vect[10] + vect[11] + vect[12] + vect[13] + vect[14] + vect[15] <= 1) begin
classe = 2'b11;
end
end
assign actual_class = classe;
endmodule
I am stuck on this part of the code. I'm not sure how I can call the generate.v file for each line of the file.
if (!$feof(data_file)) begin
generate the_circuit(output, captured_data); // HERE
end
A better way to do this would be to save my data into and use $readmemb but I'm hoping to do it this way.
Any advice is much appreciated.
To start off: it is a very bad idea to name your module after a reserved word 'generate'.
I'm not sure how I can call the generate.v
It is a module, not a function. You can not 'call' a module.
You read each line from the file and assign it to a input variable of the module. Make sure you wait long enough before reading the next line for your module (and all subsequent triggered modules) to finish processing the input. You can wait a number of clock cycles or use a 'ready' signal.
A better way to do this would be..
Maybe. If your pattern gets very big you need a big memory.

Increment and Decrement using verilog codes in quartus

My project is to design a verilog code that gives an output on the 7segments (HEX0,HEX1,HEX2,HEX3) and output must increase when the button KEY0 is pressed on the board 1 by 1, and decrease when the button KEY1 is pressed using Altera Board (Cyclone II-EP2C35F672).
I achieve to increase 1 by 1 but when I try to decrease with the same logic, I take irrelevant outputs. Is it possible to give me a way solving the problem.
My verilog code is that:
module sevensegment (KEY,HEX0,HEX1,HEX2,HEX3);
input [3:0]KEY;
output [0:6]HEX0;
output [0:6]HEX1;
output [0:6]HEX2;
output [0:6]HEX3;
counter D1(~KEY,HEX0,HEX1,HEX2,HEX3);
endmodule
module counter(in,out,out1,out2,out3);
input [3:0]in;
output [6:0]out;
output [6:0]out1;
output [6:0]out2;
output [6:0]out3;
reg[15:0] tmp;
always #(posedge in)
begin
if(~in[0])
begin
tmp <= tmp + 1'b1;
end
else if(~in[1])
begin
tmp <= tmp - 1'b1;
end
end
displaysevensegment first_digit(tmp[3:0],out);
displaysevensegment second_digit(tmp[7:4],out1);
displaysevensegment third_digit(tmp[11:8],out2);
displaysevensegment fourth_digit(tmp[15:12],out3);
endmodule
module displaysevensegment(in,out);
// abcdefg
parameter BLANK = 7'b1111111;
parameter ZERO = 7'b0000001;
parameter ONE = 7'b1001111;
parameter TWO = 7'b0010010;
parameter THREE = 7'b0000110;
parameter FOUR = 7'b1001100;
parameter FIVE = 7'b0100100;
parameter SIX = 7'b0100000;
parameter SEVEN = 7'b0001111;
parameter EIGHT = 7'b0000000;
parameter NINE = 7'b0000100;
parameter TEN = 7'b0001000;
parameter ELEVEN = 7'b1100000;
parameter TWELVE = 7'b0110001;
parameter THIRTEEN = 7'b1000010;
parameter FOURTEEN = 7'b0110000;
parameter FIFTEEN = 7'b0111000;
input [3:0]in;
output [6:0]out;
assign out = (in == 0) ? ZERO:
(in == 1) ? ONE:
(in == 2) ? TWO:
(in == 3) ? THREE:
(in == 4) ? FOUR:
(in == 5) ? FIVE:
(in == 6) ? SIX:
(in == 7) ? SEVEN:
(in == 8) ? EIGHT:
(in == 9) ? NINE:
(in == 10) ? TEN:
(in == 11) ? ELEVEN:
(in == 12) ? TWELVE:
(in == 13) ? THIRTEEN:
(in == 14) ? FOURTEEN:
(in == 15) ? FIFTEEN:BLANK;
endmodule
The simulate will not recognize the raising edge of in[1] when the sensitivity list is describes as posedge in. Only the LSB will be monitored. Instead use a bitwise operation to detect when a key is pressed and use this as the clocking signal.
wire gen_clk = |in; // bitwise OR
always #(posedge gen_clk) begin
if (in[0]) tmp <= tmp + 1'b1;
else if (in[1) tmp <= tmp - 1'b1;
end
wire gen_clk = &in; // bitwise AND
always #(posedge gen_clk) begin
if (in[0]) tmp <= tmp + 1'b1;
else if (in[1) tmp <= tmp - 1'b1;
end
Side note: Deep nested muxes often result in lower performance more area then a case statement. This is because most synthesizer will not optimize inline muxes (?:). Recommend re-coding displaysevensegment with a case statement like:
input [3:0] in;
output [6:0] out;
reg [6:0] out; // out needs to be a reg
always #* begin
case(in)
4'h0 : out = ZERO;
4'h1 : out = ONE;
// ...
4'hE : out = FOURTEEN;
4'hF : out = FIFTEEN;
default: out = BLANK;
endcase
end

Verilog design: Where should my counter live?

I am coding in Verilog a typical count-to-n-then-reset-to-0 counter. My module has the logic to increment and reset the counter.
My issue is that I don't know where the counter itself should be defined.
I could pass the counter (as inout?) to the module. That's ok, but the counter still has to be defined somewhere so it this doesn't do me any good.
Nothing else except this module should touch the counter, so I'd like to have the counter created within this module, and not passed in or out.
Is this reasonably standard, and if so, will someone point to a reference please on how to instantiate the counter?
(I'm on day 2 of Verilog, so be afraid, heh)
EDIT - here's the code. As far as I can tell, it works. I haven't implemented DIR == REVERSE yet.
Couple of interesting gotchas. The (now commented out) STEPPER=0 line was causing an error in a schematic; it thought that STEPPER was tied to ground as well as other logic.
Also, I use = instead of <= in some places involving counter - I was getting timing problems (I suppose.) The procedural assignment removed (hid?) the problem.
module cam(
input [7:0] DIVISOR,
input DIR,
input SPINDLE,
output reg STEPPER
);
parameter FORWARD = 1'b1;
parameter REVERSE = !FORWARD;
reg[7:0] counter = 0;
always #(posedge SPINDLE) begin
// STEPPER = 0;
if (DIR == FORWARD) begin
counter = counter + 1;
if (counter == DIVISOR) counter = 0;
end
else begin
// counter <= counter - 1;
// if (counter == (-1)) counter <= DIVISOR;
end
end
always #(negedge SPINDLE) begin
STEPPER = (counter == 0) ? 1 : 0;
end
endmodule
Should just be defined as a register within the module. Here's an example from some of my code.
module trigger(clk, rxReady, rxData, txBusy, txStart, txData);
input clk;
input [7:0] rxData;
input rxReady;
input txBusy;
output reg txStart;
output reg[7:0] txData;
integer count81; // Number of cells received over serial (start solving after 81)
reg[8:0] data[0:8][0:8];
integer state;
always #(posedge clk) begin
case (state)
read:
if (rxReady) begin
data[count81 % 9][count81 / 9] = rxData ? 1<<(rxData-1) : -1;
if (count81 < 80) count81 <= count81 + 1;
else begin
count81 <= 0;
state <= solving;
end
end
etc....
endcase
end
endmodule
Congrats on getting out of the Java world for the time being. FPGAs are the only thing that seems exciting anymore.

Resources