Veriog_Notes_Chapter 4

第四章

  1. 运算符,赋值语句,结构说明语句
    逻辑运算符:&&,||,!。关系运算符:(<,>,<=,>=)。等式运算符(==,!=,===,!==)其中(!==,===可以用来比较高阻态和不定值,完全一样才能为1)。移位运算符(<<,>>空位补零),位拼接运算符({}),缩减运算符(c =&b 将第一位与第二位与结果再与第三位与)。
  2. 优先级(!~)(*,/,%)(+,-)(<<,>>)(<,<=,>>=)(==,===,!=,!==)(&)(^,^~)(|)(&&)(||)(?
    赋值语句:非阻塞赋值(b<=a;)块(always块)结束时最后完成赋值操作。阻塞赋值(b=a)赋值语句执行完立即赋值,赋值语句执行完时块才结束。
  3. 块语句(begin end )顺序执行,(fork join 不可综合)并行执行。可以在块内申明语句。
  4. 逻辑运算符与逻辑运算符的区别,逻辑运算符的结果只能是0或1,而按位逻辑运算则位数同操作数相同。 Initial 内部具有多条语句时需使用begin end多个initial 之间是并行。
  5. 位拼接运算符{}使用方法:assign control ={read,write,sel[2:0],halt,load_instr…}
  6. 条件语句 循环语句 块语句 生成语句
    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相匹配。

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;(可有可无但只有一个)
Endcase
casez(不比较高组态) casex(不比较高组态和不定值)
Reg[7:0] ir;
Casez(ir)
8’b1???????:instruction1(ir);
8’b100?????:instruction2(ir);
...
Default:instruction8(ir);

4、条件语句的语法

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 ; 只执行一条
多分支语句 多用循环语句加块语句

5.循环语句:forever begin 语句;end 或forever 语句;(只能在initial语句(不可综合)Repeat 语句;或
repeat begin 语句…;end for()用法与c类似 While 语句(不可综合);或while begin 语句…;end
7. 顺序 begin_end块。并行 fork_join 两个都可带(延时tb用)和嵌套. Disable block1;禁用块
生成块:矢量或模块重复操作时可动态生成代码。生成实例可以是多种类型:1)模块
8. 块 用户定义原语;3)门级原语;4)连续赋值语句;5)initial 和always块。
关键词 generate - endgenerate 能够在申明范围内生成的数据类型:1)线网net,寄存器reg;
integer ,real time,realtime;3)event.且生成的具有唯一标识可以被层次引用。不能生成1)参数,局部参数;2)输入输出和输入输出申明;3)指定块。
9. 循环生成语句:将循环语句,条件语句,case语句则可组成。循环生成块,条件生成块。
循环生成块:1)变量申明2)模块3)用户定义原语门级原语4)连续赋值语句5)initial,always
条件生成块:模块3)用户定义原语门级原语4)连续赋值语句5)initial,always
分支生成块:1)模块3)用户定义原语门级原语4)连续赋值语句5)initial,always
10. 程序实例:由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.0415
parameter M=25; // rate 25/24 = 1.0415
parameter N=24; //25/12=2.083=1.0415*2=(25/24)*2
reg 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.5M
always@(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;
    end
end
always@( 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即为实现非整数倍分频的比率。
10. 若想for语句按照时钟节拍进行初始化则须将其时钟敏感信号加入其中

Initial
  Begin
  For(i=0;i<=1024;i++)
  Begin
  Mem[i]=i;
  @(posedge clk)  /不可综合
  End 
     End 

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;
        endcase
end
    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
        end
Endmodule

循环生成语句的使用

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);
    end
endgenerate
assign 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
    end
endmodule

分析:书中的程序有错误
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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值