Verilog

Verilog

学verilog之前必须了解的电路知识

1.数字电路都有哪些,都是干啥的?

官方一点:

组合逻辑电路:简称组合电路,它由最基本的逻辑门电路组合而成。特点是:输出值只与当时的输入值有关,即输出惟一地由当时的输入值决定。电路没有记忆功能,输出状态随着输入状态的变化而变化,类似于电阻性电路,如加法器、译码器、编码器、数据选择器等都属于此类。

时序逻辑电路:简称时序电路,它是由最基本的逻辑门电路加上反馈逻辑回路(输出到输入)或器件组合而成的电路,与组合电路最本质的区别在于时序电路具有记忆功能。时序电路的特点是:输出不仅取决于当时的输入值,而且还与电路过去的状态有关。它类似于含储能元件的电感或电容的电路,如触发器、锁存器、计数器、移位寄存器、储存器等电路都是时序电路的典型器件。

人话:(做题够用就行)

全是基础门电路的叫组合逻辑电路,它没有clk, 只看输出、输入端就行,中间的变量都不用声明,常用于:3-8译码器、加法器、选择器啥的

有clk的一定是时序逻辑电路, 像什么触发器、锁存器啥的都算 

什么样的是组合逻辑?

在这里插入图片描述

什么样的是时序逻辑?

在这里插入图片描述

2.电路中的“1”和“0”代表什么意思?

1: 高电平 定义上讲>=电源电压的70%都叫高电平  取极值就是直接接电
0:低电平        <=电源电压的30%都叫低电平  取极值就是没接电

3.电路中串行、并行的概念

串行可理解为顺序执行,

并行是同一时间全执行。多用于流水线

4、怎么看上升沿、怎么看下降沿(电路图中)?

在这里插入图片描述

5.wire和reg都是什么?什么时候用?

从仿真的角度来说,HDL语言面对的是编译器(如Modelsim等),相当于软件思路。
这时:
wire对应于连续赋值,如assign
reg对应于过程赋值,如always,initial

*********************************************************************************
从综合的角度来说,HDL语言面对的是综合器(如DC等),要从电路的角度来考虑。
这时:
1、wire型的变量综合出来一般是一根导线;
2、reg变量在always块中有两种情况:
(1)、always后的敏感表中是(a or b or c)形式的,也就是不带时钟边沿的,综合出来还是组合逻辑
(2)、always后的敏感表中是(posedge clk)形式的,也就是带边沿的,综合出来一般是时序逻辑,会包含触发器(Flip-Flop)

在设计中,输入信号一般来说你是不知道上一级是寄存器输出还是组合逻辑输出,那么对于本级来说就是一根导线,也就是wire型。而输出信号则由你自己来决定是寄存器输出还是组合逻辑输出,wire型、reg型都可以。但一般的,整个设计的外部输出(即最顶层模块的输出),要求是寄存器输出,较稳定、扇出能力也较好。
有几种情况变量需要定义成wire。
第一。assign 语句
例如:
reg a,b;
wire and_result;
...
assign and_result =a&&b;
你可以试试把wire定义成reg。综合器会报错。

第二。元件例化时候的输出必须用wire
例如:
wire dout;

ram u_ram
(
...
.out(dout)
...
);

6.什么是mos管? 工作原理是什么?

【Mos管的工作原理】 https://www.bilibili.com/video/BV1344y167qm/?share_source=copy_web&vd_source=8b70f9233f14fa0e3233bf1868c76822

知识点:

数据流建模

输入信号从组合逻辑电路传到输出时类似数据流动,而不存储。可通过连续赋值语句建模的方式叫数据流建模。
得用wire 声明 、assign赋值
assign的声明方式:
assign #(延时多少) 变量名=啥啥啥 
assign  a=1'b0;  int a=1;
assign  a=1'b1;
assign的赋值方式:
  • 显示赋值:先声明,再赋值
  • 隐式赋值:声明和赋值写成一句
assign的特点:
  • 只有wire类型能用

  • //各语句之间都是并行的关系,没有延时的情况下都是一起出结果的。

对四输入三输出组合逻辑电路进行数据流建模

在这里插入图片描述

module in4_out_3(x1,x2,x3,x4,g,h,f);
    input wire x1,x2,x3,x4;
    output reg g,h,f;
    
    assign g=(x1&&x3)||(x2&&x4);
    assign h=(x1||x3)&&(x2||x4);
    assign f=h||g;
    
endmodule

行为级建模

Verilog HDL支持设计者从电路外部行为的角度对其进
行描述,因此行为级建模是从一个层次很高的抽象角度来
表示电路的。其目标不是对电路的具体硬件结构进行说明,
它是为了综合以及仿真的目的而进行的。


跟时序电路有关系,像写c语言的函数、java的方法
格式怎么写?
  • module 名字(输出输出列表)+ ;

    这个列表声不声明数据类型都行。这里没声明就下面声明一下
    
  • 数据/变量类型声明

    变量类型常用: wire  reg(无符号) integer(有符号)
    
  • 过程语句/赋值语句

    过程:用initial/always写的
    赋值:assign/<=/=
    
  • 逻辑部分

  • endmodule

