Value in register keeps resetting to 0 every clock cycle - verilog

I do not understand why the timer counter in this code does not work. At the end of every clock cycle the value resets to 0, so the output would look like this:
clock: 0 timer: 0
clock: 1 timer: 1
clock: 0 timer: 0
clock: 1 timer: 1
Code:
module controller(clock, reset, enable, lightN, lightS, lightE, lightW, NScolor, EWcolor);
input clock, reset, enable, lightN, lightS, lightE, lightW;
output NScolor, EWcolor;
wire clock, reset, enable, lightN, lightS, lightE, lightW;
reg NScolor, EWcolor;
reg timer;
always # (posedge clock)
begin: COUNT
$display("TIMER = %d", timer);
if (reset == 1) begin
$display("Resetting!");
NScolor<= 1;
EWcolor<= 0;
timer <= 0;
end
else if (enable == 1) begin
timer <= timer + 1;
if (timer == 7) begin
switchLights;
end
else if (timer >= 10) begin
timer <= 0;
switchLights;
end
end
end
task switchLights;
begin
if (NScolor == 0 && EWcolor == 2) begin
NScolor<= 1;
EWcolor<= 0;
end
else if (NScolor == 1) begin
NScolor<= 2;
EWcolor<= 0;
end
else if (NScolor == 2) begin
NScolor<= 0;
EWcolor<= 1;
end
if (EWcolor == 0 && NScolor == 2) begin
EWcolor<= 1;
NScolor<= 0;
end
else if (EWcolor == 1) begin
EWcolor<= 2;
NScolor<= 0;
end
else if (EWcolor == 2) begin
EWcolor<= 0;
NScolor<= 1;
end
end
endtask
endmodule

You have declared timer as:
reg timer;
which is a single-bit register. Hence, it only assumes values 0 an 1 in your simulation.
You may declare it as a multi-bit register, or declare it as an integer variable (assuming this code is anyway for simulation-purposes only, not for synthesis).
Note that you also have other issues in your code. For instance you declare EWColor as a single bit, but still attempt to assign it to 2, and compare it against 2.

Related

FSM is double incrementing

