0
votes

I have a Verilog module with the fowling input and outputs

  module Foo
    #(
        parameter DATA_BITS = 32,
        parameter ENUM_BITS = 8,
        parameter LED_BITS  = 8 
    )
    (
        //Module IO declarations
        input  logic    Clk_i,
        input  logic    Reset_i,
        input  logic    NoGoodError_i,
        input  logic    EncoderSignal_i,
        input  logic    [DATA_BITS-1:0]DistanceCount_i,
        //Enable the gate 
       output logic    GateEnable_o
   )

The overall design idea is the following. When I receive the positive edge of the NoGoodError_i start a counter and count up to the DistanceCount_i count via the positive edges of the EncoderSignal_i signal. That seems pretty straight forward, however my design challenge becomes that I could get another NoGoodError_i before I am finished counting the previous count. So, I need a way to get up to 10 NoGoodError_i signal in row and start counters. Then reuse the counters once they expire (Rollover). Please any design tips would be greatly appreciated.

1
It would help if you could explain the functionally of all your inputs. And is your clk input us the only signal that should be edge sensitive? The others are just level? - dave_59
Thank you so much for your reply: My Clk_i,Reset_i ,NoGoodError_i and EncoderSignal_i are edge signals. The counters will count up with the posedge of EncoderSingal_i. The DistanceCount_i is the stopping point for the counters. The GateEnable_o is indicate that counter has expired. - I. Aguilar
If you want to use just one counter instead of declaring multiple counters in your design, I could think of a FIFO to store the incoming positive edges at NoGoodError_i while you are counting. Then once your counter rolls over, you can check if the FIFO is empty or not. - wahab

1 Answers

1
votes

I would take an array of counters each with a 'busy' bit. If the bit is set the counter is running.

Next you use a modulo-10 index which busy bit to set.

I would raise a flag if the counter you want to start is still busy.


I just typed this in on the fly: not parsed for syntax and typos are possible (even likely):

reg [DATA_BITS-1:0] counter [0:9];
reg [9:0] busy;
reg [3:0] cntr_to_start;

always @(posedge Clk_i or posedge Reset_i)
begin
   if (Reset_i)
   begin
      busy <= 10'b0;
      for (i=0; i=<10; i=i+1)
         counter[i] <= 'b0;
      cntr_to_start <= 'b0;
   end
   begin

      // Run a counter if it's busy flag is set
      // At max (rollover) stop and clear the busy flag
      for (i=0; i<10; i=i+1)
      begin
         if (busy[i])
         begin
            if (counter[i]==(33'b1<<DATA_BITS)-1)
            begin
               counter[i] <= 1'b0;
               busy[i] <= 1'b0;
            end
            else
                counter[i] <= counter[i] + 1;
         end
      end

      // If no good start the next counter
      // If we have no next counter: ????
      if (NoGoodError_i)
      begin
         if (busy[cntr_to_start])
            // Houston: we have a problem!
            // More errors then we have counters
         else
         begin
            busy[cntr_to_start] <= 1'b1;
            if (cntr_to_start==9)
               cntr_to_start <= 'b0;
            else
               cntr_to_start <= cntr_to_start + 1;            
         end
   end
end