Verilog指令_assign用法
2016-03-02 16:34
369 查看
一、引入语法的概念
1、只有寄存器类型的信号才可以在always和initial 语句中进行赋值,类型定义通过reg语句实现。
2、always 语句是一直重复执行,由敏感表(always 语句括号内的变量)中的变量触发。
3、always 语句从0 时刻开始。
4、在begin 和end 之间的语句是顺序执行,属于串行语句。
二、总结下几种assign用法:
1.作为信号量输出,通过寄存器连续赋值
output [3:0]oLED;
//internal signal
reg [3:0]sr_LED; //用独热码表示LED亮灯位置。
assign oLED[3:0] = ~ sr_LED[3:0]; //向LED灯接口输出信号。
2.作为信号量输出,通过寄存器拼接数据位实现。
output [15: 0] oSI_DATA;
//internal signal
reg [ 3: 0] s_HEX;
reg [ 7: 0] s_SEGBINARY; // s_SEGBINARY[2] should be the DOT
reg [ 3: 0] s_SEG_SEL;
assign oSI_DATA = {iLED_SEL,s_SEG_SEL,s_SEGBINARY};
3.作为信号量输出,通过判断条件,赋值给信号
output[ 1: 0] oSEG_STATE;
output oCP_PLUSE;
wire s_CNTEQCYCLE;
parameter PARAM_7SEG_CYCLE = 32'd2500000;
reg [ 1: 0] sr_SEG_STATE;
reg [31: 0] sr_cnt;
reg sr_cp_pluse;
assign oSEG_STATE = sr_SEG_STATE;
assign oCP_PLUSE = sr_cp_pluse;
assign s_CNTEQCYCLE = ( sr_cnt == PARAM_7SEG_CYCLE ) ? 1 : 0;
4.作为输出信号量,通过输入信号量赋值给输出,同样可以输入信号量和寄存器组合逻辑,赋值给输出信号量。
input iCLK50M;
input iCP_PULSE;
input[15:0] iSI_DATA;
output oSI;
output oCP;
reg [ 3: 0] sr_cnt;
reg [15: 0] sr_si_data;
reg sr_cp;
reg sr_en;
assign oSI = sr_si_data[15];
assign oCP = sr_en & iCLK50M;
三、对比输出寄存器变量和信号量
下面是功能相同但写法不同的两段代码:
第一段A
module assign_test_a (
clk,
lhold,
lholda
);
input clk;
input lhold;
output lholda;
reg lholda;
always @(posedge clk)
if (lhold)
lholda<=lhold;
else
lholda<=0;
endmodule
第二段B
module assign_test_b (
clk,
lhold,
lholda
);
input clk;
input lhold;
output lholda;
reg lholda_r;
always @(posedge clk)
if (lhold)
lholda_r<=lhold;
else
lholda_r<=0;
assign lholda=lholda_r;
endmodule
两端代码生成的电路时一样的,没有区别,只是在应用上有区别。
分析:
1. 从代码角度来看。 A是直接把内部reg信号做为输出,因此相对外部来说,外部信号引脚lholda没有选择的连接到reg输出信号。 这里其实暗含了用根导线直接把reg的输出与lholda连接起来。因此B代码就是把这个暗含的明显化。因此他们的RTL没有多大区别。
2. 从实用角度来说,这里的意义比较大。当内部有多个信号需要输出,可是输出引脚只有一个,那么这时就可以进行选择。如下:
assign lholda= (条件)? (lholda_ra): lholda_rb; 可以嵌套使用。
或者在这种情况下也非常有用。
Lholda 与 内部的reg输出lholda_ra, lholda_rb,…., 存在逻辑函数关系。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
assign是一种线的赋值语句,例如
wire a,b;
reg c;
可以写成 assign a= 1'b1;
但是不能写成 assign c=1'b1;
普通的io口也可以直接赋值 ,其实io口在电路上就是一种wire
ouput[15:0] d;
assing d=16'h1234;
------------------------------------------------------------------
----------------------------------------
reg 与 寄存器
实际上应该反过来讲:
- 如果要综合寄存器,需要同时满足俩个条件:
1。定义为reg,
2. 在always @posedge(negedge) block中赋值
- 如果要综合组合逻辑,可以(任意)
a. 定义为wire, 用assign赋值
b. 定义为reg, 只在always @(a b c d) block中赋值
在verilog语言中的reg 类型只是语法意义上。reg类型的变量不能通过assign赋值,而wire类型的变量不能在always block中赋值。参加运算的变量(赋值号的右边)没有类型检查的限制。
1、只有寄存器类型的信号才可以在always和initial 语句中进行赋值,类型定义通过reg语句实现。
2、always 语句是一直重复执行,由敏感表(always 语句括号内的变量)中的变量触发。
3、always 语句从0 时刻开始。
4、在begin 和end 之间的语句是顺序执行,属于串行语句。
二、总结下几种assign用法:
1.作为信号量输出,通过寄存器连续赋值
output [3:0]oLED;
//internal signal
reg [3:0]sr_LED; //用独热码表示LED亮灯位置。
assign oLED[3:0] = ~ sr_LED[3:0]; //向LED灯接口输出信号。
2.作为信号量输出,通过寄存器拼接数据位实现。
output [15: 0] oSI_DATA;
//internal signal
reg [ 3: 0] s_HEX;
reg [ 7: 0] s_SEGBINARY; // s_SEGBINARY[2] should be the DOT
reg [ 3: 0] s_SEG_SEL;
assign oSI_DATA = {iLED_SEL,s_SEG_SEL,s_SEGBINARY};
3.作为信号量输出,通过判断条件,赋值给信号
output[ 1: 0] oSEG_STATE;
output oCP_PLUSE;
wire s_CNTEQCYCLE;
parameter PARAM_7SEG_CYCLE = 32'd2500000;
reg [ 1: 0] sr_SEG_STATE;
reg [31: 0] sr_cnt;
reg sr_cp_pluse;
assign oSEG_STATE = sr_SEG_STATE;
assign oCP_PLUSE = sr_cp_pluse;
assign s_CNTEQCYCLE = ( sr_cnt == PARAM_7SEG_CYCLE ) ? 1 : 0;
4.作为输出信号量,通过输入信号量赋值给输出,同样可以输入信号量和寄存器组合逻辑,赋值给输出信号量。
input iCLK50M;
input iCP_PULSE;
input[15:0] iSI_DATA;
output oSI;
output oCP;
reg [ 3: 0] sr_cnt;
reg [15: 0] sr_si_data;
reg sr_cp;
reg sr_en;
assign oSI = sr_si_data[15];
assign oCP = sr_en & iCLK50M;
三、对比输出寄存器变量和信号量
下面是功能相同但写法不同的两段代码:
第一段A
module assign_test_a (
clk,
lhold,
lholda
);
input clk;
input lhold;
output lholda;
reg lholda;
always @(posedge clk)
if (lhold)
lholda<=lhold;
else
lholda<=0;
endmodule
第二段B
module assign_test_b (
clk,
lhold,
lholda
);
input clk;
input lhold;
output lholda;
reg lholda_r;
always @(posedge clk)
if (lhold)
lholda_r<=lhold;
else
lholda_r<=0;
assign lholda=lholda_r;
endmodule
两端代码生成的电路时一样的,没有区别,只是在应用上有区别。
分析:
1. 从代码角度来看。 A是直接把内部reg信号做为输出,因此相对外部来说,外部信号引脚lholda没有选择的连接到reg输出信号。 这里其实暗含了用根导线直接把reg的输出与lholda连接起来。因此B代码就是把这个暗含的明显化。因此他们的RTL没有多大区别。
2. 从实用角度来说,这里的意义比较大。当内部有多个信号需要输出,可是输出引脚只有一个,那么这时就可以进行选择。如下:
assign lholda= (条件)? (lholda_ra): lholda_rb; 可以嵌套使用。
或者在这种情况下也非常有用。
Lholda 与 内部的reg输出lholda_ra, lholda_rb,…., 存在逻辑函数关系。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
assign是一种线的赋值语句,例如
wire a,b;
reg c;
可以写成 assign a= 1'b1;
但是不能写成 assign c=1'b1;
普通的io口也可以直接赋值 ,其实io口在电路上就是一种wire
ouput[15:0] d;
assing d=16'h1234;
------------------------------------------------------------------
----------------------------------------
reg 与 寄存器
实际上应该反过来讲:
- 如果要综合寄存器,需要同时满足俩个条件:
1。定义为reg,
2. 在always @posedge(negedge) block中赋值
- 如果要综合组合逻辑,可以(任意)
a. 定义为wire, 用assign赋值
b. 定义为reg, 只在always @(a b c d) block中赋值
在verilog语言中的reg 类型只是语法意义上。reg类型的变量不能通过assign赋值,而wire类型的变量不能在always block中赋值。参加运算的变量(赋值号的右边)没有类型检查的限制。
相关文章推荐
- ConfigParser模块
- SpringMVC原理分析
- Oracle常见授权与回收权限(grant和revoke)学习记录
- ios 添加全屏返回手势
- Spring MVC执行定时任务
- setData()方法给下拉框赋值--------附的仅仅是显示值-,再选择会去掉,如果一直存在,需要加到数组里
- iOS开发---根据控件找到指定的cell
- 解决android4.4以上系统的相册选择图片后获取不到有效的URI
- Java properties存储与读取遍历
- Xpath定位元素-一个例子
- Find the Kth number c++ version
- ORACLE ADF:EO 入门
- C++中在容器Vector中使用结构体Struct
- unity脚本自带函数执行顺序
- java-String类深入剖析和 intern()方法解析
- Linux tcpdump命令详解
- 提高程序安全性
- BP神经网络推导过程详解
- redis set zset 的具体操作
- 使用FreeImage来进行Qt图片的读入