Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

Verilog XOR issue

Hi All,

I have a working piece of code :

if(in_I & in_Q) cnt <= cnt + `INC_SIZ;

if(in_I & !in_Q) cnt <= cnt - `INC_SIZ;

if(!in_I & in_Q) cnt <= cnt - `INC_SIZ;

if(!in_I & !in_Q) cnt <= cnt + `INC_SIZ;

in an attempt to be clever, I changed it to

if(in_I ^ in_Q) begin cnt <= cnt + `INC_SIZ; end

else begin cnt <= cnt - `INC_SIZ; end

which stopped working.

in_I and in_Q are single bit input ports.

What am I doing that is daft, the logic looks OK to me.

Thanks,

Mark

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I don't know. I use a similar construct with ^ operator and it works.

    Did you try if(in_I != in_Q) ? It should be the same.

    I'm assuming all this is in a always@(posedge clk) block. Is this correct?

    Or maybe is always@(in_I or in_Q) ?

    Just a remark: I'm rather concerned about the first piece of code (working).

    I'd have written it: if... else if...else if... else
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Your first logic is equivalent to this below:

    if(in_I ^ in_Q) begin cnt <= cnt - `INC_SIZ; end

    else begin cnt <= cnt + `INC_SIZ; end
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi guys,

    Thanks for your thoughts.

    I tried changing xor to == and != without success.

    Here are the full modules.

    All I am doing is building an up/down counter based on inputs from an I/Q rotary shaft encoder. I and Q do not change together.

    There are two cascaded meta stability D latched between this module and the hardware.

    I am not worried about direction of count and the final output assignments are just sample probes at the moment.

    One module works, the other does not.

    Compilation size is also different - I was expecting them to compile to same code.

    Regards,

    Mark

    ========= works

    //-----------------------------------------------------

    // IQ counter

    //-----------------------------------------------------

    module IQ_ctr(in_I, in_Q, clk, out_0, out_1);

    `define INC_SIZ 16'd125

    //----------Output Ports--------------

    output out_0;

    output out_1;

    //------------Input Ports--------------

    input in_I, in_Q, clk;

    //------------Internal Variables--------

    reg out_0;

    reg out_1;

    reg [16:0] cnt;

    reg last_I;

    reg last_Q;

    //-------------Code Starts Here-------

    always @(posedge clk)

    begin

    if(in_I ^ last_I) // I changed

    begin

    if(in_I & in_Q) cnt <= cnt + `INC_SIZ;

    if(in_I & !in_Q) cnt <= cnt - `INC_SIZ;

    if(!in_I & in_Q) cnt <= cnt - `INC_SIZ;

    if(!in_I & !in_Q) cnt <= cnt + `INC_SIZ;

    end

    if(in_Q ^ last_Q) // Q changed

    begin

    if(in_Q & in_I) cnt <= cnt - `INC_SIZ;

    if(in_Q & !in_I) cnt <= cnt + `INC_SIZ;

    if(!in_Q & in_I) cnt <= cnt + `INC_SIZ;

    if(!in_Q & !in_I) cnt <= cnt - `INC_SIZ;

    end

    last_I <= in_I;

    last_Q <= in_Q;

    out_0 = cnt[15];

    out_1 = cnt[14];

    end

    endmodule

    ========= does not work

    //-----------------------------------------------------

    // IQ counter

    //-----------------------------------------------------

    module IQ_ctr(in_I, in_Q, clk, out_0, out_1);

    `define INC_SIZ 16'd125

    //----------Output Ports--------------

    output out_0;

    output out_1;

    //------------Input Ports--------------

    input in_I, in_Q, clk;

    //------------Internal Variables--------

    reg out_0;

    reg out_1;

    reg [16:0] cnt;

    reg last_I;

    reg last_Q;

    //-------------Code Starts Here-------

    always @(posedge clk)

    begin

    if(in_I ^ last_I) // I changed

    begin

    if(in_I != in_Q) cnt <= cnt - `INC_SIZ;

    else cnt <= cnt + `INC_SIZ;

    end

    if(in_Q ^ last_Q) // Q changed

    begin

    if(in_I != in_Q) cnt <= cnt + `INC_SIZ;

    else cnt <= cnt - `INC_SIZ;

    end

    last_I <= in_I;

    last_Q <= in_Q;

    out_0 = cnt[15];

    out_1 = cnt[14];

    end

    endmodule
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Arrgh, busted hardware !

    That was quite a waste of a few hours.

    The problem really smelt like a compiler bug.

    Change to new hardware and everything looks OK.

    Regards,

    Mark