Generating number sequence in verilog (automat)

937 views Asked by At

I was given a task to create verilog code that generates number sequence 323135343355.

It should be generated like automat so it has states and next number in sequence is generated according to its previous output.

Task should be done in two ways.

First one is that sequence is generated in eternity (solved that one, but still wonder can my code be reduced.)

Second one is when sequence is generated once output should be only one number that repeats (for example 32313534335511111111111111....) I tried this one by settinf if statment but default case always outputs 4 if all demands are not met.

//implementation
module prvi(
output reg [3:0] out,
input clk, restart
    );

reg [3:0] state;

    always@(posedge clk)
    begin
        if(restart)
        begin
            out<=3;
            state<=5;//state is set to 5 because previos number is 5
        end
        
        else
        begin
            case(out)
                3:begin
                    if(state==5)
                        begin
                            out<=2;
                            state<=2;//state is set to 2 because it is our output
                        end
                    else if(state==2)
                        begin
                            out<=1;
                            state<=1;//output is 1 so state is 1
                        end
                    else if(state==1)
                        begin
                            out<=5;
                            state<=0;//state is 0 because 5 already in use 0=STATE WHEN 3534
                        end
                    else if(state==0)
                        begin
                            out<=4;
                            state<=4;//output is 4 so state is 4
                        end
                    else if(state==4)
                        begin
                            out<=3;
                            state<=3;//output is 3 so state is 3 BUT STATE AT 4335
                        end
                    else if(state==3)
                        begin
                            out<=5;
                            state<=6;//5 ALREADY IN USE SO STATE=6 IS FOR 355
                        end
                    end
                2:begin
                    out<=3;
                    state<=2;
                end
                1:begin
                    out<=3;
                    state<=1;
                end
                5:begin
                    if(state==6)
                        begin
                            out<=5;
                            state<=3;
                        end
                    else if(state==3)
                        begin
                            out<=3;
                            state<=5;
                        end
                        else if(state==0)
                            begin
                                out<=3;
                                state<=0;
                            end
                    end
                4:begin
                    out<=3;
                    state<=4;
                end
                default:begin
                    out<=4;
                    state<=4;
                end
            endcase
        end
    end
endmodule

//test module
module test_prvi;

    // Inputs
    reg clk;
    reg restart;

    // Outputs
    wire [3:0] out;

    // Instantiate the Unit Under Test (UUT)
    prvi uut (
        .out(out), 
        .clk(clk), 
        .restart(restart)
    );

    initial begin
        // Initialize Inputs
        clk = 0;
        restart = 0;
        
        #60 restart=1;
        #9 restart=0;
        

        // Wait 100 ns for global reset to finish
        #200 $stop;
        
        // Add stimulus here

    end
    always begin
        #3 clk=~clk;
    end
      
endmodule
1

There are 1 answers

0
Serge On

but still wonder can my code be reduced

Here is a possible solution which reduces your code size: store the sequence in a variable and just retrieve what is needed every cycle, without creating a classic state machine:

module prvi(
            output reg [3:0] out,
            input            clk, restart
            );

   reg [48-1:0]              state;
   reg [3:0]                 count;

   always@(posedge clk)
     begin
        if(restart)
          begin
             count <= 0;
             state <= 48'h553343531323; // reverce of 323135343355
          end
        else if (count == 12)
          begin
             out <= 4'h1;
          end
        else
          begin
             count <= count + 1;
             out <= state & 4'hf;
             state <= state >> 4;
          end
     end
endmodule

To simplify code and demonstrate the concept I used right shift >> and for that reason reversed your sequence of numbers. When count reaches 12 (length of the sequence), the result will always be '1'. The signal width you need is 12 * 4 = 48, 4 bits per hex digit. Decimal digits are a subset of hex.

You can use direct sequences or two-dimensional arrays to achieve it.