Veriog_Notes_Chapter 5

来源:互联网 发布:linux命令date格式化 编辑:程序博客网 时间:2024/06/03 21:07
  1. 条件语句 循环语句 块语句 生成语句
    if-else使用方法:
1Ifa<b) 或这(!rst)简写形式  语句1if(a<b)     //嵌套块  Begin 语句1;语句2;语句3;end    Else  语句2If (a<b)  语句1Else if (a=b)  语句2Else if(a>b)  语句2Else   语句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],因此超过了定义的范围。

0 0
原创粉丝点击