【原创】FPGA设计技巧总结---第一节
0赞
发表于 7/4/2015 12:58:15 PM
阅读(2300)
受时序控制的脉冲信号或时钟信号或其他信号的正确运用,对我们的设计非常有帮助。接下来,介绍下我总结的几种信号的产生。
1)复位结束后,以固定时间(这里以5个时钟周期为例)产生脉冲信号,如图1所示:
图1
其相应的Verilog HDL实现如下所示:
`timescale 1ns/1ps module signal_gen1( rst_n, clk, flag ); // 输入/输出端口声明 input rst_n; input clk; output flag; // 参数声明 parameter [2:0] PERIOD = 5; // 产生脉冲的周期 // 变量定义 reg [2:0] cnt; // 计数器变量 // 计数器 always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin cnt <= 0; end else begin if(cnt==PERIOD-1'b1) cnt <= 0; else cnt <= cnt + 1'b1; end end // 脉冲信号的产生 assign flag = (cnt==PERIOD-1'b1)?1'b1:1'b0; endmodule
其modelsim仿真结果如图2所示:
图2
2)一个信号的起始电平为低电平,复位结束后再经过一段时间的延时后则保持高电平,如图3所示:
图3
其相应的Verilog HDL实现如下所示:
`timescale 1ns/1ps module signal_gen2( rst_n, clk, flag ); // 输入/输出端口声明 input rst_n; input clk; output flag; // 参数声明 parameter [2:0] DELAY = 5; // 延时常量 // 变量定义 reg [2:0] cnt; // 延时计数器变量 // 计数器 always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin cnt <= 0; end else begin if(cnt==DELAY) cnt <= DELAY; else cnt <= cnt + 1'b1; end end // 脉冲信号的产生 assign flag = (cnt==DELAY)?1'b1:1'b0; endmodule
其modelsim仿真结果如图4所示:
图4
3)复位后再经过一段时间的延时,再以固定时间产生脉冲信号(其实就是1)和2)的结合),如图5所示:
图5
其相应的Verilog HDL实现如下所示:
`timescale 1ns/1ps module signal_gen3( rst_n, clk, flag1 ); // 输入/输出端口声明 input rst_n; input clk; output flag1; // 参数声明 parameter [2:0] DELAY = 5; // 延时常量 parameter [2:0] PERIOD = 5; // 产生脉冲的周期 // 变量定义 reg [2:0] cnt1; // 延时计数器变量 reg [2:0] cnt2; // 脉冲计数器变量 // 延时完成标志 wire flag = (cnt1==DELAY)?1'b1:1'b0; // 计数器 always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin cnt1 <= 0; cnt2 <= 0; end else begin // 延时计数器 if(cnt1==DELAY) cnt1 <= DELAY; else cnt1 <= cnt1 + 1'b1; // 脉冲计数器 if(flag) begin if(cnt2==PERIOD-1'b1) cnt2 <= 0; else cnt2 <= cnt2 + 1'b1; end end end // 脉冲信号的产生 assign flag1 = (cnt2==PERIOD-1'b1)?1'b1:1'b0; endmodule
其modelsim仿真结果如图6所示:
图6
4)在系统整个运行过程中,只出现一个脉冲,如图7所示:
图7
其相应的Verilog HDL实现如下所示:
`timescale 1ns/1ps module signal_gen4( rst_n, clk, flag ); // 输入/输出端口声明 input rst_n; input clk; output flag; // 参数声明 parameter [2:0] DELAY = 5; // 延时常量 // 变量定义 reg [2:0] cnt; // 延时计数器变量 // 计数器 always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin cnt <= 0; end else begin if(cnt==DELAY) cnt <= DELAY; else cnt <= cnt + 1'b1; end end // 脉冲信号的产生 assign flag = (cnt==DELAY-1'b1)?1'b1:1'b0; endmodule
其modelsim仿真结果如图8所示:
图8
5)只有在满足一定的条件下,才能产生一定数量的脉冲或时钟信号,如图9所示,在cs为低电平时才有脉冲产生,而脉冲的产生由状态机来实现:
图9
其相应的Verilog HDL实现如下所示(第一:采用简单模型;第二:由于状态机比较小,这里采用一段式状态机):
`timescale 1ns / 1ps module signal_gen5( rst_n, clk, flag ); // 输入/输出端口声明 input rst_n; input clk; output flag; // 参数声明 parameter PERIOD = 1; // 产生脉冲的周期 parameter [2:0] PERIOD_CNT = 4; parameter [1:0] IDLE = 2'b00, DEAL = 2'b01, FINISH = 2'b10; // 变量定义 reg cnt1; // 计数器变量 reg [2:0] cnt2; // 计数脉冲个数 reg [1:0] state; // 状态机变量 reg cs; // 计数器 always @(posedge clk or negedge rst_n) begin if(rst_n==1'b0) begin state <= IDLE; cs <= 1'b1; cnt1 <= 0; cnt2 <= 0; end else begin case(state) IDLE : begin cs <= 1'b0; state <= DEAL; cnt1 <= 0; cnt2 <= 0; end DEAL : begin if(cnt1==PERIOD) cnt1 <= 0; else cnt1 <= cnt1 + 1'b1; // 计数脉冲个数,一旦检测到已产生一定数量的脉冲则状态转移 if(flag) begin if(cnt2==PERIOD_CNT-1'b1) begin cnt2 <= 0; cs <= 1'b1; state <= FINISH; end else begin cnt2 <= cnt2 + 1'b1; state <= DEAL; end end end FINISH : begin state <= IDLE; end default : begin state <= IDLE; end endcase end end // 脉冲信号的产生 assign flag = (cnt1==PERIOD)?1'b1:1'b0; endmodule
其modelsim仿真结果如图10所示:
图10
很多其他情况的信号均可由以上五种情况组合来产生。