Veriog_Notes_Chapter 5
来源:互联网 发布:linux命令date格式化 编辑:程序博客网 时间:2024/06/03 21:07
- 条件语句 循环语句 块语句 生成语句
if-else使用方法:
1)If (a<b) 或这(!rst)简写形式 语句1;if(a<b) //嵌套块 Begin 语句1;语句2;语句3;end Else 语句2;If (a<b) 语句1; Else if (a=b) 语句2; Else if(a>b) 语句2; Else 语句n;Else 只与最近的if相匹配。
2.Case语句用法
Reg [15:0] rega;Reg [9:0] result;Case (rega) 16’b0: result = 10’b0111111111; 16’b7x: result = 10’b0111001111; 16’bz5: result = 10’b0000011111; ... Default:result =10’bx;(可有可无但只有一个)Endcasecasez(不比较高组态) casex(不比较高组态和不定值)Reg[7:0] ir;Casez(ir)8’b1???????:instruction1(ir);8’b100?????:instruction2(ir);...Default:instruction8(ir);
3、条件语句的语法
if (expression) true_statement; true_statement 执行或不执行If(expression) true_statement; else false_statement ;If(expression) true_statement_1; else if true_statement_1 else false_statement ; 只执行一条多分支语句 多用循环语句加块语句
4.循环语句:forever begin 语句;end 或forever 语句;(只能在initial语句(不可综合)Repeat 语句;或
repeat begin 语句…;end for()用法与c类似 While 语句(不可综合);或while begin 语句…;end
5. 顺序 begin_end块。并行 fork_join 两个都可带(延时tb用)和嵌套. Disable block1;禁用块
生成块:矢量或模块重复操作时可动态生成代码。生成实例可以是多种类型:1)模块
6. 块 用户定义原语;3)门级原语;4)连续赋值语句;5)initial 和always块。
关键词 generate - endgenerate 能够在申明范围内生成的数据类型:1)线网net,寄存器reg;
integer ,real time,realtime;3)event.且生成的具有唯一标识可以被层次引用。不能生成1)参数,局部参数;2)输入输出和输入输出申明;3)指定块。
7. 循环生成语句:将循环语句,条件语句,case语句则可组成。循环生成块,条件生成块。
循环生成块:1)变量申明2)模块3)用户定义原语门级原语4)连续赋值语句5)initial,always
条件生成块:模块3)用户定义原语门级原语4)连续赋值语句5)initial,always
分支生成块:1)模块3)用户定义原语门级原语4)连续赋值语句5)initial,always
8. 程序实例:由25Mhz得到12Mhz的分频方法。思路:首先进行2倍分频然后在进行1.0415倍分频
module clk_divided_decimals( sys_clk, clk_out ); input sys_clk;output clk_out;parameter K=10; //divided 2 ,tdivided 1.0415parameter M=25; // rate 25/24 = 1.0415parameter N=24; //25/12=2.083=1.0415*2=(25/24)*2reg div; reg del;reg clk_2_div; reg [K-1:0] p; initial begin //initiate reg p<=32'b0; div<=2'b0; clk_2_div<=0; end //devide sys_clk into 12.5Malways@(posedge sys_clk) begin clk_2_div = ~clk_2_div; end always@(posedge clk_2_div) begin if(p<M) begin p<=p+N; end if(p>=M) begin p<=p-M+N; del<=2'b0; end if(N<=p&&p<M) begin del<=2'b1; endendalways@( sys_clk ) begin if(del==1) div<=2'b1; else div<=clk_2_div;end assign clk_out = div;endmodule
module clk_divided_decimals_tb; reg sys_clk; wire clk_out; clk_divided_decimals uut ( .sys_clk(sys_clk), .clk_out(clk_out) ); initial begin sys_clk = 0; #100; end always #200 sys_clk = ~sys_clk;endmodule
测试平台时钟25M,需得到12M就必须得2.083分频。于是先两倍分频再1.0415倍分频。非整数倍分频则采用去脉冲的方式实现。每输入25个脉冲就去除其中的一个脉冲,就能得到1.0415倍的分频。不过此种方法不易得到占空比为50%的时钟。即在模型中M/N即为实现非整数倍分频的比率。
9. 若想for语句按照时钟节拍进行初始化则须将其时钟敏感信号加入其中
Initial Begin For(i=0;i<=1024;i++) Begin Mem[i]=i; @(posedge clk) /不可综合 End End
10.case语句与拼接语句的使用实例(ls138)
module sim_74ls138( g, y, a, b, c );input [1:0] g; output [7:0] y; input a,b,c; reg [7:0] tmp;/*if((g==2'b0x)||(g==2'bx1)) tmp=8'b1111_1111; case ({a,b,c}) 3'b000: tmp=8'b0111_1111; 3'b001: tmp=8'b1011_1111; 3'b010: tmp=8'b1101_1111; 3'b011: tmp=8'b1110_1111; 3'b100: tmp=8'b1111_0111; 3'b101: tmp=8'b1111_1011; 3'b110: tmp=8'b1111_1101; 3'b111: tmp=8'b1111_1110; default : tmp=8'b1111_1111; Endcase*/always@(*) begin case ({g,a,b,c}) 5'b10000: tmp=8'b0111_1111; 5'b10001: tmp=8'b1011_1111; 5'b10010: tmp=8'b1101_1111; 5'b10011: tmp=8'b1110_1111; 5'b10100: tmp=8'b1111_0111; 5'b10101: tmp=8'b1111_1011; 5'b10110: tmp=8'b1111_1101; 5'b10111: tmp=8'b1111_1110; default : tmp=8'b1111_1111; endcaseend assign y=tmp;Endmodule
module sim_74ls138_tb; reg [1:0] g; reg a; reg b; reg c; wire [7:0] y; sim_74ls138 uut ( .g(g), .y(y), .a(a), .b(b), .c(c) ); initial begin g = 2'b10; a = 0; b = 0; c = 0; #100; end always begin fork #100 begin a=1; b=0; c=0; end #200 begin a=0; b=0; c=0; end #300 begin a=1; b=0; c=1; end #400 begin a=1; b=1; c=0; end #500 begin a=1; b=1; c=1; end join endEndmodule
11.循环生成语句的使用
module ripple_adder( co, sum, a0, a1, ci ); parameter N = 4;output [N-1:0] sum;output co;input [N-1:0] a0,a1;input ci;wire [N-1:0] carry;genvar i;generate for(i=0;i<N;i=i+1) begin :r_loop wire t1,t2,t3; xor g1(t1,a0[i],a1[i]); xor g2(sum[i],t1,carry[i]); and g3(t2,a0[i],a1[i]); and g4(t3,t1,carry[i]); or g5(carry[i],t2,t3); endendgenerateassign co= carry[N-1];Endmodule
reg [3:0] a0; reg [3:0] a1; reg ci; wire co; wire [3:0] sum; ripple_adder uut ( .co(co), .sum(sum), .a0(a0), .a1(a1), .ci(ci) ); initial begin a0 = 0; a1 = 0; ci = 0;#100; end always begin fork #100 begin a0=2'b10; a1=2'b01; ci=2'b1; end #200 begin a0=2'b11; a1=2'b01; ci=2'b1; end #300 begin a0=2'b10; a1=2'b11; ci=2'b1; end join endendmodule
分析:书中的程序有错误
Assign carry[0]=c0;一直在赋值而在执行generate的同时也会对carry[0]进行操作。此处不可综合。
在书本的程序中当i为3时,generate中最后一句or g5(carry[i+1],t2,t3);carry此时为carry[4],而carry的定义为[3:0],因此超过了定义的范围。
- Veriog_Notes_Chapter 5
- Veriog_Notes_Chapter 1
- Veriog_Notes_Chapter 2
- Veriog_Notes_Chapter 4
- Veriog_Notes_Chapter 6
- Veriog_Notes_Chapter 3
- Veriog_Notes_Chapter 7
- 5
- 5
- 5
- 5
- 5
- 5
- 5
- 5
- 5
- 5
- 5
- 字符练习
- 线段覆盖4
- java 静态代码块 动态代码块 加载时间
- 字符的使用
- Android应用
- Veriog_Notes_Chapter 5
- 位运算
- 单列的实现的问题
- Linux下如何安全退出线程
- if使用注意事项
- JAVA 并发编程-线程同步工具类(十二)
- linux查看jar包内文件命令
- Validate Binary Search Tree
- uiwebview通过cookie自动登录