0
\$\begingroup\$

I'm using Altera Cyclone IV EP4CE6 as my FPGA. Compiling the design in Quartus Prime 18.0.0 Lite Edition.

The State register in the below module appears to be 0 initially even if I specify a different default value (I.e. if I set ST_INITIALWAIT to anything but 0 it doesn't work).

I've tried specifying the default value inline with the definition and in an initial block.

Non-zero initial register values work fine in other modules in the same design, so I'm puzzled why it doesn't in this module.

module CamSetup(clk, ready, error, scl, sda);
input clk;
output ready, error;
output scl;
inout sda;

parameter ST_READY = 4'd1;
parameter ST_WRITING = 4'd2;
parameter ST_ENDING = 4'd3;
parameter ST_INTERIM = 4'd4;
parameter ST_INITIALWAIT = 4'd0;

parameter REG_COUNT = 1;

//truncated to save space (actually updates 170 registers)
bit [1:REG_COUNT][0:2][7:0] RegValues = {
    8'h42, 8'h7a, 8'h20 
};

parameter CLKS_INIT = 10;
parameter CLKS_INTERIM = 50000;

reg [23:0] InitiCounter = 0;
reg [23:0] InterimCounter = 0;

reg [3:0] State = ST_INITIALWAIT;
reg [7:0] RegIndex  = 0;
reg [2:0] RegByteIndex  = 0;
reg [7:0] WrData = 0;

wire WrDataRq;
wire I2cIdle;
wire Enable = (State == ST_WRITING);
assign ready = (State == ST_READY);


i2c i2c0(.clk(clk), .enable(Enable), .wr_data(WrData), .wr_data_rq(WrDataRq), .idle(I2cIdle), .error(error), .scl(scl), .sda(sda));

always @(posedge clk)
begin

    case(State)

    ST_INITIALWAIT:
    begin
        InitiCounter <= InitiCounter + 1;

        if(InitiCounter >= CLKS_INIT)
        begin
            State <= ST_ENDING;
        end     
    end

    ST_ENDING:
    begin
        if(I2cIdle)
        begin           
            if(RegIndex < REG_COUNT)
            begin
                RegIndex <= RegIndex + 1;
                RegByteIndex <= 0;              
                WrData <= RegValues[RegIndex+1][0];
                State <= ST_INTERIM;
            end
            else
            begin
                State <= ST_READY;
            end         
        end
    end

    ST_INTERIM:
    begin
        InterimCounter <= InterimCounter + 1;

        if(InterimCounter >= CLKS_INTERIM)
        begin
            InterimCounter <= 0;
            State <= ST_WRITING;
        end
    end

    ST_WRITING:
    if(WrDataRq)
    begin       
        if(RegByteIndex < 2)
        begin
            RegByteIndex <= RegByteIndex + 1;
            WrData <= RegValues[RegIndex][RegByteIndex+1];
        end
        else
        begin
            State <= ST_ENDING;
        end
    end         

    endcase

end

endmodule
\$\endgroup\$
0
\$\begingroup\$

I believe in Quartus, the initial value in a declaration only works for simulation. For Synthesis (and simulation), you need to use a separate initial block.

initial begin
    State = non_zero_state;
    ...
\$\endgroup\$
  • \$\begingroup\$ Tried both the initial block and the inline. The inline works just fine in other modules in the same design. \$\endgroup\$ – axk Feb 17 at 21:04
  • 1
    \$\begingroup\$ Then for a state machine, you may need a reset. \$\endgroup\$ – dave_59 Feb 17 at 21:05
  • \$\begingroup\$ I've made the initial state 0 and it works fine, just curious why the non-zero values didn't work in this case. \$\endgroup\$ – axk Feb 17 at 21:07
  • 1
    \$\begingroup\$ Like I said, for registers recognized as FSM state variables, you need an explicit reset to get a value other than 0 as an initial state \$\endgroup\$ – dave_59 Feb 18 at 1:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.