Estoy intentando implementar un contador ascendente y descendente síncrono en verilog con las siguientes reglas:
- El contador solo cambia en el flanco ascendente del reloj
- Cuando se restablece = 1, el conteo pasa a 00, operación normal cuando se restablece = 0
- el conteo está habilitado cuando en = 1 y deshabilitado cuando en = 0 cuenta hacia arriba cuando dir = 0 cuenta hacia atrás cuando dir = 1
- el conteo NO se ajusta. Cuando se realiza una cuenta regresiva, NO va de 00 a 11 (es decir, se mantiene en 00). Al contar, NO va de 11 a 00 (es decir, se mantiene en 11)
Hasta ahora mi código es:
module counter
(
input clock,
input reset,
input en,
input dir,
output reg [1:0] count
);
always @ (posedge clock) begin
if (reset==1'b1 || en==1'b0) begin
count=2'b0;
end
else if(en==1 && dir==0) begin //up count when dir=0
count <= count+1;
end
else begin //down count when dir=1
count <=count-1;
end
end
endmodule
Esto lo hace todo, excepto los envoltorios de conteo. ¿Cómo lo haría no envolver?
Testbench a continuación (los comentarios dicen lo que debería estar haciendo el código)
'timescale 1 ns / 1 ns // Time for each step, time precision
'define CLOCK_PERIOD 10
module main;
reg clock; // Free running clock
reg reset; // Input - reset
reg en; // Input - enable counting
reg dir; // Input - direction (0=up)
wire [1:0] count; // Output - Counter output
// Instantiate module
counter u1( clock, reset, en, dir, count );
initial // Done once at start up
begin
$display( "Up/Down Counter (no wrap)" );
$dumpfile( "dump.vcd" );
$dumpvars;
// Set initial values for inputs, asset reset
clock = 0;
reset = 1;
en = 0;
dir = 0;
// Turn off reset after one clock
#('CLOCK_PERIOD * 1)
reset = 0;
// Wait for a while to make sure it does not count
#('CLOCK_PERIOD * 2)
// Assert enable, should count up to 3 and stop
en = 1;
#('CLOCK_PERIOD * 5)
// Make sure does not count if we now deassert enable
en = 0;
#('CLOCK_PERIOD * 2)
// Set dir=1 but en=0, so should not change
dir = 1;
#('CLOCK_PERIOD * 2)
// Now enable, should count down and stop at 0
en = 1;
// Count back down, check if reset is ignored if not asserted
// at a clock edge
dir=1;
#7
reset = 1;
#6
reset = 0;
#('CLOCK_PERIOD * 5)
reset = 0;
// Leave time to stabilize
#('CLOCK_PERIOD * 4)
$finish;
end