initial/always怎么用?
  • initial+语句块

    • +begin end

      
      initial 
      	begin
      		 a=0;b=1;c=0;
      	#100 a=1,b=0;
      	#100 a=0;c=1;
      	#100 b=1;
      	#100 b=0;c=0;
      	end
      
    • +fork join

      initial 
          fork
              	a=0;b=1;c=0;
             #100 a=1,b=0;
      	#200 a=0;c=1;
      	#300 b=1;
      	#400 b=0;c=0;
          join
      
  • always @(敏感列表)+xxx

    • 对组合电路,敏感列表把全部输入信号写入

      input in0,in1,in2,in3;
      xxxx;
      reg out;
      always@(in0 or in1 or in2 or in3)
      	case(sel)
      			2'b00: out=in0;
                  2'b01: out=in1;
                  2'b10: out=in2;
                  2'b11: out=in3;
                  default: out=2'bx;
      	endcase
      endmodule
      
    • 对时序电路,需要把关键信号(时间/rst为多)和部分输入信号放入列表里面

      module mux4_1(out,in0,in1,in2,in3,sel);
          input in0,in1,in2,in3;
          ouput out;
          input [1:0]sel;
          reg out;
          
          always@(in0 or in1 or in2 or in3 or sel)
              case(sel)
                  2'b00: out=in0;
                  2'b01: out=in1;
                  2'b10: out=in2;
                  2'b11: out=in3;
                  default: out=2'bx;
              endcase
      endmodule
      
      • 敏感列表如何使用

        always@(in0 or in1)							//当in0或in1值改变是 走下面的语句
        always@(posedge clock)						//当clock的上升沿到来时 走下面的语句
        always@(negedge clock)						//当clock的下降沿到来时 走下面的语句
        always@(posedge clock or negedge reset ) 	//当clock的上升沿到来或reset下降沿到来时 走下面的语句
        
逻辑语句
阻塞赋值 和 非阻塞赋值

精准空降☞【【电子】Verilog硬件描述语言 西安电子科技大学 蔡觉平等主讲】 【精准空降到 14:07】 空降
你看前面说的应该会很懵,(1.5倍速)蔡老师讲到补充时序电路和组合电路结构 、流水线的思想那里应该就恍然大悟了。

最大区别:

一个不用等延时之间给,一个得等延时才能给

阻塞赋值语句:
b=a; 
d=c;
在串行中b=a;必须执行完之后才能进行d=c
在并行中没啥影响。
非阻塞赋值语句:
b<=a;
在串行中也没有先后之分了。
先计算a的值,然后等待延迟时间的结束,再将计算的值赋给左边的变量。

D触发器:

在这里插入图片描述

//阻塞
module D_block(din,clk,out1,out2);
    input wire din,clk;
    output reg out1,out2;
    always@(posedge clk or din or clk )
        begin
            out1=din;
            out2=out1;
        end
endmodule



/*
等效于
out1=din;
out2=din;
*/
//阻塞tb
module D_touchtb();
reg din,clk;
wire out1,out2;

initial 
begin
din=0;clk=0;
#50 clk=1;
#50 din=1;
#50 clk=0;
#50 din=0;
end
D_block d0(din,clk,out1,out2);
endmodule

在这里插入图片描述

在这里插入图片描述

//非阻塞
module D_unblock1(din,clk,out1,out2);
    input wire din,clk;
    output reg out1,out2;
    always@(posedge clk or din or clk )
        begin
            out1<=din;
            out2<=out1;//out1 out2 kaishi doushi h,out2=h,out 1=din;
        end
endmodule
//非阻塞tb
module D_unblocktb();
reg din,clk;
wire out1,out2;

initial 
begin
din=0;clk=0;
#50 clk=1;
#50 din=1;
#50 clk=0;
#50 din=0;
end
D_unblock1 d0(din,clk,out1,out2);
endmodule
module D_unblock1(din,clk,out1,out2);
    input wire din,clk;
    output reg out1,out2;
    always@(posedge clk )
        begin
            out1<=din;
            out2<=out1;//out1 out2开始都是h,上升沿一到out2=h的同时out1=din;
        end
endmodule

