fpga 语法

数据与位宽不匹配,数据长则舍弃最高位,位宽大则前面补0

0 1 z(高阻态) x(未知状态)

wire 线连接  

reg  寄存器(always组合逻辑只能用reg)

=阻塞赋值 ,执行结束之后才执行下面语句

<=非阻塞赋值

归约运算 是第一步先用操作数的第一位和第二位进行位操作,然后再用第一步的结果和操作的数的下一位  进行位操作,如此重复直到最后一位。

将8bit的a、3bit 的 b、5bit的c按顺序拼接成一个16位的d,表示方法为: d = {a, b,c}:
时间单位和时间精度由值1、10、和100以及单位s、ms、us、ns、ps 和fs组成。

1s = 1000ms        1ms = 1000μs        1μs = 1000ns        1ns = 1000ps

#10   代表延时10个时间单位

时间精度:决定时间相关量的精度及仿真显示的最小刻度。
'timescale 1ns/10ps精度0.01,#10.11表示延时10110ps。

系统函数

打印输出

$display  可以自动换行

$write  需要写换行符 \n

$strobe  只能最后执行

$monitor  检测变量变化,只有变化才能打印

时间函数

$time返回时间

$random 返回随机数

$readmemb用于读二进制文件函数 

$readmemb ("<数报文件名>",<存贮器名>);  把数报文件名赋给存贮器

$readmemh 用于读十六进制文件函数
 

向量表示      : reg [7:0] count
一维数组表示  : reg count [7:0] (默认每个元素位宽为一)
                reg [7:0] count [3:0] 4个位宽为8元素的一维数组
二维数组      :reg [7:0] count [3:0][3:0] 可以看作矩阵
 

奇、偶分频

偶分频

module  divider_six
#(
    parameter    CNT =  2'd2)
