I having been trying to implement a simple sequence detector on a Nexys 3 (Spartan 6) board. The code works perfectly on Xilinx simulation but on the hardware, it doesn't work. Since I am new to FPGA implementation I couldn't solve this issue.
I dont know what changes I should make for the code to work in hardware.
It would be great if someone could help me..
And this is the code
module sequence( in, clock,reset,test);
input in;
input reset;
output reg test=0;
reg [3:0] state=0, next=0 ;
input clock;
always#( posedge clock)
begin
if(reset==1)
begin
state= 0;
end
else
begin
state=next;
end
end
always #*
begin
if(reset == 1)
begin
next=0;
test=0;
end
else
begin
case ( state )
'd0 : begin
if ( in==1)
begin
next=state+1;
end
else
next=next;
end
'd1 : begin
if ( in==1)
begin
next=state+1;
end
else
next=0;
end
'd2 : begin
if ( in==1)
begin
next=state+1;
end
else
next=0;
end
'd3 : begin
if ( in==1)
begin
next=state+1;
end
else
next=0;
end
'd4 : begin
if ( in==1)
begin
next=state+1;
test=1;
end
else
next=0;
end
default : begin
next=0;
test=0;
end
endcase
end
end
endmodule
I would change the beginning of your always block to:
always #*
begin
next = state;
test = 0;
case (state)
'd0 :
begin
if ( in==1)
next=state+1;
end
...
Setting a default assignment to all values in the state machine eliminates the possibility of creating an implicit latch. Your "next = next" statement shouldn't have any effect but might be creating latch (should probably be "next = state').
Also test is not assigned in every branch and has no default, so it will also create a latch.
The problems that I found in your Verilog code is given below.
Output variable test must be assigned in every case statement branches, else unwanted latches will form.
Use nonblocking assignments when you are specifying sequential circuit.
Try to code your sequence detector as below.
//sequence detector 101101
module fsm (rst,in1,clk,out1);
parameter s0 = 3'b000, s1 = 3'b001, s2 = 3'b010, s3 = 3'b011, s4 = 3'b100, s5 = 3'b101;
input rst,in1,clk;
output reg out1;
reg [2:0] state;
always #(posedge clk)
if (rst)
begin
state <= s0;
out1 <= 0 ;
end
else
case(state)
s0 : if (in1) begin state <= s1; out1 <= 0 ; end
else begin state <= s0; out1 <= 0 ; end
s1 : if (in1) begin state <= s0; out1 <= 0 ; end
else begin state <= s2; out1 <= 0 ; end
s2 : if (in1) begin state <= s3; out1 <= 0 ; end
else begin state <= s0; out1 <= 0 ; end
s3 : if (in1) begin state <= s4; out1 <= 0 ; end
else begin state <= s2; out1 <= 0 ; end
s4 : if (in1) begin state <= s1; out1 <= 0 ; end
else begin state <= s5; out1 <= 0 ; end
s5 : if (in1) begin state <= s1; out1 <= 1 ; end
else begin state <= s0; out1 <= 0 ; end
default: if (in1) begin state <= s0; out1 <= 0 ; end
else begin state <= s0; out1 <= 0 ; end
endcase
endmodule
Related
this is a very basic question but if somebody can help me with these errors, I'd really appreciate it. I am an EE undergrad, new to Verilog, and I'd appreciate any help/explanation.
The errors I received were:
10028 Can't resolve multiple constant drivers for "led" at compare_block.sv (66)
10029 Constant driver at compare_block.sv(61)
What are the multiple constant drivers here? Originally, I had the led assignment (led <= led_val) within the second always block, and I thought moving it up to the first always block would change the errors, but it did not.
module compare_block (clk, reset_n, result, led);
parameter data_width = 8; /
parameter size = 1000;
input clk, reset_n;
input [data_width:0] result;
logic [(data_width):0] data_from_rom;
logic [9:0] addr_to_rom;
output reg led;
reg [(data_width):0] comp_sig [size-1:0];
reg [data_width:0] comp_sig_temp;
reg [(data_width):0] filt_sig [size-1:0];
reg [(data_width):0] ans_sig [size-1:0];
integer i, iii;
reg [9:0] ii ;
integer sum_array;
wire [(data_width+3):0] array_avg;
reg [data_width:0] summed_arr [size-2 : 0];//container for all summation steps
wire total_sum;
reg ans_sig_done;
reg [data_width : 0] summed_ans;
reg [data_width:0] max_val, error_val;
initial begin
i = 0;
ii = 0;
led=0;
data_from_rom='b000000000;
summed_ans='b000000000;
max_val='b000000000;
for (iii=0;iii<(size-1);iii=iii+1) begin
filt_sig[iii]=0;
ans_sig [iii]=0;
comp_sig[iii]=0;
summed_arr[iii]=0;
end
end
//port map to ROM
rom_compare ref_wave(
.clk(clk),
.addr(addr_to_rom), //text file?
.data(data_from_rom)
);
//Moore FSM
localparam [3:0]
s0=0, s1 = 1, s2 = 2, s3 = 3, s4 = 4, s5 = 5;
reg [3:0] state_reg, state_next;
initial state_next = 0;
always #(posedge clk, negedge reset_n) begin
if (reset_n == 'b0) begin //reset is active low
state_reg <= s0;
end else begin
state_reg <= state_next;
led <= led_val;
end
end
always #(state_reg) begin
state_next = state_reg;
led=0;
case (state_reg)
s0 : begin //initial state, reset state
if (!reset_n) begin
led <= 0;
ii <= 0;
end else begin
state_next <= s1;
end
end
s1 : begin
if (ii>(size)) begin
ii <= 0;
end else begin
addr_to_rom <= ii;
state_next <= s2;
end
end
s2 : begin
comp_sig_temp <= data_from_rom;
filt_sig [ii] <= result;
state_next <= s3;
end
s3 : begin
comp_sig[ii] <= comp_sig_temp;
state_next <= s4;
end
s4 : begin
ans_sig[ii] <= filt_sig[ii] - comp_sig[ii];
state_next <= s5;
end
s5 : begin
if (ii>(size-2)) begin
ans_sig_done = 1;
end else begin
ans_sig_done = 0;
end
ii <= ii+1;
state_next <= s0;
end
endcase
end
reg [(data_width+2):0] sum;
integer j;
always #* begin
sum = 0;
if (ans_sig_done == 1) begin
for (j=4; j<(size-1); j=j+2) begin
sum = sum +ans_sig[j];
if (ans_sig[j] > max_val) begin
max_val = ans_sig[j];
end
end
end
end
assign array_avg = sum >> 'd3; //2^3 = 8
always #(clk, result) begin //posedge clk, result
filt_sig [i] <= result;
i <= i + 1;
end
assign error_val = max_val >> 'd2; //approx 25% of max value of array
reg led_val;
always #(*)
begin
if (array_avg < error_val) begin
led_val <= 'b1;
end else begin
led_val <= 'b0;
end
end
endmodule
I figured it out!
The two instances were me trying to initialize one led = 0 in one always block and then assigning led <= led_val in another. You can't refer to an output in two different always blocks.
Quartus is telling me that I have inferred latches for input_val, ii, output_val, delayed, and addr_to_rom. I have looked at previous posts and made changes so that all my if statements have an else component and that my case statement has a default option.
What else could be causing all of these inferred latches?
(updated code below)
module simple_fir(clk, reset_n, output_val);
parameter data_width = 8;
parameter size = 1024;
input wire clk;
input wire reset_n;
//input reg [(data_width):0] input_val;
reg [(data_width):0] input_val;
output reg [data_width:0] output_val;
reg [(data_width):0] delayed;
reg [data_width:0] to_avg;
reg [9:0] ii ;
reg [9:0] i ;
reg [data_width:0] val;
reg [data_width:0] output_arr [(size-1):0];
logic [(data_width):0] data_from_rom; //precalculated 1 Hz sine wave
logic [9:0] addr_to_rom;
initial delayed = 0;
initial i = 0;
initial ii = 0;
//port map to ROM
rom_data input_data(
.clk(clk),
.addr(addr_to_rom), //text file?
.data(data_from_rom)
);
//Moore FSM
localparam [3:0]
s0=0, s1 = 1, s2 = 2, s3 = 3, s4 = 4, s5 = 5, s6 = 6;
reg [3:0] state_reg, state_next;
initial state_next = 0;
always #(posedge clk, negedge reset_n) begin //posedge clk, reset_n
if (reset_n == 'b0) begin //reset is active low
state_reg <= s0;
end else begin
state_reg <= state_next;
end
end
always #* begin
state_next = state_reg; // default state_next
case (state_reg)
s0 : begin //initial state, reset state
if (!reset_n) begin
output_val = 0;
delayed = 0;
to_avg= 0;
i = 0;
ii = 0;
end else begin
state_next = s1;
end
end
s1 : begin
if (ii>(size-2)) begin
ii = 0;
end else begin
addr_to_rom = ii;
end
input_val = input_val;
delayed = delayed;
state_next = s2;
end
s2 : begin
input_val = data_from_rom;
ii = ii+1;
delayed = delayed;
state_next = s3;
end
s3 : begin
delayed = input_val;
state_next = s4;
end
s4 : begin
addr_to_rom = ii;
input_val = input_val;
delayed = delayed;
state_next = s5;
end
s5 : begin
input_val = data_from_rom;
delayed = delayed;
//i=i+1;
//ii <= ii+1;
state_next = s6;
end
s6 : begin
to_avg = input_val + delayed; //summing two values
val = (to_avg >> 1); //taking the average
output_arr[ii-1] = val; //indexing starts on [2]
output_val = val;
state_next = s0;
input_val = input_val;
end
default: begin
addr_to_rom = addr_to_rom;
data_from_rom = data_from_rom;
delayed = delayed;
input_val = input_val;
to_avg = to_avg;
val = val;
output_val = output_val;
ii = ii;
end
endcase
end
endmodule
You have 6 states in your combo always block, but you are assigning to delayed in only 3 of them. This implies that you want to retain state, which infers latches. You should make sure delayed is assigned some value in all states (and in all branches of if/else, if applicable.
Also, you have an incomplete sensitivity list. You likely want to change:
always #(state_reg) begin
to:
always #* begin
#* is the implicit sensitivity list, which triggers the always block whenever a change occurs to any signal on the RHS of an assignment.
you have to look at the ways state machines are programmed. Usually states are calculated using flop and the final assignment is a combinatorial. You have it vice versa. Therefore you have issues. Something like the following should work for you. Sorry, i did not test it. The code needs to use non-blocking assignments except in the place where you caculate an intermediate value.
always #*
state_reg = state_next;
always #(posedge clk, negedge reset_n) begin //posedge clk, reset_n
if (reset_n == 'b0) begin //reset is active low
state_next <= s0;
end
else begin
case (state_reg)
S0: begin
output_val <= 0;
delayed <= 0;
i <= 0;
ii <= 0;
end
s1 : begin
if (ii>(size-2)) begin
ii <= 0;
end else begin
addr_to_rom <= ii;
end
input_val <= input_val;
delayed <= delayed;
state_next <= s2;
end
s2 : begin
input_val <= data_from_rom;
ii <= ii+1;
state_next <= s3;
end
s3 : begin
delayed <= input_val;
state_next <= s4;
end
s4 : begin
addr_to_rom <= ii;
state_next <= s5;
end
s5 : begin
input_val <= data_from_rom;
state_next <= s6;
end
s6 : begin
// calculating intermediate value, need blocking assignments here
to_avg = input_val + delayed; //need blocking here
val = (to_avg >> 1); //need blocking here
output_arr[ii-1] <= val; //indexing starts on [2]
output_val <= val;
state_next <= s0;
end
endcase
end // else
end // always
I noticed you used a coding style that a default assignment state_next = state_reg is placed at the very top of the always block. That makes state_next always have a legal driver if it is not explicitly assigned. This is also required for other combinational signals. Otherwise, latch inferred. Besides, the signal data_from_rom, which I assume is an output from module rom_data, has mutiple drivers.
Verilog Error
I am trying to learn verilog . This code is made for seven segment led using counter. But I am not able to assign value to nr it gives error. I made a state machine and wish to get next number on seven segment led after each positive clock.
/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/
module LED ( nr,clk);
input clk;
output [6:0]nr; //output led seven bit number
reg [6:0]nr;
reg [2:0]state;
always #(posedge clk);
begin
state <= 3'b000; // assigning at each clock
case (state)
3'b000:
begin
nr <= 7'b0000001;
state <= 3'b001;
end
3'b001:
begin
nr <= 7'b0011111;
state <= 3'b010;
end
3'b010:
begin
nr <= 7'b0100101;
state <= 3'b011;
end
3'b011:
begin
nr <= 7'b0001100;
state <= 3'b100;
end
3'b100:
begin
nr <= 7'b1011010;
state <= 3'b101;
end
3'b101:
begin
nr <= 7'b1001000;
state <= 3'b110;
end
3'b110:
begin
nr <= 7'b1000000;
state <= 3'b111;
end
3'b111:
begin
nr <= 7'b0011101;
state <= 3'b000;
end
end
endmodule
always #(posedge clk) no semicolon!
So i am currently doing a little project involving a hd44780 display. But since i want to write my own init sequence i decided to use a state machine. I am quite new to FPGAs an their programming coming from a Java background.
This is my State machine Block.
I this state it works and the IDE doesnt show any errors.
always #(posedge reset)
begin
en_timeout <= 2'b00;
timeout <= 14'b00000000000000;
init <= 4'b000;
data <= 8'b00000000;
en <= 1'b1; //active low
rs <= 1'b0;
rw <= 1'b0;
state <= 4'b0000;
next_state <= 4'b0000;
debug <= 1'b0;
end
if(timeout == 0)
begin //Begin of Initiation state machine
case(state)
s0:
begin
end
s1:
begin
end
s2:
begin
end
s3:
begin
end
s4:
begin
end
s5:
begin
end
s6:
begin
end
s7:
begin
end
s8:
begin
end
s9:
begin
end
s10:
begin
end
normal:
begin
end
endcase
end //End of Initiation state machine
But if i add any assignment between the begin and end of one of the states it shows me "Line n: Syntax error near "<="."
for example:
case(state)
s0:
begin
state <= s1;
end
Full code of my DisplayDriver so far:
module DisplayDriver(
output reg [8:0] data,
output reg en,
output reg rs,
output reg rw,
output reg debug,
input clk,
input reset
);
parameter s0=0,s1=1,s2=2,s3=3,s4=4,s5=5,s6=6,s7=7,s8=8,s9=9,s10=10,normal = 11;
reg [3:0] state; // 4 bit for max 11 combinations s0-s10 and normal
reg [3:0] state; // 4 bit for max 11 combinations s0-s10 and normal [next State]
reg [1:0] en_timeout; // 2 bit for en high to low to high cylce
reg [13:0] timeout; // 14 bit
initial
// begin init
begin
en_timeout <= 2'b00;
timeout <= 14'b00000000000000;
init <= 4'b000;
data <= 8'b00000000;
en <= 1'b1; //active low
rs <= 1'b0;
rw <= 1'b0;
state <= 4'b0000;
next_state <= 4'b0000;
debug <= 1'b0;
end
// end of init
always #(posedge clk)
//begin of everything that needs the clock
begin
if(en_timeout > 0) //begin timeout stack
begin
en_timeout <= en_timeout -1;
en <= ~en;// if en_timeout = 2 -> en = 0; if en_timeout = 1 -> en = 1;
end
else if (timeout > 0) timeout <= timeout -1; //end timeout stack
if(timeout == 0)state <= next_state;
end //end of everything that needs the clock
always #(posedge reset)
begin
en_timeout <= 2'b00;
timeout <= 14'b00000000000000;
init <= 4'b000;
data <= 8'b00000000;
en <= 1'b1; //active low
rs <= 1'b0;
rw <= 1'b0;
state <= 4'b0000;
next_state <= 4'b0000;
debug <= 1'b0;
end
if(timeout == 0)
begin //Begin of Initiation state machine
case(state)
s0:
begin
end
s1:
begin
end
s2:
begin
end
s3:
begin
end
s4:
begin
end
s5:
begin
end
s6:
begin
end
s7:
begin
end
s8:
begin
end
s9:
begin
end
s10:
begin
end
normal:
begin
end
endcase
end //End of Initiation state machine
endmodule
Does anyone have an idea why it behaves this way?
I assume that you are trying to synthesize a register for "state", in which case the update "<=" needs to be inside always (#posedge clk).
I am trying to design a fsm for showing rotational which runs the 4-digit 7-segment LED display unit, to cause a rotating pattern of circulating squares in clockwise or counterclockwise. I am trying to fix the syntax errors in my case block but I am in verilog coding and I cannot find my mistake. Here is the code:
module fsm( EN, CW, clk, AN1,AN2,AN3,AN4, leds );
//inputs and outputs
input EN, CW, clk;
output AN1,AN2,AN3,AN4;
output reg leds[6:0];
//state register and parameters
reg state[3:0];
parameter s0 = 3'b000;
parameter s1 = 3'b001;
parameter s2 = 3'b010;
parameter s3 = 3'b011;
parameter s4 = 3'b100;
parameter s5 = 3'b101;
parameter s6 = 3'b110;
parameter s7 = 3'b111;
//states and outputs according to the states
always # (posedge clk)
begin
if (EN == 1)
begin
case(state)
s0: leds<=7'b1100011; if(CW)begin state <= s1; end else begin state <= s7; end
s1: leds<=7'b1100011; if(CW)begin state <= s2; end else begin state <= s0; end
s2: leds<=7'b1100011; if(CW)begin state <= s3; end else begin state <= s1; end
s3: leds<=7'b1100011; if(CW)begin state <= s4; end else begin state <= s2; end
s4: leds<=7'b1011100; if(CW)begin state <= s5; end else begin state <= s3; end
s5: leds<=7'b1011100; if(CW)begin state <= s6; end else begin state <= s4; end
s6: leds<=7'b1011100; if(CW)begin state <= s7; end else begin state <= s5; end
s7: leds<=7'b1011100; if(CW)begin state <= s0; end else begin state <= s6; end
endcase
end
end
//output logic
assign AN1 = ~((state == s0) | (state == s7));
assign AN2 = ~((state == s1) | (state == s6));
assign AN3 = ~((state == s2) | (state == s5));
assign AN4 = ~((state == s3) | (state == s4));
endmodule
A few things.
You should declare your vector signals like this:
output reg [6:0] leds;
//state register and parameters
reg [3:0] state;
And, you need to wrap each case item with a begin/end. I also spread the statements across a few lines, which might make it more readable:
s0: begin
leds <= 7'b1100011;
if (CW) begin
state <= s1;
end else begin
state <= s7;
end
end
Or, you could replace the if/else with a ternary:
s0: begin
leds <= 7'b1100011;
state <= (CW) ? s1 : s7;
end