# Verilog Down Counter Logic Implementation

fpgaverilog

I'm trying to write logic for storing trigger data. For example, I'm using a 3-bit counter as an address generator to store data samples. When I have a trigger event, I want to store the 4 data samples just before the trigger event occurred and the 4 after wards. So I use a 2-bit down counter when the trigger occurs and stops the counter when it counts down to 0 thus giving me 4 data samples from before the trigger and 4 data samples after the trigger.
I'm having trouble implementing this though and get only 3 addresses once I start the down counter and it counts down to 0

``````//=== 8-bit wide loadable up-counter =============================
`timescale 1 ns / 1 ps

module fw_up_counter_3 (tc, count, d, ld, en, clk, rst);

output          tc;
output  [2:0]   count;
input   [2:0]   d;
input           ld, en, clk, rst;
reg     [2:0]   l_count;
wire            tc;

assign  tc      = &count[2:0];
assign  count   = l_count ;

always @(posedge clk)
begin
if(rst)
l_count <=      3'b0;
else if(ld)
l_count <=      d;
else if (en & ~ld)
l_count <=      l_count + 1;
else
l_count <=      l_count;
end
endmodule

module fw_dn_counter_1(tc, count, en, ld, clk, rst);
output tc;
output [1:0] count;
input en, clk, rst, ld;
reg [1:0] l_count;
reg [1:0] d = 2'b11;
wire tc;

assign tc = ~|count[1:0];
assign count = l_count;

always@(posedge clk)
begin
if (rst)
l_count <= 2'b11;
else if (ld)
l_count <= d;
else if(en & ~ld & ~tc)
l_count <= l_count - 1;
else if (l_count == 2'b00)
l_count <= 2'b00;
else
l_count <= l_count;
end
endmodule

module trig_test(clk, tc1, tc2, en1, en2, count1, count2, rst, ld, trig, trig_loc);
input clk, rst, en1, en2, ld;
output [2:0] count1;
output [1:0] count2;
output tc1, tc2;
input trig;
output reg [2:0]trig_loc;

fw_up_counter_3 counter1(.tc(tc1), .count(count1), .d(3'b000), .ld(ld), .en(~tc2), .clk(clk), .rst(rst));

fw_dn_counter_1 counter2(.tc(tc2), .count(count2), .en(trig) , .ld(ld), .clk(clk), .rst(rst));

always@(posedge trig)
begin
trig_loc <= count1;
end

endmodule
`````` Anyone have any ideas on where I'm going wrong ?

`counter2` is reset to state 11. When the `trig` rising edge occurs, it starts counting down.
Your code shows no way to ensure that the `trig` edge is syncronized with your `clk` signal. In your simulation, `trig` goes high very shortly before a `clk` rising edge. So on that edge, `counter2` starts counting down --- going to the 10 state. But in between the `trig` edge and the `clk` edge, you did have a brief period where `counter2` was in the 11 state. So you did in fact have `counter2` in 4 different states after the trigger edge.
If you want to be sure to keep the counter in the 11 state for at least one full `clk` cycle after the trigger, you could either syncronize `trig` to `clk`, or delay the input to the counter `en` input for one cycle after the trigger is seen (essentially the same thing, but making a new syncronized signal).