Forum Discussion

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

OR condition acts like an AND in Verilog?

Short Version:

I have an input to a module and a wire within the module. When either of these are TRUE, I want something to happen. However, only when the input is fixed TRUE and the wire flips to TRUE do I get the behavior I want. So the OR is acting like an AND. The code snippet is


input hard_reset;
wire timer_reset;
assign max_reset = (timer_reset | hard_reset);

but I only get things to work like I want them to when hard_reset is fixed high, then things are controlled just by timer_reset. Thus, it is an AND. Any idea what is happening?

Long Version:

I am writing code to do pulse counting with the MegaWizard LPM-Counter function. I have two counters, one counting incoming pulses to my DE2 board and another counting clock 50MHz clock cycles up to 5,000,000, giving me a timing system for 1/10th of a second. Each time the clock counter reaches 5,000,000, I store the count on the pulse counter and reset both counters in order to count pulses for the next 1/10sec.

The weird thing happens when I want to include a hard reset. I want to be able to reset both counters manually if I need to. So I have the code:


module mokango_counter(hard_reset, pulse_in, count);
//define inputs and outputs
input hard_reset;
input pulse_in;
output  count;
//define extra needed signals
wire max_reset;
wire  timer_count;
wire  pulse_count;
reg timer_reset;
reg save_data;
//Define reset conditions
assign max_reset = (timer_reset | hard_reset);
//Do counting
counter time(.aclr(max_reset), .clock(CLOCK_50), .q(timer_count));
counter pulse(.aclr(max_reset), .clock(pulse_in), .q(pulse_count));
//check if we've reached our max time limit
always @(timer_count)
begin
if(timer_count==5000000) begin
timer_reset <= 1;
save_data <= 1;end
else begin
timer_reset <= 0;
save_data <= 0;
end
end
//Save counted data when necessary.
always @(save_data, pulse_count)
begin
if(save_data) count_out <= pulse_count;
end
//write output
assign count = count_out;
endmodule

I want the counters to reset on either me telling it to reset (hard_reset_ or 1/10sec has elapsed (timer_reset), which is what the red code line above should do, I think. But this isn't what it does do. Instead, it only updates counts when hard_reset is set to 1. If I set hard_reset to be controlled by a button on my DE2 board, it will only show me update counts (by linking the output count to the LED lights on the board) when I am holding down the button. So the system only updates when, as far as I can tell, max_reset is 1.

I've tried to change the code by changing max_reset to a reg and putting it into an always statement that checks hard_reset and timer_reset via if statements and assigns max_reset a value directly, but that gives me the same behavior.

The only time I can get the code to work correctly is if I drop the hard_reset condition from the red line and only have max_reset controlled by timer_reset, but of course then I lose the ability to reset on demand.

What is my mistake and how might I fix it?

3 Replies

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

    Your mistake might be you have not done any simulation or signaltap. So it could be just wrong observation

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

    The code doesn't register save_data in a reliable way. The latch must be expected to react on glitches in the counter output. Don't jump into conclusions about Verilog from a bad synchronous hardware description.

    I also notice that you don't show compilable code, CLOCK_50 is e.g. undefined. Thus the original code may have additional issues.

    The save count block should at minimum use a synchronous @posedge CLOCK_50 condition. But there may be still a problem of synchronizing pulse_in to CLOCK_50, which goes beyond the scope of this thread, however.