zynq上用verilog实现单稳态电路

该单稳态verilog模块,要求触发当输入收到由低变高后,输出一个高电平。高电平的时间根据五个输入离散量值delaycount延时,总延时时间等于90us乘delaycount。模块输入包括reset#异步复位,clk为50Mhz。

Monostable,Verilog模块。该模块在检测到输入信号的上升沿后,会输出一个固定宽度的脉冲,脉冲宽度由delaycount参数控制。

```verilog

module monostable_pulse (

input wire clk, // 50MHz时钟

input wire rst_n, // 异步低电平复位

input wire trigger, // 触发信号输入

input wire [4:0] delaycount, // 延时计数(0-31)

output reg pulse_out // 脉冲输出

);

// ============================

// 参数定义

// ============================

// 50MHz时钟周期 = 20ns

// 90us = 90,000ns = 4500个时钟周期 (20ns * 4500 = 90us)

parameter CLK_PERIOD_NS = 20; // 时钟周期20ns

parameter BASE_DELAY_US = 90; // 基本延时90us

parameter BASE_CYCLES = 4500; // 90us对应的时钟周期数 (90,000ns / 20ns)

// ============================

// 内部信号定义

// ============================

reg trigger_d1, trigger_d2; // 触发器用于边沿检测

wire trigger_rising; // 上升沿检测信号

reg [15:0] counter; // 计数器(最大支持31*4500=139500 < 2^17)

reg state; // 状态机:0=空闲,1=脉冲输出

// ============================

// 上升沿检测

// ============================

always @(posedge clk or negedge rst_n) begin

if (!rst_n) begin

trigger_d1 <= 1'b0;

trigger_d2 <= 1'b0;

end else begin

trigger_d1 <= trigger;

trigger_d2 <= trigger_d1;

end

end

assign trigger_rising = trigger_d1 && !trigger_d2;

// ============================

// 状态机和控制逻辑

// ============================

always @(posedge clk or negedge rst_n) begin

if (!rst_n) begin

state <= 1'b0;

counter <= 16'd0;

pulse_out <= 1'b0;

end else begin

case (state)

// 空闲状态,等待触发

1'b0: begin

pulse_out <= 1'b0;

if (trigger_rising && (delaycount != 5'd0)) begin

state <= 1'b1;

counter <= BASE_CYCLES * delaycount - 1'b1; // 计算总延时周期数

pulse_out <= 1'b1;

end

end

// 脉冲输出状态

1'b1: begin

if (counter == 16'd0) begin

state <= 1'b0;

pulse_out <= 1'b0;

end else begin

counter <= counter - 1'b1;

pulse_out <= 1'b1;

end

end

default: begin

state <= 1'b0;

pulse_out <= 1'b0;

end

endcase

end

end

// ============================

// 断言(用于仿真调试)

// ============================

// synthesis translate_off

always @(posedge clk) begin

if (trigger_rising && (delaycount == 5'd0)) begin

display("\[WARNING\] %t: trigger received with delaycount=0, no pulse will be generated", time);

end

end

// synthesis translate_on

endmodule

```

模块功能说明:

  1. 输入输出接口

· clk:50MHz系统时钟(周期20ns)

· rst_n:异步低电平复位

· trigger:触发信号输入,检测上升沿

· delaycount[4:0]:延时倍数输入(0-31)

· pulse_out:脉冲输出信号

  1. 延时计算

· 基本延时单位:90us

· 50MHz时钟周期:20ns

· 90us对应的时钟周期数:90,000ns / 20ns = 4500个周期

· 总延时时间 = 90us × delaycount

· 总时钟周期数 = 4500 × delaycount

  1. 工作流程

  2. 在空闲状态(state=0)等待触发信号的上升沿

  3. 检测到上升沿后,检查delaycount是否为0:

· 如果为0,不产生脉冲(有警告信息)

· 如果非0,进入脉冲输出状态(state=1)

  1. 在脉冲输出状态,计数器从(4500×delaycount-1)递减到0

  2. 计数器归零后,返回空闲状态

  3. 使用示例

```verilog

// 实例化示例

monostable_pulse u_monostable (

.clk(clk_50m), // 50MHz时钟

.rst_n(sys_rst_n), // 系统复位

.trigger(btn_press), // 触发信号

.delaycount(5'd10), // 10倍延时 = 900us

.pulse_out(pulse) // 输出脉冲

);

```

  1. 仿真测试模块(可选)

```verilog

module tb_monostable_pulse;

reg clk;

reg rst_n;

reg trigger;

reg [4:0] delaycount;

wire pulse_out;

// 实例化被测模块

monostable_pulse dut (

.clk(clk),

.rst_n(rst_n),

.trigger(trigger),

.delaycount(delaycount),

.pulse_out(pulse_out)

);

// 时钟生成(50MHz)

initial begin

clk = 0;

forever #10 clk = ~clk; // 20ns周期

end

// 测试激励

initial begin

// 初始化

rst_n = 0;

trigger = 0;

delaycount = 5'd0;

// 复位释放

#100 rst_n = 1;

// 测试1:延时1倍(90us)

#200;

delaycount = 5'd1;

trigger = 1;

#40 trigger = 0;

// 测试2:延时5倍(450us)

#500000; // 等待500us

delaycount = 5'd5;

trigger = 1;

#40 trigger = 0;

// 测试3:delaycount=0的情况

#500000;

delaycount = 5'd0;

trigger = 1;

#40 trigger = 0;

#1000000;

$finish;

end

// 波形输出

initial begin

$dumpfile("monostable.vcd");

$dumpvars(0, tb_monostable_pulse);

end

endmodule

```

注意事项:

  1. 当delaycount=0时,模块不会产生脉冲输出(仿真时会显示警告)

  2. 最大延时时间:31 × 90us = 2.79ms

  3. 模块使用同步设计,适合在Zynq FPGA中实现

  4. 可根据需要调整BASE_DELAY_US参数来改变基本延时单位

相关推荐
xgbing15 小时前
在ubuntu中安装modelsim
fpga开发·modelsim
碎碎思19 小时前
SURF:SLAC 开源 FPGA 与 ASIC 通用 RTL 框架详解
fpga开发
FPGA小迷弟1 天前
FPGA在工业控制行业的应用,行业研究文章
fpga开发·制造·数据采集·fpga·工业控制
洋洋Young1 天前
【Xilinx FPGA】CLB SliceL 与 SliceM
fpga开发·xilinx·clb
集芯微电科技有限公司1 天前
PC1001超高频率(50HMZ)单通单低侧GaN FET驱动器支持正负相位配置
数据结构·人工智能·单片机·嵌入式硬件·神经网络·生成对抗网络·fpga开发
stars-he1 天前
FPGA学习笔记(8)以太网UDP数据报文发送电路设计(二)
网络·笔记·学习·fpga开发
FPGA_小田老师1 天前
FPGA例程(3):按键检测实验
fpga开发·verilog·vivado·led灯·按键测试
博览鸿蒙1 天前
想考研到电子类,未来从事 FPGA/IC方向,目前该怎么准备?
考研·fpga开发
m0_555762901 天前
FPGA + AD7768-4 实现数据采集的可能方案
fpga开发