Verilog基础模块总结
verilog基础模块
verilog基础模块包括数据类型,运算符,组合逻辑和时序逻辑四个部分。数据类型包括常量和变量,在常量中有整数,X和Z以及参数。X代表不定制,Z代表高阻值。下划线不具有任何意义,是用来分割位数,提高程序可读性,8‘b0000_如1111。常量中的参数parameter可以用标识符定义常量,运用时只使用标识符即可,提高程序可读性及维护性,如定义parameter width=8;定义寄存器reg[width-1:0]a;即定义了8位宽度的寄存器。
参数传递:在一个模块中如果有定义参数,在其他模块调用此模块时可以传递参数,并可以修改参数,如下所示,在module后用#()表示。
module rom
#(parameter depth=15,parameter width=8)(input [depth-1:0]addr,input [width-1:0]data,output result
);
endmodulemodule top();
wire[31:0] addr;
wire[15:0] data;
wire result;rom
#(.depth(32),.witdth(16))
r1
(.addr(addr),.data(data),.result(result)
);
endmodule
parameter可以用于模块间的参数传递,而localparam仅用于本模块内使用,不能用于参数传递。localparam多用于状态机状态的定义。
数据类型中的变量有Wire型,Reg型,Memory型。wire类型变量,也叫网络类型变量,用于结构实体之间的物理连接,如门与门之间,不能存储值,用连续赋值语句assign赋值,定义为wire[n-1:0]a;其中n代表位宽,如定义wire;assign a=b;是将b的节点连接到连线a上。Reg类型变量,也称为寄存器变量,可用来储存值,必须在always语句里使用(值变化需时钟)。 其定义为reg[n-1:0]a;表示n位位宽的寄存器,如reg[7:0]a;表示定义8位位宽的寄存器a。也可以生成组合逻辑,如数据选择器,敏感信号没有时钟。可以用memory类型来定义RAM,ROM等存储器,其结构为reg[n-1:0]存储器名[m-1:0],表示为m个n位深度的寄存器。
运算符包括(1)算术运算符(+,-,*,/,%);(2)赋值运算符(=,<=);(3)关系运算符(>,<,>=,<=,==,!=);(4)逻辑运算符(&&,||,!);(5)条件运算符(?:);(6)位运算符(~,|,^,&,^~);(7)移位运算符(<<,>>);(8)拼接运算符({})。
这里面着重探讨一下赋值运算符“=”和“<=”。“=”为阻塞赋值,“<=”非阻塞赋值。阻塞赋值为执行完一条赋值语句,再执行下一条,可理解为顺序执行,而且赋值是立即执行;非阻塞赋值可理解为并行执行,不考虑顺序,在always块语句执行完成后,才进行赋值。一般情况下,在时序逻辑电路中使用非阻塞赋值,可避免仿真时出现竞争冒险现象;在组合逻辑中使用阻塞赋值,执行赋值语句后立即改变;在assign语句中必须用阻塞赋值。
组合逻辑电路的特点时任意时刻的输出仅仅取决于输入信号,输入信号变化,输出立即变化,不依赖于时钟。如与门“&”;或门“|”;非门“~”;异或门“^”;比较器;半加器(半加器和全加器时算术运算电路中的基本单元,由于半加器不考虑从低位来的进位,所以称之为半加器);全加器;乘法器;数据选择器(通过选择信号,选择不同的输入信号输出到输出端);3-8译码器;三态门。
时序逻辑电路在逻辑功能上特点是任意时刻的输出仅仅取决于当前时刻的输入,与电路原来的状态无关。而时序逻辑在逻辑功能上的特点是任意时刻的输出不仅仅取决于当前的输入信号,而且取决于电路原来的状态。如D触发器(D触发器在时钟的上升沿或下降沿存储数据,输出与时钟跳变之前输入信号的状态相同。)两级D触发器,带异步复位的D触发器(异步复位是指独立于时钟,一旦复位信号有效,就触发复位操作。);异步复位同步清零的D触发器;移位寄存器(移位寄存器是指在每个时钟脉冲来时,向左或向右移动一位,由于D触发器的特性,数据输出同步于时钟边沿,每个时钟来临,每个D触发器的输出q等于前一个D触发器输出的值,从而实现移位的功能)。
然后是几位重磅级的时序逻辑电路:
1.单口RAM:单口RAM的写地址与读地址公用一个地址,代码如下,其中reg[7:0]ram[63:0]意思是定义了64个8位宽度的数据。其中定义了addr_reg,可以保持住读地址,延迟一周期之后将数据送出。
module top
(input[7:0]data,input[5:0]addr,input wr,input clk,output[7:0] q
);
reg[7:0] ram[63:0]; //declare ram
reg[5:0] addr_reg; //addr registeralways @(posedge clk)
beginif(wr)ram[addr]<=data;addr_reg<=addr;
end
assign q=ram[addr_reg];
endmodule
2.伪双口RAM:伪双口RAM的读写地址是独立的,可以随机选择写或读地址,同时进行读写操作。代码如下
module top
(input[7:0] data,input[5:0] write_addr,input[5:0] read_addr,input wr,input rd,input clk,output reg[7:0] q
);
reg [7:0] ram[63:0]; //declare ram
reg [5:0] addr_reg; //addr registeralways @(posedge clk)
beginif(wr)ram[write_addr]<=data;if(rd)q<=ram[read_addr];
end
endmodule
3.真双口RAM:真双口RAM有两套控制线,数据线,允许两个系统对其进行读写操作,代码入下:
module top
(input [7:0] data_a,data_b,input [5:0] addr_a,addr_b,input wr_a,wr_b,input rd_a,rd_b,input clk,output reg[7:0] q_a,q_b
);reg[7:0] ram[63:0]; //declare ram
//port A
always @ (posedge clk)
beginif(wr_a)beginram[addr_a]<=data_a;q_a<=data_a;endif(rd_a)q_a<=ram[addr_a];
end
//port B
always @ (posedge clk)
beginif(wr_b)beginram[addr_b]<=data_b;q_b<=data_b;endif(rd_b)q_b<=ram[addr_b];
end
endmodule
4.单口ROM:ROM是用来存储数据的,可以按照下列代码形式初始化ROM,但这种方法处理大容量的ROM就比较麻烦,建议用FPGA自带的ROM IP核实现,并添加初始化文件。代码实现:
module top
(input [3:0] addr,input clk,output reg [7:0] q
);
reg [7:0] rom [15:0]; //declare rom
always @(addr)
begincase(addr)4’d0:rom[addr]=8'd15;4'd1:rom[addr]=8'd24;4'd2:rom[addr]=8'd100;4'd3:rom[addr]=8'd78;4'd4:rom[addr]=8'd98;4'd5:rom[addr]=8'd105;4'd6:rom[addr]=8'd86;4'd7:rom[addr]=8'd254;4'd8:rom[addr]=8'd76;4'd9:rom[addr]=8'd35;4'd10:rom[addr]=8'd120;4'd11:rom[addr]=8'd85;4'd12:rom[addr]=8'd37;4'd13:rom[addr]=8'd19;4'd14:rom[addr]=8'd22;4'd15:rom[addr]=8'd67;endcase
end
always @(posedge clk)
beginq<=rom[addr];
end
endmodule
5.有限状态机:在verilog里经常会用到有限状态机,处理相对复杂的逻辑,设定好不同的状态,根据触发条件跳转到对应的状态,在不同的状态下做相应的处理。有限状态机主要用到always及case语句。状态机有两种写法:一段式和三段式。一段式只用一个always语句,所有的状态转移,判断状态转移条件,数据输出都在一个always语句里,缺点是如果状态会多,会使整段程序显得冗长。三段式写法,状态转移用一个always语句,判断状态转移条件式组合逻辑,采用了一个always语句,数据输出也是单独得always语句,这样写起来比较直观清晰,状态很多时也不会显得繁琐。
Mealy有限状态机,输出不仅与当前状态有关,也与输入信号有关,一段式写法如下:
module top
(input shift_start,input shift_stop,input rst,input clk,input d,output reg [7:0] q
);parameter Idle =2'd0; //Idle state
parameter Start=2'd1; //Start state
parameter Run =2'd2; //Run state
parameter Stop =2'd3; //Stop statereg[1:0] state; //statement
reg[4:0] delay_cnt; //delay counteralways @(posedge clk or negedge rst)
beginif(!rst)beginstate<=Idle;delay_cnt<=0;q<=0;endelsecase(state)Idle: beginif(shift_start)state<=Start;endStart:beginif(delay_cnt==5'd99)begindelay_cnt<=0;state<=Run;endelsedelay_cnt<=delay_cnt+1'b1;endRun :beginif(shift_stop)state<=Stop;elseq<={q[6:0],d};endStop:beginq<=0;state<=Idle;enddefault :state<=Idle;endcase
end
endmodule
Moore有限状态机,输出只与当前状态有关,与输入信号无关,输入信号只影响状态得改变,不影响输出,比如对delay_cnt和q得处理,只与state状态有关。三段式写法代码如下
module top
(input shift_start,input shift_stop,input rst,input clk,input d,output reg[7:0] q
);parameter Idle=2'd0; //Idle state
parameter State=2'd1; //Start state
parameter Run=2'd2; //Run state
parameter Stop=2'd3; //Stop statereg[1:0] currernt_state; //statement
reg[1:0] next_state;
reg[4:0] delay_cnt; //delay counter//First part:statement transition
always @(posedge clk or negedge rst)
beginif(!rst)current_state<=Idle;elsecurrent_state<=next_state;
end
//Second part:combination logic,judge statement transition condition
always @(*)
begincase(current_state)Idle :beginif(shift_start)next_state<=Start;elsenext_state<=Idle;endStart :beginif(delay_cnt==5'd99)next_state<=Run;elsenext_state<=Start;endRun: beginif(shift_stop)next_state<=Stop;elsenext_state<=Run;endStop: next_state<=Idle;default:next_state<=Idle;endcase
end
//Last part:output data
always @(posedge clk or negedge rst)
beginif(!rst)delay_cnt<=0;else if(current_state==Start)delay_cnt<=delay_cnt+1'b1;elsedelay_cnt<=0;
endalways @(posedge clk or negedge rst)
beginif(!rst)q<=0;else if(current_state==Run)q<={q[6:0],d};elseq<=0;
end
endmodule
基础模块finish!
Verilog基础模块总结相关推荐
- Verilog功能模块——取滑动平均值(使用寄存器组)
我的另一篇博客:Verilog功能模块--取滑动平均值(使用FIFO) 两者用不同的方式实现相同的功能, 使用FIFO占用较少寄存器资源,适用于取值N较大的场合. 使用寄存器组不需要额外的IP,更简单 ...
- (61)Verilog HDL模块例化Verilog模块
(61)Verilog HDL模块例化Verilog模块 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL模块例化Verilog模块 5)结语 1. ...
- (62)Verilog HDL模块例化system Verilog模块
(62)Verilog HDL模块例化system Verilog模块 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL模块例化system Ver ...
- (63)Verilog HDL模块例化VHDL模块
(63)Verilog HDL模块例化VHDL模块 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL模块例化VHDL模块 5)结语 1.2 FPGA ...
- (66)Verilog HDL模块参数化例化
(66)Verilog HDL模块参数化例化 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL模块参数化例化 5)结语 1.2 FPGA简介 FPG ...
- (67)Verilog HDL模块条件例化
(67)Verilog HDL模块条件例化 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL模块条件例化 5)结语 1.2 FPGA简介 FPGA( ...
- (02)Verilog HDL模块
(02)Verilog HDL模块 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL模块 5)结语 1.2 FPGA简介 FPGA(Field Pr ...
- (03)Verilog HDL模块例化
(03)Verilog HDL模块例化 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL模块例化 5)结语 1.2 FPGA简介 FPGA(Fiel ...
- (04)Verilog HDL模块仿真激励
(04)Verilog HDL模块仿真激励 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)Verilog HDL模块仿真激励 5)结语 1.2 FPGA简介 FPGA( ...
最新文章
- 数据库性能优化1——正确建立索引以及最左前缀原则
- 耗材领用登记系统php_简单说一说,实验室管理系统LIMS系统功能描述吧
- 关于BCH交易规范排序(CTOR)的优缺
- python入门到精通需要学多久-廖雪峰python教程要学多久-零基础学Python需要多久...
- java mysql报表T加1_MySQL报错: java.sql.SQLException: Column count doesn't match value count at row 1...
- delphi listview失去焦点后的颜色_阴阳师姑获鸟和惠比寿建模更新对比 爷爷帅了 觉醒后鸟姐颜值提升...
- python创建数据库字数不限制_textarea字数限制方法一例
- PocketSphinx语音识别系统的编译、安装和使用
- lucene 建索引
- S3C6410的DRAM控制器
- 机器学习实战(四)逻辑回归LR(Logistic Regression)
- 零基础学python难吗-Python课程学习难不难?零基础可以学习Python吗?
- 深入理解Java虚拟机2——内存管理机制及工具
- 华为路由器交换机配置命令集合
- 人类基因组大数据分析(大数据人工智能公司)
- python内存泄漏_python 泄漏
- Android开发实例-Android平台手机新闻客户端
- 数据挖掘十大经典算法(详解)
- ICC 图文学习——LAB2:Design Planning 设计规划
- C入门学习之水仙花数个人总结