(
    input   wire    sys_clk    	,  
    input   wire    sys_rst  	,  

    output  reg      clk_out		                                              
);
reg	[1:0]	cnt;//012
//reg	cnt_flag;
always@(posedge sys_clk or negedge sys_rst)
    if(sys_rst == 1'b0)
		cnt=2'b0		;
    else    if(cnt==CNT)
		cnt=2'b0		;     
    else
		cnt=cnt+2'b1	;

always@(posedge sys_clk or negedge sys_rst)
    if(sys_rst == 1'b0)
		clk_out=1'b0		;
    else    if(cnt==CNT)
		clk_out=	~clk_out	;      
    else
		clk_out=	clk_out		;		
		
endmodule

奇分频  1、数到5,cnt_flag标志

                2、奇分频,上升沿下降沿各一次,然后两个结果或运算

always@(posedge sys_clk or negedge sys_rst)

always@(negedge sys_clk or negedge sys_rst)

x<<n使用的是逻辑移位运算符,其对包括符号位在内的所有位进行移位操作;(乘除法)
x<<<n使用的是算术移位运算符,其只对非符号位的进行移位操作,而符号位保持不变。

4’b1001<<1 = 5’b10010;

4’b1001<<2 = 6’b100100;

1<<6 = 32’b1000000;

4’b1001>>1 = 4’b0100;

4’b1001>>4 = 4’b0000;

逻辑左移(<<):低位补0

逻辑右移(>>):高位补0

算数左移(<<<):低位补0

算数右移(>>>):对于有符号数,高位补符号位;对于无符号数,高位补0

下降沿、上升沿寻找,除了打一拍之外的操作

//寻找busy的下降沿
reg		[1:0]	busy_reg;
wire			busy_neg;
always@(posedge CLK_OUT or negedge sys_rst)
    if(sys_rst == 1'b0)
		busy_reg<=2'd0;  
    else
		busy_reg<={busy_reg[0] , busy};
assign	busy_neg=(!busy)&busy_reg[0];
wire	read_done;
reg	[1:0]	read_done_reg;
always@(posedge sys_clk or negedge sys_rst)
    if(sys_rst == 1'b0)
		read_done_reg<=2'd0;
    else
		read_done_reg<={read_done_reg[0],read_done};
assign	read_done_pos=(!read_done_reg[0])&read_done;

以太网

 发送数据时钟,先发送低位,再发送高位,4位4位的发送;接收时序也是一样;

关于txc核rxc的时钟是根据开发板的通信速率/4得到的,因为一个时钟传4位

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于 FPGA 对四位动态数码管的控制,我们需要通过时序逻辑来实现。这里给出一个简单的例子,假设我们的 FPGA 时钟频率为 50MHz,我们希望每秒钟数码管显示一次数字。我们可以考虑使用一个计数器来计时,当计数器达到一定值时,就更新数码管的显示内容。 下面是一个简单的 Verilog 代码实现: ``` parameter CLK_FREQ = 50000000; // FPGA 时钟频率 parameter DISPLAY_FREQ = 1; // 数码管刷新频率 parameter REFRESH_COUNT = CLK_FREQ / (4 * DISPLAY_FREQ); // 刷新计数器的计数值 reg [3:0] digit[0:3]; // 数码管的四个位 reg [3:0] count = 0; // 刷新计数器 always @(posedge clk) begin if (count == REFRESH_COUNT - 1) begin // 刷新数码管 digit[0] <= ...; digit[1] <= ...; digit[2] <= ...; digit[3] <= ...; count <= 0; end else begin count <= count + 1; end end // 控制数码管的显示 assign anode[0] = 1; assign anode[1] = 0; assign anode[2] = 0; assign anode[3] = 0; always @(posedge clk) begin if (anode[0]) begin seg <= digit[0]; end else if (anode[1]) begin seg <= digit[1]; end else if (anode[2]) begin seg <= digit[2]; end else if (anode[3]) begin seg <= digit[3]; end end ``` 在这段代码,我们使用了一个计数器来计时,当计数器达到一定值时,就更新数码管的显示内容。在每个时钟上升沿时,使用 `anode` 信号控制数码管的哪一位显示,使用 `seg` 信号输出对应的数字。 其,数码管的显示内容需要根据具体的应用场景来确定。下面给出一个基于这个例子的时钟应用代码: ``` // 时钟计时器 reg [5:0] hour = 0; reg [5:0] minute = 0; reg [5:0] second = 0; always @(posedge clk) begin // 计时 if (second == 59) begin second <= 0; if (minute == 59) begin minute <= 0; if (hour == 23) begin hour <= 0; end else begin hour <= hour + 1; end end else begin minute <= minute + 1; end end else begin second <= second + 1; end // 更新数码管的显示内容 digit[0] <= second % 10; digit[1] <= second / 10; digit[2] <= minute % 10; digit[3] <= minute / 10; end // 闹钟和暂停功能 reg [5:0] alarm_hour = 0; reg [5:0] alarm_minute = 0; reg [0:0] alarm_on = 0; reg [0:0] pause = 0; always @(posedge clk) begin if (!pause) begin // 计时 if (second == 59) begin second <= 0; if (minute == 59) begin minute <= 0; if (hour == 23) begin hour <= 0; end else begin hour <= hour + 1; end end else begin minute <= minute + 1; end end else begin second <= second + 1; end // 判断是否响铃 if (alarm_on && hour == alarm_hour && minute == alarm_minute && second == 0) begin // 响铃 end // 更新数码管的显示内容 if (alarm_on) begin // 闹钟已经开启,显示闹钟时间 digit[0] <= alarm_minute % 10; digit[1] <= alarm_minute / 10; digit[2] <= alarm_hour % 10; digit[3] <= alarm_hour / 10; end else begin // 闹钟未开启,显示当前时间 digit[0] <= second % 10; digit[1] <= second / 10; digit[2] <= minute % 10; digit[3] <= minute / 10; end end else begin // 暂停状态,不计时,数码管显示 PAUS digit[0] <= 1; // P digit[1] <= 10; // A digit[2] <= 11; // U digit[3] <= 12; // S end end ``` 在这段代码,我们使用了一个时钟计时器来计时,并在每秒钟更新数码管的显示内容。同时,我们还添加了闹钟和暂停功能。当闹钟开启时,数码管显示闹钟时间;否则,数码管显示当前时间。当暂停按钮按下时,计时器暂停,数码管显示 PAUS。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值