首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Verilog HDL设计练习进阶(五)--用always块实现较复杂的组合逻辑电路

Verilog HDL设计练习进阶(五)--用always块实现较复杂的组合逻辑电路

练习五. 用always块实现较复杂的组合逻辑电路目的: 1.掌握用always实现组合逻辑电路的方法;
      2.了解assign与always两种组合逻辑电路实现方法之间的区别。
    仅使用assign结构来实现组合逻辑电路,在设计中会发现很多地方会显得冗长且效率低下。而适当地采用always来设计组合逻辑,往往会更具实效。已进行的范例和练习中,我们仅在实现时序逻辑电路时使用always块。从现在开始,我们对它的看法要稍稍改变。
下面是一个简单的指令译码电路的设计示例。该电路通过对指令的判断,对输入数据执行相应的操作,包括加、减、与、或和求反,并且无论是指令作用的数据还是指令本身发生变化,结果都要作出及时的反应。显然,这是一个较为复杂的组合逻辑电路,如果采用assign
语句,表达起来非常复杂。示例中使用了电平敏感的always块,所谓电平敏感的触发条件是指在@后的括号内电平列表中的任何一个电平发生变化,(与时序逻辑不同,它在@后的括号内没有沿敏感关键词,如posedge 或negedge)就能触发always块的动作,并且运用了case结构来进行分支判断,不但设计思想得到直观的体现,而且代码看起来非常整齐、便于理解。
//---------------  alu.v --------------------------
`define plus    3'd0
`define minus   3'd1
`define band    3'd2
`define bor     3'd3
`define unegate 3'd4
module  alu(out,opcode,a,b);
output[7:0] out;
reg[7:0]    out;
input[2:0] opcode;
input[7:0] a,b;              //操作数。
[email=always@(opcode]always@(opcode[/email] or a or b)    //电平敏感的always块
begin
      case(opcode)
          `plus:  out = a+b;   //加操作。
          `minus: out = a-b;  //减操作。
          `band:  out = a&b;   //求与。
          `bor:   out = a|b;   //求或。
          `unegate:  out=~a; //求反。
          default:   out=8'hx;//未收到指令时,输出任意态。
      endcase
end
endmodule   
同一组合逻辑电路分别用always块和连续赋值语句assign描述时,代码的形式大相径庭,但是在always中适当运用default(在case结构中)和else(在if…else结构中),通常可以综合为纯组合逻辑,尽管被赋值的变量一定要定义为reg型。不过,如果不使用default或else对缺省项进行说明,则易生成意想不到的锁存器,这一点一定要加以注意。
指令译码器的测试模块源代码:
//------------- alu_Top.v -----------------
`timescale 1ns/1ns
`include  "./alu.v"
module    alutest;
   wire[7:0] out;
   reg[7:0]  a,b;
   reg[2:0]  opcode;
   parameter   times=5;
   initial
    begin  
        a={$random}%256;  //Give a radom number blongs to [0,255] .
        b={$random}%256;  //Give a radom number blongs to [0,255].
        opcode=3'h0;
        repeat(times)
          begin
          #100     a={$random}%256;  //Give a radom number.
                   b={$random}%256;  //Give a radom number.
                   opcode=opcode+1;
          end
        #100  $stop;
   end         
   alu    alu1(out,opcode,a,b);
endmodule
仿真波形(部分):
[[wysiwyg_imageupload:248:]] 练习:运用always块设计一个八路数据选择器。要求:每路输入数据与输出数据均为4位2进制数,当选择开关(至少3位)或输入数据发生变化时,输出数据也相应地变化。
记录学习中的点点滴滴,让每一天过的更加有意义!
返回列表