I have a newbie FSM Verilog question. In the below code, around line 96, I am incrementing led_num with the non blocking led_num <= led_num+1; However, because of the way my code is setup I have a non blocking curr_state <= next_state at line 82, and then I am doing a next_state <= "NEXT STATE" in every one of my case statements. This is causing me to be in each state 2 clocks and is causing my led_num <= led_num+1 to execute twice, and I want just a single time.
How do I go about fixing this so I am in each state a single clock or how do I prevent the led_num being incremented by two each time? I had one person tell me to non blocking all of the time, but some examples mix them and I am pretty sure I need to move my nextState to use a blocking assignment but I have tried several things so far and I keep messing it up.
`timescale 1ns / 1ps
module ws2812_b(clk, rst, send_the_data, led_data_out);
input clk;
input rst;
input send_the_data;
output reg led_data_out;
parameter NUMBER_LEDS = 5;
parameter ADDRESS_BITS =8;
parameter NUM_BITS = 24;
parameter STATE_BITS = 4;
parameter T0_HIGH_0_COUNT = 6; // .35us (System clock = 12Mhz, 83.3 ns/cycle.
parameter T0_HIGH_1_COUNT = 16; // .9us
parameter CYCLE_COUNT = (T0_HIGH_0_COUNT+T0_HIGH_1_COUNT); //.9+.35
parameter RESET_COUNT = 1500; // 50us
localparam ST_IDLE = 4'd0,
ST_GET_WORD = 4'd1,
ST_SEND_START = 4'd2,
ST_UPDATE_WORD = 4'd3,
ST_DELAY_0 = 4'd4,
ST_DRIVE_0 = 4'd5,
ST_DELAY_1 = 4'd6,
ST_CHECK_WORD_DONE = 4'd7,
ST_SEND_RESET = 4'd8,
ST_NDEF_9 = 4'd9,
ST_NDEF_10 = 4'd10,
ST_NDEF_11 = 4'd11,
ST_DELAY_1S = 4'd12,
ST_NDEF_13 = 4'd13,
ST_NDEF_14 = 4'd14,
ST_NDEF_15 = 4'd15;
reg [STATE_BITS-1:0]currState;
reg [STATE_BITS-1:0]nextState;
reg [14:0] delay_value;
reg [NUM_BITS-1:0] led_word;
reg [5:0] bit_num;
reg [13:0] delay0, delay1;
reg [8:0] led_num;
`define rundelay currState <= ST_DELAY_1S
`define returndelay currState <= nextState
always #(posedge clk, posedge rst)
begin
if (rst) begin
currState <= ST_IDLE;
nextState <= ST_IDLE;
led_data_out <=0;
led_word <= 0;
bit_num <= 0;
delay0 <= 0;
delay1 <=0;
delay_value <=0;
led_num <= 0;
end
else
begin
currState <= nextState;
case (currState)
ST_IDLE: //0
begin
led_data_out <= 0;
nextState <= ST_GET_WORD;
led_num <= 0;
end
ST_GET_WORD: //1
begin
led_word <= 24'h335599;
bit_num <= 0;
nextState <= ST_SEND_START;
led_num <= led_num + 1 ; // ***** DOUBLE INCREMENTS ****
end
ST_SEND_START: //2
begin
led_data_out <= 1;
if (led_word[0]==1)
begin
delay0 <= T0_HIGH_1_COUNT;
delay1 <= (CYCLE_COUNT - T0_HIGH_1_COUNT + 1);
end else
begin
delay0 <= T0_HIGH_0_COUNT;
delay1 <= (CYCLE_COUNT - T0_HIGH_0_COUNT + 1);
end
nextState <= ST_UPDATE_WORD;
end
ST_UPDATE_WORD: //3
begin
led_word[23:0] <= {1'b0,led_word[23:1]};
bit_num <= bit_num+1;
nextState <= ST_DRIVE_0;
delay_value <= delay0;
`rundelay;
end
ST_DRIVE_0: //5
begin
led_data_out <= 0;
nextState <= ST_CHECK_WORD_DONE;
delay_value <= delay1;
`rundelay;
end
ST_CHECK_WORD_DONE: //4
begin
if (bit_num<24)
begin
nextState <= ST_SEND_START;
end else
begin
if (led_num<3)
begin
nextState <= ST_GET_WORD;
end else
begin
nextState <= ST_SEND_RESET;
end
end
end
ST_SEND_RESET:
begin
led_data_out <= 0;
nextState <= ST_IDLE;
delay_value <= 2000;
`rundelay;
end
ST_DELAY_1S: // Delay of ~1sec. Note that the total delay is one clock cycle more because of the state transition.
begin
if (delay_value)
begin
delay_value <= delay_value -1; // as long as delay_value is larger than zero ( bitwise or)
// decrement (decrementing counters synthesize smaller than
// incrementing counters as no comparator is needed, only a
// zero check which is a bitwise or.
currState <= currState;
end
else
begin
//currState <= nextState; // if it hits zero ; throw the target state into currentstate.
`returndelay;
end
end
default:
begin
currState <= ST_IDLE;
end
endcase
end
end
endmodule
As Greg pointed out, FSMs are implemented one of two ways:
Single always block (like you've implemented) In this case, every clock runs through the "always block" once and you only need one "State" variable. All variables are "non-blocking" ("<=" symbol) which implies that all statements are executed in parallel.
Double always blocks. In this case, the first always block is purely combinational, which is fully "blocking" assigns so that you can have sequential arithmetic to calcuate your final value. The second always block behaves like a set of registers to let the whole state-machine "step" to the next state on the clock edge. This setup requires "currState" and "nextState". The first combinational always block calculates "nextState" from "currState". The second (sequential) always block simply transfers nextState to currState on a clock edge.
In your case, it looks like you're trying to jump to a "delay" state for a certain number of cycles and then jump back to the next state in the sequence like a subroutine in C code that delays.
While I haven't run it, I think the following is closer to what you're trying to do. When you jump to ST_DELAY_1S, you need to save the state you want to return to in a separate variable (I used afterDelayState) so that you can spin in the delay state and then return (much like the instruction pointer on the stack) to the proper place.
`timescale 1ns / 1ps
module ws2812_b(clk, rst, send_the_data, led_data_out);
input clk;
input rst;
input send_the_data;
output reg led_data_out;
parameter NUMBER_LEDS = 5;
parameter ADDRESS_BITS =8;
parameter NUM_BITS = 24;
parameter STATE_BITS = 4;
parameter T0_HIGH_0_COUNT = 6; // .35us (System clock = 12Mhz, 83.3 ns/cycle.
parameter T0_HIGH_1_COUNT = 16; // .9us
parameter CYCLE_COUNT = (T0_HIGH_0_COUNT+T0_HIGH_1_COUNT); //.9+.35
parameter RESET_COUNT = 1500; // 50us
localparam ST_IDLE = 4'd0,
ST_GET_WORD = 4'd1,
ST_SEND_START = 4'd2,
ST_UPDATE_WORD = 4'd3,
ST_DELAY_0 = 4'd4,
ST_DRIVE_0 = 4'd5,
ST_DELAY_1 = 4'd6,
ST_CHECK_WORD_DONE = 4'd7,
ST_SEND_RESET = 4'd8,
ST_NDEF_9 = 4'd9,
ST_NDEF_10 = 4'd10,
ST_NDEF_11 = 4'd11,
ST_DELAY_1S = 4'd12,
ST_NDEF_13 = 4'd13,
ST_NDEF_14 = 4'd14,
ST_NDEF_15 = 4'd15;
reg [STATE_BITS-1:0] State;
reg [STATE_BITS-1:0] afterDelayState;
reg [14:0] delay_value;
reg [NUM_BITS-1:0] led_word;
reg [5:0] bit_num;
reg [13:0] delay0, delay1;
reg [8:0] led_num;
//`define rundelay currState <= ST_DELAY_1S
//`define returndelay currState <= nextState
always #(posedge clk, posedge rst)
begin
if (rst) begin
State <= ST_IDLE;
afterDelayState <= ST_IDLE;
led_data_out <=0;
led_word <= 0;
bit_num <= 0;
delay0 <= 0;
delay1 <=0;
delay_value <=0;
led_num <= 0;
end
else
begin
case (State)
ST_IDLE: //0
begin
led_data_out <= 0;
State <= ST_GET_WORD;
led_num <= 0;
end
ST_GET_WORD: //1
begin
led_word <= 24'h335599;
bit_num <= 0;
State <= ST_SEND_START;
led_num <= led_num + 1 ; // ***** DOUBLE INCREMENTS ****
end
ST_SEND_START: //2
begin
led_data_out <= 1;
if (led_word[0]==1)
begin
delay0 <= T0_HIGH_1_COUNT;
delay1 <= (CYCLE_COUNT - T0_HIGH_1_COUNT + 1);
end else
begin
delay0 <= T0_HIGH_0_COUNT;
delay1 <= (CYCLE_COUNT - T0_HIGH_0_COUNT + 1);
end
State <= ST_UPDATE_WORD;
end
ST_UPDATE_WORD: //3
begin
led_word[23:0] <= {1'b0,led_word[23:1]};
bit_num <= bit_num+1;
State <= ST_DRIVE_0;
delay_value <= delay0;
// delay "delay0" cycles and then jump to ST_DRIVE_0
delay_value <= delay0;
State <= ST_DELAY_1S;
afterDelayState <= ST_DRIVE_0;
end
ST_DRIVE_0: //5
begin
led_data_out <= 0;
// delay "delay1" cycles and then jump to ST_CHECK_WORD_DONE
delay_value <= delay1;
State <= ST_DELAY_1S;
afterDelayState <= ST_CHECK_WORD_DONE;
end
ST_CHECK_WORD_DONE: //4
begin
if (bit_num<24)
begin
State <= ST_SEND_START;
end else
begin
if (led_num<3)
begin
State <= ST_GET_WORD;
end else
begin
State <= ST_SEND_RESET;
end
end
end
ST_SEND_RESET:
begin
led_data_out <= 0;
// delay 2000 cycles and then jump to ST_IDLE
delay_value <= 2000;
State <= ST_DELAY_1S;
afterDelayState <= ST_IDLE;
end
// This is a special "delay" loop that jumps to a specified "afterDelayState" when the delay_value runs to zero
ST_DELAY_1S: // Delay of ~1sec. Note that the total delay is one clock cycle more because of the state transition.
begin
if (delay_value)
begin
// every clock cycle stay in the ST_DELAY_1S state until the "delay_value" runs to zero
delay_value <= delay_value -1; // as long as delay_value is larger than zero ( bitwise or)
// decrement (decrementing counters synthesize smaller than
// incrementing counters as no comparator is needed, only a
// zero check which is a bitwise or.
//
// no change in State, so we stay here
// State <= State
end
else
begin
//after it hits zero, jump to the state we stored in afterDelayState
State <= afterDelayState;
end
end
default:
begin
State <= ST_IDLE;
end
endcase
end
end
endmodule
In the code above, each state has only one State <= (new state) command.
We only assign the afterDelayState variable when jumping to the ST_DELAY_1S "subroutine" so we know where to go back to.
I took out the `defines to make all assignments more explicit.
One side recommendation is to install VSCode and iverilog so that you can do syntax checking, auto-formatting and compile checking inside the editor. This quickly helped me clean things up.

Failed to use "generate" for memory

I'm using Verilog-2001 with Vivado 2015.4. There is my code:
parameter SHIFT = 16;
wire integrators_reset;
reg [INTEGRATOR_WIDTH - 1 : 0] sum_mem [SHIFT - 1 : 0];
reg [SHIFT - 1 : 0] full_mem;
wire [SHIFT - 1 : 0] equal;
genvar i;
generate
for(i = 0; i < SHIFT; i = i + 1) begin
always #(negedge equal[i]) begin
if(integrators_reset) begin
sum_mem[i] <= 0;
full_mem[i] <= 0;
end
else begin
if(sum_mem[i] == INTEGRATOR_MAX)
full_mem[i] <= 1;
else
sum_mem[i] <= sum_mem[i] + 1;
end
end
end
endgenerate
There is the error:
ERROR: [DRC 23-20] Rule violation (MDRV-1) Multiple Driver Nets- Net sum_mem[0][0] has multiple drivers
If i'm not using "generate" all is fine. For example:
always #(negedge equal[0]) begin
if(integrators_reset) begin
sum_mem[0] <= 0;
full_mem[0] <= 0;
end
else begin
if(sum_mem[0] == INTEGRATOR_MAX)
full_mem[0] <= 1;
else
sum_mem[0] <= sum_mem[0] + 1;
end
end
And there is not errors during implementation.
This seems like a tool limitation. You should be able to assign different fixed elements of an unpacked array from different always blocks. One workaround would be to move the declaration of sum_mem into the generate block.
for(I = 0; I < SHIFT; i = i + 1) begin : block_name
reg [INTEGRATOR_WIDTH - 1 : 0] sum_mem;
always #(negedge equal[I]) begin
if(integrators_reset) begin
sum_mem <= 0;
full_mem[i] <= 0;
end
else begin
if(sum_mem[i] == INTEGRATOR_MAX)
full_mem[i] <= 1;
else
sum_mem <= sum_mem + 1;
end
end
end
Now you have block_name[0].sum_mem, block_name[1].sum_mem, but you can not access block_name with a variable index.

In verilog, how to double the high signal and keep the low signal same

the picture indicates what I want the output signal is: the high signal double and the low signal keep same.
I wrote the code like:
integer x=0, count_valid=1, count_down=0;
reg valid_1, valid_reg;
always#(posedge clk)
begin
if(tag==1) begin
if(valid) begin
count_valid <= count_valid +1;
x<=x+1;
valid_reg <= 1;
end
else begin
x<=0;
count_down <= count_down+1;
if(count_valid>0) begin
valid_reg <= 1;
count_valid <= count_valid -1;
end
else if(count_down>0) begin
valid_reg <= 0;
count_down <= count_down-1;
end
end
end
else begin
valid_reg <= valid;
if (valid) x<=x+1;
else x<=0;
end
valid_1 <= valid_reg;
end
valid is the original signal in the picture and valid_reg is the modified signal. the count_valid is used to count how many cycles for high and use it to sub one to achieve the doubling. then count_down is for counting the cycles of low signal. but I realized when valid high the valid_reg will high.
can anyone give me some idea how to make the low signal run same cycles in output signal? any idea is also great.
You didn't mention if the input signal was periodic or not. Given the fact that your output is stretched over time, if the input is not periodic, then you would need infinite storage to keep track of what the input signal looked like. If it is periodic, or quasi-periodic, you can do something like below.
Keep track of the high count and low count in one block, and generate the output signal in another block, using the current registered values of the counts. Getting the output's first edge to line up with the input's is kind of tricky, requiring a mux, selected depending on whether it's the first time through the loop or not.
integer count, count_q, countdown, countdown_q, outcount;
logic valid_q, valid_reg, out_q;
logic new;
always #(posedge clk or negedge reset_n)
begin
if(~reset_n)
begin
if(~reset_n)
begin
new <= 1;
valid_q <= 0;
count_q <= 0;
countdown_q <= 0;
end
else
begin
valid_q <= valid;
if(valid & ~valid_q)//rising edge
begin
count <= 1;
countdown_q <= countdown;
end
else if(~valid & valid_q)//falling edge
begin
new <= 0;
count_q <= count;
countdown <= 1;
end
else if(valid)
count <= count+1;
else
countdown <= countdown+1;
end
end
end
always #(posedge clk or negedge reset_n)
begin
if(~reset)
begin
outcount <= 0;
out_q <= 0;
end
else
begin
if(new & valid & ~valid_q)
begin
out_q <= 1;
outcount <= 2;//valid_reg is already high here
end
else
if(out_q && (outcount == (count_q<<1)))
begin
out_q <= 0;
outcount <= 1;
end
else if(~out_q && (outcount == (countdown_q)))
begin
out_q <= 1;
outcount <= 1;
end
else
outcount <= outcount + 1;
end
end
assign valid_reg = new? valid : out_q;//this gets your initial rising edge lined up

I2C master for tmp007 sensor module

I'm trying to create an I2C protocol in verilog to read data from a sensor (TMP007)then show the data received using led but to no avail. I've been trying to put led (eg. LED_GREEN[2] =1;) in the state to test the flow of the state. Only the LED_GREEN1 and LED_GREEN[0] are lighten up. So I guess the problem does occur in STATE_WACK2. Anyone can help?
module tmpi2c(
input wire clk,
input wire reset,
inout reg i2c_sda,
output wire i2c_scl,
output reg [17:0] LED_RED, // LED Red[17:0]
output reg [7:0] LED_GREEN
);
// write to device address 0x40, 0x01h
localparam STATE_IDLE = 0;
localparam STATE_START = 1;
localparam STATE_ADDR = 2;
localparam STATE_RW = 3;
localparam STATE_WACK = 4;
localparam STATE_DATA = 5;
localparam STATE_WACK2 = 6;
localparam STATE_ADDR2 = 7;
localparam STATE_RW2 = 8;
localparam STATE_WACK3 = 9;
localparam STATE_READ = 10;
localparam STATE_WACK4 = 11;
localparam STATE_READ2 = 12;
localparam STATE_WACK5 = 13;
localparam STATE_STOP = 14;
localparam STATE_DISPLAY = 15;
reg enable; //(r=1, w=0)
reg clki2c = 0;
reg [9:0]counter = 0; // 10-bit counter size
reg [9:0] timer = 0;
reg [7:0] state;
reg [6:0] addr;
reg [7:0] data;
reg [7:0] count;
reg [15:0] value =0;
reg [4:0] ge,shi,bai;
reg i2c_scl_enable =0;
assign i2c_scl = (i2c_scl_enable == 0) ? 1 : ~clki2c;
reg i2c_sda_en;
wire i2c_sda_in = i2c_sda ;
// counter size calculation according to input and output frequencies
parameter sys_clk = 50000000; // 50 MHz system clock
//parameter clk_out = 400000; // 0.4 MHz clock output
parameter clk_out = 200000; // 0.2 MHz clock output
//parameter clk_out = 1; // 1Hz clock output
parameter max = sys_clk / (2*clk_out); // max-counter size
//clock divider from 50Mhz to 0.4Mhz
always#(posedge clk or posedge reset)
begin
if(reset) begin
counter <=0;
clki2c <= 0;
end
else begin
if (counter < max) begin
counter <= counter + 1'd1;
end
else begin
counter <= 0;
clki2c <= ~clki2c;
end
end
end
//end clock divider
always#(posedge clki2c) begin
if (!i2c_sda_en) begin i2c_sda = i2c_sda ;
end else begin
i2c_sda = 1'bz;
end
if (reset == 1)
begin
state <= 0;
//i2c_sda <= 1;
//i2c_scl <= 1;
i2c_sda_en <= 1;// i2c_sda ==z;
addr <= 7'h40;
count <= 8'd0;
data <= 8'h01;
LED_RED[17:0] = 0;
LED_GREEN[7:0] = 0;
end
else begin
case(state)
STATE_IDLE: begin //idle
state <= STATE_START;
end
STATE_START: begin //start
i2c_sda_en <= 0;
state <=STATE_ADDR;
count <= 6;
end
STATE_ADDR: begin //msb address bit
LED_GREEN[0] =1;
i2c_sda <= addr[count];
if (count ==0) state <= STATE_RW;
else count <= count -1;
end
STATE_RW: begin
i2c_sda <=0; //write here
state <=STATE_WACK;
end
STATE_WACK: begin
i2c_sda_en <= 1;
if(i2c_sda_in==1)
begin
state <= STATE_WACK;
end
else
begin
state <= STATE_DATA;
end
count <= 7 ;
i2c_sda_en <= 0;
end
STATE_DATA: begin
LED_GREEN[1] =1;
i2c_sda <= data[count];
if (count == 0) state <= STATE_WACK2;
else count <= count -1;
end
STATE_WACK2: begin
i2c_sda_en <= 1;
if(i2c_sda_in==1)
begin
state <= STATE_WACK2;
end
else
begin
state <= STATE_ADDR2;
//LED_GREEN[1] =1;
end
count <= 6;
i2c_sda_en <= 0;
end
STATE_ADDR2: begin
LED_GREEN[2] =1;
i2c_sda <= addr[count];
if (count ==0) state <= STATE_RW2;
else count <= count -1;
end
STATE_RW2: begin
i2c_sda <=1; //read here
state <=STATE_WACK3;
end
STATE_WACK3: begin
i2c_sda_en <= 1;
if(i2c_sda_in==1)
begin
state <= STATE_WACK2;
end
else
begin
state <= STATE_READ;
end
count <= 15;
//i2c_sda_en <= 0;
end
STATE_READ: begin
LED_GREEN[3] =1;
value[count] <= i2c_sda_in;
if (count == 8) state<= STATE_WACK4;
else count <= count -1;
end
STATE_WACK4: begin
i2c_sda_en <= 0;
i2c_sda <=1; //Master should leave SDA high to terminate a single-byte read operation.
state <= STATE_READ2;
count <= 7;
i2c_sda_en <= 1;
end
STATE_READ2: begin
LED_GREEN[4] =1;
value[count] <= i2c_sda_in;
if (count == 0) state<= STATE_WACK5;
else count <= count -1;
end
STATE_WACK5: begin
i2c_sda_en <= 0;
i2c_sda <=1; //Master should leave SDA high to terminate a two-byte read operation.
state <= STATE_STOP;
end
STATE_STOP: begin
//i2c_sda <=1;
state <= STATE_DISPLAY;
end
STATE_DISPLAY: begin
LED_RED[17] = value[15];
LED_RED[16] = value[14];
LED_RED[15] = value[13];
LED_RED[14] = value[12];
LED_RED[13] = value[11];
LED_RED[12] = value[10];
LED_RED[11] = value[9];
LED_RED[10] = value[8];
LED_RED[9] = value[7];
LED_RED[8] = value[6];
LED_RED[7] = value[5];
LED_RED[6] = value[4];
LED_RED[5] = value[3];
LED_RED[4] = value[2];
LED_RED[2] = value[0];
LED_RED[3] = value[1];
//display delay
if (timer < 100000) timer <= timer+1;
else timer <= 0;
state <= STATE_IDLE;
end
endcase
end
end
endmodule

ERROR: HDLCompiler:806 ... Syntax error near "end"

I'm trying to make an I2C protocol on Verilog, and I was typing what this guy was typing (a video on YouTube that explains how to make a I2C BUS protocol)
module step1(
input wire clk,
input wire reset,
output reg i2c_sda,
output reg i2c_scl
);
//goal is to write to device addres 0x50, 0xaa
localparam STATE_IDLE = 0;
localparam STATE_START = 1;
localparam STATE_ADDR = 2;
localparam STATE_RW = 3;
localparam STATE_WACK = 4;
localparam STATE_DATA = 5;
localparam STATE_STOP = 6;
localparam STATE_WACK2 = 7;
reg [7:0] state;
reg [6:0] addr;
reg [7:0] data;
reg [7:0] count;
always #(posedge clk) begin
if (reset == 1) begin
state <= 0;
i2c_sda <= 1;
i2c_scl <= 1;
addr <= 7'h50;
count <= 8'd0;
data <= 8'haa;
end
else begin
case(state)
STATE_IDLE: begin //idle
i2c_sda <= 1;
state <= STATE_START;
end // end state idle
STATE_START: begin //start
i2c_sda <= 1;
state <= STATE_ADDR;
count <= 6;
end // end of state start
STATE_ADDR: begin // fisrt addres bit or the most significant adress bit
i2c_sda <= addr[count];
if (count == 0) state <= STATE_RW;
else count <= count - 1;
end // end of state ADDR
STATE_RW: begin // Read or Write opperation
i2c_sda <= 1;
state <= STATE_WACK;
end // end state RW
STATE_WACK: begin
state <= STATE_DATA;
count <= 7;
end // end of state WACK
STATE_DATA: begin
i2c_sda <= data[count];
if (count == 0) state <= STATE_WACK2;
else count <= count-1;
end // end of state DATA
STATE_WACK2: begin
state <= STATE_STOP;
end // end state WACK2
STATE_STOP: begin
i2c_sda <= 1;
state <= STATE_IDLE;
end // end of state STOP
end// end of case
end // end of the else
end // end of if
endmodule
But, when I try to compile, the following error pops out. I really don't understand why, because all end are correct (at least for me):
ERROR:HDLCompiler:806 - "/home/yunta23/Documentos/Digital1/VideosYou/primero/step1/step1.v" Line 97: Syntax error near "end".
A case statement requires the endcase keyword, not an end keyword. Change:
end// end of case
to:
endcase

Resources