单稳态多谐振荡器仿真
Monostable multivibrator simulation
monostable
模块实现了一个单稳态多谐振荡器。它接受三个输入(clk、reset、trigger)并输出一个 (pulse
).
触发输入触发模块。当被触发时,输出信号(pulse
)将切换到高电平一段时间的时钟滴答,然后return到低电平。输出信号的脉冲宽度可以通过 PULSE_WIDTH
参数设置,该参数表示信号应保持高电平的时钟周期。
现在,发生的事情是当它被触发时,立即输出信号 (pulse
) 变高。
触发后,输出信号 (pulse
) 应在 clk
的下一个有效边沿为高电平。可以做哪些改变?
module monostable(
input clk,
input reset,
input trigger,
output reg pulse = 0
);
parameter PULSE_WIDTH = 20;
reg [4:0] count = 0;
wire countReset = reset | (count == PULSE_WIDTH);
always @(posedge trigger, posedge countReset) begin
if (countReset) begin
pulse <= 1'b0;
end else begin
pulse <= 1'b1;
end
end
always @(posedge clk, posedge countReset) begin
if(countReset) begin
count <= 0;
end else begin
if(pulse) begin
count <= count + 1'b1;
end
end
end
endmodule
module monostable_tb();
reg clk;
reg reset;
reg trigger;
wire pulse;
parameter PULSE_WIDTH = 20;
monostable imonostable(.*);
initial begin
clk=0;
forever #50 clk=~clk;
end
initial begin
$monitor("trigger=%b pulse=%b, count = %0d",trigger,pulse,imonostable.count);
$dumpfile("monostable_tb.vcd");
$dumpvars(0,monostable_tb);
trigger=1'b0;
reset = 1'b0;
@(posedge clk) reset = 1'b1;
@(posedge clk) reset = 1'b0;
@(posedge clk) trigger=1'b1;
@(posedge clk) trigger=1'b0;
repeat(25) @(posedge clk);
$finish;
end
endmodule
如果需要 1 个时钟的同步延迟,则 运行 通过触发器输出。
module monostable(
input clk,
input reset,
input trigger,
output reg pulse = 0
);
parameter PULSE_WIDTH = 20;
reg [4:0] count = 0;
reg reg_pulse_temp;
wire countReset = reset | (count == PULSE_WIDTH);
always @(posedge trigger, posedge countReset) begin
if (countReset) begin
reg_pulse_temp <= 1'b0;
end else begin
reg_pulse_temp <= 1'b1;
end
end
always @(posedge clk, posedge countReset) begin
if(countReset) begin
count <= 0;
// reset the flop
pulse <= 0;
end else begin
if(pulse) begin
count <= count + 1'b1;
end
end
// flip flop
pulse <= reg_pulse_temp;
end
endmodule
这是一个简化的设计,它在输入触发脉冲后设置输出一个周期,并保持输出高电平 20 个周期:
module monostable(
input clk,
input reset,
input trigger,
output reg pulse = 0
);
parameter PULSE_WIDTH = 20;
reg [4:0] count;
always @(posedge clk, posedge reset) begin
if (reset) begin
pulse <= 1'b0;
end else if (trigger) begin
pulse <= 1'b1;
end else if (count == PULSE_WIDTH-1) begin
pulse <= 1'b0;
end
end
always @(posedge clk, posedge reset) begin
if(reset) begin
count <= 0;
end else if (pulse) begin
count <= count + 1'b1;
end
end
endmodule
它现在使用一个时钟信号,而不是 2 个。它还使用一个简单的复位信号,可以避免潜在的故障导致不需要的异步复位。
您还应该在测试台中使用非阻塞分配:
@(posedge clk) reset <= 1'b1;
@(posedge clk) reset <= 1'b0;
@(posedge clk) trigger<= 1'b1;
@(posedge clk) trigger<= 1'b0;
monostable
模块实现了一个单稳态多谐振荡器。它接受三个输入(clk、reset、trigger)并输出一个 (pulse
).
触发输入触发模块。当被触发时,输出信号(pulse
)将切换到高电平一段时间的时钟滴答,然后return到低电平。输出信号的脉冲宽度可以通过 PULSE_WIDTH
参数设置,该参数表示信号应保持高电平的时钟周期。
现在,发生的事情是当它被触发时,立即输出信号 (pulse
) 变高。
触发后,输出信号 (pulse
) 应在 clk
的下一个有效边沿为高电平。可以做哪些改变?
module monostable(
input clk,
input reset,
input trigger,
output reg pulse = 0
);
parameter PULSE_WIDTH = 20;
reg [4:0] count = 0;
wire countReset = reset | (count == PULSE_WIDTH);
always @(posedge trigger, posedge countReset) begin
if (countReset) begin
pulse <= 1'b0;
end else begin
pulse <= 1'b1;
end
end
always @(posedge clk, posedge countReset) begin
if(countReset) begin
count <= 0;
end else begin
if(pulse) begin
count <= count + 1'b1;
end
end
end
endmodule
module monostable_tb();
reg clk;
reg reset;
reg trigger;
wire pulse;
parameter PULSE_WIDTH = 20;
monostable imonostable(.*);
initial begin
clk=0;
forever #50 clk=~clk;
end
initial begin
$monitor("trigger=%b pulse=%b, count = %0d",trigger,pulse,imonostable.count);
$dumpfile("monostable_tb.vcd");
$dumpvars(0,monostable_tb);
trigger=1'b0;
reset = 1'b0;
@(posedge clk) reset = 1'b1;
@(posedge clk) reset = 1'b0;
@(posedge clk) trigger=1'b1;
@(posedge clk) trigger=1'b0;
repeat(25) @(posedge clk);
$finish;
end
endmodule
如果需要 1 个时钟的同步延迟,则 运行 通过触发器输出。
module monostable(
input clk,
input reset,
input trigger,
output reg pulse = 0
);
parameter PULSE_WIDTH = 20;
reg [4:0] count = 0;
reg reg_pulse_temp;
wire countReset = reset | (count == PULSE_WIDTH);
always @(posedge trigger, posedge countReset) begin
if (countReset) begin
reg_pulse_temp <= 1'b0;
end else begin
reg_pulse_temp <= 1'b1;
end
end
always @(posedge clk, posedge countReset) begin
if(countReset) begin
count <= 0;
// reset the flop
pulse <= 0;
end else begin
if(pulse) begin
count <= count + 1'b1;
end
end
// flip flop
pulse <= reg_pulse_temp;
end
endmodule
这是一个简化的设计,它在输入触发脉冲后设置输出一个周期,并保持输出高电平 20 个周期:
module monostable(
input clk,
input reset,
input trigger,
output reg pulse = 0
);
parameter PULSE_WIDTH = 20;
reg [4:0] count;
always @(posedge clk, posedge reset) begin
if (reset) begin
pulse <= 1'b0;
end else if (trigger) begin
pulse <= 1'b1;
end else if (count == PULSE_WIDTH-1) begin
pulse <= 1'b0;
end
end
always @(posedge clk, posedge reset) begin
if(reset) begin
count <= 0;
end else if (pulse) begin
count <= count + 1'b1;
end
end
endmodule
它现在使用一个时钟信号,而不是 2 个。它还使用一个简单的复位信号,可以避免潜在的故障导致不需要的异步复位。
您还应该在测试台中使用非阻塞分配:
@(posedge clk) reset <= 1'b1;
@(posedge clk) reset <= 1'b0;
@(posedge clk) trigger<= 1'b1;
@(posedge clk) trigger<= 1'b0;