Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

Verilog XOR issue

Altera_Forum
Honored Contributor II
1,689 Views

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
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
992 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
992 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
992 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
992 Views

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
0 Kudos
Reply