I don't know if it's in Verilog-2005 standard but I managed to compile following code with «synplify pro» and «icarus verilog».
integer fsm_step_number;
always #(posedge clk or posedge rst)
if(rst) begin
pc <= 8'h00;
wb_addr_o <= 8'h00;
wb_wdat_o <= 8'h00;
wb_stb_o <= 1'b0;
wb_cyc_o <= 1'b0;
wb_we_o <= 1'b0;
temt <= 1;
end
else begin
fsm_step_number=1;
case(pc)
fsm_step_number++: begin
wb_addr_o <= UART_LSR;
wb_stb_o <= 1'b1;
wb_cyc_o <= 1'b1;
wb_we_o <= 1'b0;
end
fsm_step_number++: begin
temt <= wb_rdat_i[6];
wb_stb_o <= 1'b0;
wb_cyc_o <= 1'b0;
wb_we_o <= 1'b0;
end
[...]
endcase
end
The incrementation of fsm_step_number integer doesn't works with lattice synthesis program (LSE) neither Yosys.
I have a syntax error with yosys :
yosys> read_verilog uart_ctrl_pre.v
1. Executing Verilog-2005 frontend.
Parsing Verilog input from `uart_ctrl_pre.v' to AST representation.
ERROR: Parser error in line uart_ctrl_pre.v:74: syntax error, unexpected TOK_INCREMENT
Do you know if it's possible to do a think like that with Yosys (increment integer into case state) ?
The ++ operator is in SystemVerilog, not Verilog.
And I think that synthesis tools require that the either the case(expression) or list of item: expressions be a constant, but do not allow both to be non-constant expressions.
Related
I am trying to write a Finite State Machine for an assignment. However, I don't understand what is wrong with my module code. I get the error:
ERROR VCP5221 "Illegal reference to memory: st." "design.sv" 77 5
when I try to synthesize. I think I've either misunderstood how switch-case is used in Verilog or I've attempted to make an illegal assignment inside the switch-case but I don't know how to find it.
//Code here
module MooreFSM(
input clk,
input in,
output out
);
reg state[2:0];
reg sel[2:0];
reg o;
assign out = o;
initial begin
state <= 3'b000;
o <= 1'b0;
end
always#(negedge clk) begin
state <= sel;
end
always#(posedge clk) begin
case(state)
3'b000: begin
if(in == 1'b0) begin
sel <= 3'b010;
o <= 1'b0;
end
else if(in == 1'b1) begin
sel <= 3'b001;
o <= 1'b0;
end
end
3'b001: begin
if(in == 1'b0) begin
sel <= 3'b000;
o <= 1'b0;
end
else if(in == 1'b1) begin
state <= 3'b011;
o <= 1'b0;
end
end
3'b010: begin
if(in == 1'b0) begin
sel <= 3'b100;
o <= 1'b0;
end
else if(in == 1'b1) begin
sel <= 3'b000;
o <= 1'b0;
end
end
3'b011: begin
if(in == 1'b0) begin
sel <= 3'b000;
o <= 1'b1;
end
else if(in == 1'b1) begin
sel <= 3'b011;
o <= 1'b1;
end
end
3'b100: begin
if(in == 1'b0) begin
sel <= 3'b100;
o <= 1'b1;
end
else if(in == 1'b1) begin
sel <= 3'b000;
o <= 1'b1;
end
end
default: begin
sel <= 3'b000;
o <= 1'b0;
end
endcase
end
endmodule
Please help me identify the problem, or if I need to use a different method to synthesize a mux.
I think when you put
else if(in == 1'b1) begin
state <= 3'b011;
o <= 1'b0;
end
you might have meant to write
else if(in == 1'b1) begin
sel <= 3'b011;
o <= 1'b0;
end
By putting state as something being assigned in just one case of this switch statement, you're implicitly asking for it to be latched back to in every other case, which conflicts with you explicitly making it a flop above.
I want to write a synthesizable state machine that read/write wishbone commands in an ordered sequence.
Currently I defined some verilog macros :
`define WB_READ(READ_ADDR) \
begin \
wb_addr_o <= UART_DIV;\
wb_stb_o <= 1'b1; wb_cyc_o <= 1'b1; wb_we_o <= 1'b0; end
`define WB_WRITE(WR_ADDR, WVALUE) \
begin \
wb_addr_o <= WR_ADDR;\
wb_wdat_o <= WVALUE;\
wb_stb_o <= 1'b1; wb_cyc_o <= 1'b1; wb_we_o <= 1'b1; end\
`define WB_NOPE \
begin\
wb_stb_o <= 1'b0; wb_cyc_o <= 1'b0; wb_we_o <= 1'b0; end
And used in in my FSM process :
always #(posedge clk or posedge rst)
if(rst) begin
count <= 8'h00;
wb_addr_o <= 8'h00;
wb_wdat_o <= 8'h00;
wb_stb_o <= 1'b0;
wb_cyc_o <= 1'b0;
wb_we_o <= 1'b0;
end
else begin
case(count)
{7'h01, 1'b1}: `WB_READ(UARD_DIV)
{7'h02, 1'b1}: `WB_READ(UARD_DIV)
{7'h03, 1'b1}: `WB_WRITE(UART_LCR, 8'h60)
{7'h04, 1'b1}: `WB_WRITE(UART_DIV, 8'h01)
{7'h05, 1'b1}: `WB_WRITE(UART_THR, 8'h55)
default: `WB_NOPE
endcase
if (count < {7'h06, 1'b1})
count <= count + 1;
end
Each time count is even, WB_NOPE state is «executed» and each time it's odd, the command given is executed.
That works in simulation but if I want to add a command in the middle of state machine, I have to re-indent all {7'hxx, 1'b1} states. and increment the if(count < ...) at the end.
Is somebody know how to improve this (with macro ?) to avoid it ?
You can just use an integer value in the case statements, and increment it for each step. Here's a slightly stripped back version of your code that does what you want (or at least something close enough that you can fix it :-) )
module testcase (input logic clk,input logic rst);
enum logic [1:0] { READ,WRITE,NOP } op;
logic [7:0] count;
`define WB_READ begin op <= READ; end
`define WB_WRITE begin op <= WRITE; end
`define WB_NOPE begin op <= NOP; end
logic [6:0] fsm_step_number;
always #(posedge clk or posedge rst)
if(rst) begin
count <= 8'h00;
op <= NOP;
end
else begin
fsm_step_number=1;
case(count)
{(fsm_step_number++), 1'b1}: `WB_READ
{(fsm_step_number++), 1'b1}: `WB_READ
{(fsm_step_number++), 1'b1}: `WB_WRITE
{(fsm_step_number++), 1'b1}: `WB_WRITE
{(fsm_step_number++), 1'b1}: `WB_WRITE
default: `WB_NOPE
endcase
if (count < {(fsm_step_number), 1'b1})
count <= count + 1;
end
assert
endmodule
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!
I'm implementing a repeating bit shifter for a 16 bit number. To do this, I have a bit counter that counts how many times I've shifted and resets when I reach 4'b1111. Then I have an assign statement that feeds the MSB to an output. However, the logic makes it so that the output skips the first MSB every time. What is the most succinct way to include the first MSB, before any shifting has occurred?
CODE
module DAC_Control(
input [15:0]data_in,
input clk,
input rst,
output data_out,
output reg cs,
output reg enable
);
//bit counter
reg [3:0] bit_counter;
//to help with shifting
reg [15:0] shifter;
always #(data_in)
shifter <= data_in;
//shifter
always #(posedge (clk)) begin
if (rst) begin
bit_counter <= 4'b0;
enable <= 1'b0;
cs <= 1'b1;
end
else if (bit_counter == 4'b1111) begin
bit_counter <= 4'b0;
enable <= 1'b1;
cs <= 1'b1;
end
else begin //this is the problem area
bit_counter <= bit_counter + 1'b1;
enable <= 1'b0;
cs <= 1'b0;
shifter <= shifter << 1;
end
end
assign data_out = shifter[15];
endmodule
Firstly it would be better to have a trigger to capture the data_in. If not then in simulation ,if the data_in changes in between the shifting it will update the shifter and cause the expected output to change. It would be preferable to capture the data_in based on a qualifying event ( e.g. counter_enable in the example below) . Synthesis will produce an error as shifter has two drivers . One the continuous assignment shifter <= data_in; and other the shifting logic shifter <= shifter << 1;
Updated sample code should serialize the data.
module DAC_Control(
input [15:0]data_in,
input counter_enable,
input clk,
input rst,
output data_out,
output reg cs,
output reg enable
);
//bit counter
reg [3:0] bit_counter;
//to help with shifting
reg [15:0] shifter;
//shifter
always #(posedge (clk)) begin
if (rst) begin
bit_counter <= 4'b0;
shifter <= 0;
end
else if (counter_enable == 1) begin
shifter <= data_in;
bit_counter <= 4'b0;
end
else begin
shifter <= shifter << 1; // shifting
bit_counter <= bit_counter + 1'b1; // counter
end
end
always #(posedge (clk)) begin
if (rst) begin
enable <= 1'b0;
cs <= 1'b1;
end
else if (bit_counter == 4'b1111) begin
enable <= 1'b1;
cs <= 1'b1;
end
else begin
enable <= 1'b0; // generate enable signals
cs <= 1'b0;
end
end
assign data_out = shifter[15];
endmodule
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).