user3776279
user3776279

Reputation: 1

Reset variable in a sequential case statement in verilog

I want to give only one strobe pulse of 2 clock cycles wide everytime a data is placed on the output. I am not able to implement the logic in verilog.Here is the pseudocode i have written

reg [1:0] step = 2'b00;
always @ (posedge clock)
begin    
case (switch)
1'b0 : begin        
       load data 1;
       flag <= 1;
   end
1'b0 : begin        
       load data 2;
       flag <= 1;
       end    
endcase

if (flag == 1)
case (step)
2'b00 : strobe high;
2'b01 : wait;
2'b10 : strobe low;
2'b11 : flag <=0;   
endcase 
end

If I do this the reg step is becoming 2'b11 after properly giving the strobe pulse after the first data, but I am not able to reset it to zero again for the second data, so when second time flag is set high the step variable only enters the last case. If I set step <= 2'b00 elsewhere the strobe output is constantly changing with each clock cycle. I want only one pulse.

Actual Code :

`timescale 1ns / 1ps

module test3(
input i_clock,
input i_switch,
output reg [7:0] o_data = 8'b00001111,
output reg o_strobe = 1'b0
);

reg flag = 1'b0;
reg [1:0] step = 2'b00;

always @ (posedge i_clock)
begin
  if (flag == 1'b0)
    begin
      case (i_switch)                                 
        1'b0  :  begin
                   o_data [7:0] <= 32'b00000000;
                   flag <= 1'b1;
                 end
        1'b1  :  begin
                   o_data [7:0] <= 32'b11111111;
                   flag <= 1'b1;
                 end
      endcase
    end
else if (flag == 1)
      begin
        case (step)
          2'b00  :  begin
                      o_strobe <= 1'b1;
                      step <= 2'b01;
                    end
          2'b00  :  begin
                      step <= 2'b10;
                    end
          2'b10  :  begin
                      o_strobe <= 1'b0;
                      step <= 2'b11;
                    end
          2'b11  :  begin
                      flag <= 1'b0;
                      // step <= 2'b00;
                    end
       endcase
    end
  end
endmodule

Waveforms: No strobe on 2nd data, step <= 2'b00 commented

http://i30.photobucket.com/albums/c315/soumyabumba/strobe_zpsc342b740.gif

 photo strobe_zpsc342b740.gif

Continuous toggling strobe, step <= 2'b00 uncommented

Strobe toggling photo pulse_strobe_zps8a1a5fb4.gif

http://i30.photobucket.com/albums/c315/soumyabumba/pulse_strobe_zps8a1a5fb4.gif

Upvotes: 0

Views: 2758

Answers (1)

user3776279
user3776279

Reputation: 1

Thank a lot Tim. I solved it and its only because of your helpful suggestion to add the flag and step waveforms. The main problem was that the case(switch) is getting executed on each clock cycle with the switch value of previous cycle and it is triggering the flag which is there under each statement. So I removed the case(i_switch) from always @ (i_clock) and put it separately in an always @ (i_switch) so that the case(switch) runs only when the switch is changed.

I am facing a minor problem though. Since I have added the always@(i_switch) block I am having doubts on initializing the i_switch input in the test bench file. If I initialize it before the global reset of 100# the o_data is starting as 00000000 instead of 00001111 i.e. the case statement started running even before the global reset completes. If i give i_switch as a stimulus after 100# a red line and a X is coming for i_switch for 100# indicating uninitialized input. I have attached the waveform and the solved code. Will there be any problem in implementation of this? Also I read somewhere all if statement must follow by else statement otherwise unwanted latching may occur, what can be written under else (flag == 0) condition under always @(i_clock)?

Waveform :

http://i30.photobucket.com/albums/c315/soumyabumba/strobe_solved_zps72b65a42.png

Solved Code:

`timescale 1ns / 1ps

module test3(
input i_clock,
input i_switch,
output reg [7:0] o_data = 8'b00001111,
output reg o_strobe = 1'b0
);

reg flag = 1'b0;
reg [1:0] step = 2'b00;

always @ (i_switch)
begin
    case (i_switch)                                 
    1'b0  :  begin
               o_data [7:0] <= 32'b00000000;
               flag <= 1'b1;
             end
    1'b1  :  begin
               o_data [7:0] <= 32'b11111111;
               flag <= 1'b1;
             end
    endcase
end

always @ (posedge i_clock)
begin
if (flag == 1)
  begin
    case (step)
      2'b00  :  begin
                  o_strobe <= 1'b1;
                  step <= 2'b01;
                end
      2'b01  :  begin
                  step <= 2'b10;
                end
      2'b10  :  begin
                  o_strobe <= 1'b0;
                  step <= 2'b11;
                end
      2'b11  :  begin
                  flag <= 1'b0;
                  step <= 2'b00;
                end
   endcase
end
end
endmodule

Upvotes: 0

Related Questions