练习五:用always块实现较复杂的组合逻辑电路

一、实验目的

  1. 掌握用always实现较大组合逻辑电路的方法;
  2. 进一步了解assign与always两种组合电路实现方法的区别和注意点;
  3. 学习测试模块中随机数的产生和应用;
  4. 学习综合不同层次的仿真,并比较结果。

 

二、实验原理

        使用assign结构来实现组合逻辑电路,如果逻辑关系比较复杂,不容易理解语句的功能。而适当地采用always来设计组合逻辑,使源代码语句的功能容易理解。

        下面是一个简单的指令译码电路的设计示例。该电路通过对指令的判断,对输入数据执行相应的操作,包括加、减、与、或和求反,并且无论是指令作用的数据还是指令本身发生变化,结果都要作出及时的反应。显然,这是一个较为复杂的组合逻辑电路,如果采用assign语句,表达起来非常复杂。示例中使用了电平敏感的always块,所谓电平敏感的触发条件,是指在@后的括号内电平列表中的任何一个电平发生变化(与时序逻辑不同,它在@后的括号内没有沿敏感关键词,如posedge或negedge),就能触发always块的动作,并且运用了case结构来进行分支判断,不但设计思想得到直观的体现,而且代码看起来非常整齐、便于理解。

       同一组合逻辑电路分别用always块和连续赋值语句assign 描述时,代码的形式大相径庭,但是在always中,若适当运用default(在case结构中)和else(在if…else结构中)语句时,通常可以综合为纯组合逻辑,尽管被赋值的变量一定要定义为reg型;若不使用default或else对默认项进行说明,则易生成意想不到的锁存器,这点一定要加以注意。

模块源代码:
//-------------- 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;
  
  always@(opcode or a or b)
  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



测试模块源代码:
//-------------- alutest.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;
    b={$random}%256;
    opcode=3'h0;
    repeat(times)
    begin
      #100  a={$random}%256;
            b={$random}%256;
            opcode=opcode+1;
    end
    #100  $stop;
  end
  
  alu alu1(out,opcode,a,b);
endmodule

复杂组合逻辑电路的仿真波形(部分)如下所示:

 

三、实验要求及实验内容

(1)实验内容:

         运用always块设计一个8路数据选择器。要求:每路输入数据与输出数据均为4位2进制数,当选择开关(至少3位)或输入数据发送变化时,输出数据也相应地变化。

(2)实验代码:

模块源代码:
//-------------- mux8_to_1.v --------------
`timescale  1ns/1ns

module mux8_to_1(out,opcode,in1,in2,in3,in4,in5,in6,in7,in8);
  output    [7:0]   out;
  reg       [7:0]   out;
  input     [2:0]   opcode;
  input     [7:0]   in1,in2,in3,in4,in5,in6,in7,in8;
  
  always@(opcode or in1 or in2 or in3 or in4 or in5 or in6 or in7 or in8)
  begin
    case(opcode)
      3'b000: out=in1;
      3'b001: out=in2;
      3'b010: out=in3;
      3'b011: out=in4;
      3'b100: out=in5;
      3'b101: out=in6;
      3'b110: out=in7;
      3'b111: out=in8;
      default:  out=8'hx;
    endcase
  end
endmodule


测试模块源代码:
//-------------- mux8_to_1_Top.v  --------------
`timescale  1ns/1ns
`include    "./mux8_to_1.v"

module mux8_to_1_Top;
  wire    [7:0]   out;
  reg     [7:0]   in1,in2,in3,in4,in5,in6,in7,in8;
  reg     [2:0]   opcode;
  
  parameter times=8;
  
  initial
  begin
    in1={$random}%256;
    in2={$random}%256;
    in3={$random}%256;
    in4={$random}%256;
    in5={$random}%256;
    in6={$random}%256;
    in7={$random}%256;
    in8={$random}%256;
    opcode=3'h0;
    repeat(times)
    begin
      #100  in1={$random}%256;
            in2={$random}%256;
            in3={$random}%256;
            in4={$random}%256;
            in5={$random}%256;
            in6={$random}%256;
            in7={$random}%256;
            in8={$random}%256;
            opcode=opcode+1;
    end
    #100  $stop;
  end
  
  mux8_to_1 mux8to1(out,opcode,in1,in2,in3,in4,in5,in6,in7,in8);
endmodule

 

四、实验结果

 

 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星羽空间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值