Ya que etiquetó su pregunta con verilog , asumiré que realmente estás buscando una solución HDL dirigida a un FPGA. En este caso, usar un único divisor programable tiene mucho más sentido que tener múltiples divisores seguidos de un multiplexor. Algo como esto:
module clockdiv (
input master_clock,
input reset,
input [1:0] select,
output reg clock_out
)
reg [15:0] divider;
always @* begin
case (select)
2'b00: divider <= X; // defined elsewhere
2'b01: divider <= Y; //
2'b10: divider <= Z; //
2'b11: divider <= W; // ... etc.
endcase
end
reg [15:0] counter;
always @(posedge master_clock) begin
if (reset) begin
counter <= 0;
clock_out <= 0;
end else begin
if (counter >= divider) begin
counter <= 0;
clock_out <= !clock_out;
end else begin
counter <= counter + 1;
end
end
end
endmodule
Defina X
, Y
, Z
, etc. para obtener los índices de división de reloj que está buscando, teniendo en cuenta que el reloj de salida se divide por 2 para producir una onda cuadrada.
Esta solución nunca producirá un pulso de reloj malo, incluso si la entrada select
cambia en medio de un ciclo de salida.
Abordando su problema secundario de controlar las líneas de selección, la clave aquí es llevar las dos señales de pulsador de rebote al mismo dominio de reloj que el resto de la lógica. Algo como esto:
module up_down (
input master_clock,
input reset,
input button_up,
input button_down,
output reg [1:0] count
)
// Synchronizers and edge detectors for asynchronous inputs
reg button_up_a, button_up_b, button_up_c;
reg button_down_a, button_down_b, button_down_c;
always @(posedge master_clock) begin
button_up_a <= button_up;
button_up_b <= button_up_a;
button_up_c <= button_up_b;
button_down_a <= button_down;
button_down_b <= button_down_a;
button_down_c <= button_down_b;
if (reset) begin
count <= 0;
end else begin
if (button_up_b && !button_up_c) begin
//rising edge on button_up detected
count <= count + 1;
end else if (button_down_b && !button_down_c) begin
//rising edge on button_down detected
count <= count - 1;
end
end
end
endmodule
Conecte la salida count
de este módulo a la entrada select
del módulo anterior.