![在这里插入图片描述](https://img-blog.csdnimg.cn/4922b8d4dcfe4cd195a3cc01a60d3c67.png#pic_center)


##### 例题1:

根据不同的代码,画不同的电路图

~~~verilog
//代码1
module block3(a,b,c,clk,sel,out);
input a,b,c,clk,sel;
output out;
reg out,temp;
always@(posedge clk)
begin
    temp=a&b;
	if(sel) out=temp|c;
	else out=c;
end
endmodule

在这里插入图片描述

//代码2
module block4(a,b,c,clk,sel,out);
input a,b,c,clk,sel;
output out;
reg out,temp;
always@(posedge clk)
begin
    temp<=a&b;
    if(sel) out<=temp|c;
	else out<=c;
end
endmodule
例题2:

img

//阻塞语句

always@(posedge clk)
	begin
		out3=out2;
		out2=out1;
		out1=out0;
		out0=din;
	end
//非阻塞语句
always@(posedge clk)
	begin 	
		out0<=din;
		out1<=out0;
		out2<=out1;
		out3<=out2;
	end
同步异步清零置数问题
  • 同步清零同步置数
always @(posedge clk)
    if(!reset) out = 8'h00; //同步清 零,低电平有效 
else if(load) out = data; //同步置数  
  • 异步清零异步置数
always @(posedge clk or negedge clear) //clk上升 沿和clear低电平清零有效
   if(!clear) //异步清零 out=0; 
else out=out+1;--> 
assign和deassign
assign在行为级建模是给reg用的,wire用不了的,
重复赋值会保存这个新值在reg中
对于deassign语句,
是一条撤销连续赋值的语句。执行后,原来由assign语句对
变量进行的连续赋值操作将失效,恢复原来的值
force和release
也是赋值,reg和wire都能用;
优先级比assign、deassign高
对某种信号进行临时性的赋值和测试时常用

长什么样啊?

force out=a|b;
#5;
release out
if else
跟c java中的差不多,不用刻意记
case
  • 格式:

    case(控制表达式)
    值1:语句块1
    值2:语句块2
    ...
    值n:语句块n
    default:语句块n+1
    endcase
    
  • 注意点:

循环
  • forever

    forever 语句一般用在initial过程语句中,如果在forever语句中没有 加入时延控制,forever语句将在0时延后无限循环下去

    initial
    begin
    clock=0;
    forever #50 clock=~clock;
    end
    
  • repeat
    先计算出循环次数表达 式的值,并将它作为循环次数保存起来;接着执行后面的 语句块(循环体),语句块执行结束后,将重复执行次数减 去一次,再接着重新执行下一次的语句块操作,如此重复, 直至循环执行次数被减为0时,结束整个循环过程

    //等效于java或者c里面的 while(n-->0;)
    initial
    begin
    	clock=0;
        repeat(8) clock=~clock;//循环体所预先制定的循环次数为8次,相应产生
    4个时钟周期信号
    end
    
  • while

    先判断条件表 达式是否为真,如果是,则执行后面的语句,接着再回来 判断条件表达式是否仍为真,只要是真,再执行语句,直 至某一次执行完语句后,判断出条件表达式的值为非真时, 结束循环过程。为保证循环过程的正常结束,通常在循环 体内部必定有一条语句用以改变条件表达式的值

    //同java 和c
    initial
    begin
    clock=0;
    while(1)
    #50 clock=~clock;
    end
    
  • for
    同java c

    initial
    begin
    clk=0;
    for(i=0;i>=0;i=i+1)
    #50 clk=~clk;
    end
    
例题:看图写代码:

在这里插入图片描述

module shift_regist2(Q,D,rst,clk);
output [7:0] Q;
input D,rst,clk;
reg [7:0] Q;
integer i;
always @(posedge clk)
if (!rst) Q<=8'b000000;
else
for (i=7;i>0;i=i-1)
begin
Q[i]<=Q[i-1];
Q[0]<=D;
end
endmodule
作业题1:

在这里插入图片描述

在这里插入图片描述

作业题2:

在这里插入图片描述

在这里插入图片描述

结构化建模
1.模块级别建模(模块调用)
D_unblock1  d0 (din,clk,out1,out2);
D_unblocl1  d[15:0](din,clk,out1,out2);
dff U1(.q(out[0]),.d(din),.clk(clock),.clr(clear));
module para1(C,D);
parameter a=1;
parameter b=1; ...
endmodule

module para2; ...
    para1 #(4,3) U1(C1,D1) ;
    para1 #(.b(6),.a(5)) U2(C2,D2); //语句2 ...
endmodule
2.门级建模

在这里插入图片描述

​ 怎么写呢?

and A1 (out1, in1, in2);
or O2 (a, b, c, d);
xor X1(x_out, p1, p2);
3.开关级建模

在这里插入图片描述

  • 基本的nmos开关电路

    module aNMOS(din,ctr,out);
    input din,ctr;
    output out;
    nmos U1(out,din,ctr);
    endmodule
    

ff U1(.q(out[0]),.d(din),.clk(clock),.clr(clear));


~~~verilog
module para1(C,D);
parameter a=1;
parameter b=1; ...
endmodule

module para2; ...
    para1 #(4,3) U1(C1,D1) ;
    para1 #(.b(6),.a(5)) U2(C2,D2); //语句2 ...
endmodule
2.门级建模

​ 怎么写呢?

and A1 (out1, in1, in2);
or O2 (a, b, c, d);
xor X1(x_out, p1, p2);
3.开关级建模
  • 基本的nmos开关电路

    module aNMOS(din,ctr,out);
    input din,ctr;
    output out;
    nmos U1(out,din,ctr);
    endmodule
    

在这里插入图片描述

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值