目录
练习五. 用always块实现较复杂的组合逻辑电路
目的: 1.掌握用always实现组合逻辑电路的方法;2.了解assign与always两种组合逻辑电路实现方法之间的区别。
仅使用assign结构来实现组合逻辑电路,在设计中会发现很多地方会显得冗长且效率低下。而适当地采用always来设计组合逻辑,往往会更具实效。已进行的范例和练习中,我们仅在实现时序逻辑电路时使用always块。从现在开始,我们对它的看法要稍稍改变。
下面是一个简单的指令译码电路的设计示例。该电路通过对指令的判断,对输入数据执行相应的操作,包括加、减、与、或和求反,并且无论是指令作用的数据还是指令本身发生变化,结果都要作出及时的反应。显然,这是一个较为复杂的组合逻辑电路,如果采用assign语句,表达起来非常复杂。示例中使用了电平敏感的always块,所谓电平敏感的触发条件是指在@后的括号内电平列表中的任何一个电平发生变化,(与时序逻辑不同,它在@后的括号内没有沿敏感关键词,如posedge 或negedge)就能触发always块的动作,并且运用了case结构来进行分支判断,不但设计思想得到直观的体现,而且代码看起来非常整齐、便于理解
// ALU.v
`timescale 1ns / 1ps
`define add 3'd0
`define sub 3'd1
`define and 3'd2
`define or 3'd3
`define turn 3'd4
module ALU(
input [2:0] opcode,
input [7:0] a,b,
output [7:0] out
);
reg [7:0] out;
always@(a or b or opcode)
begin
case(opcode)
`add : out = a + b;
`sub : out = a - b;
`and : out = a & b;
`or : out = a | b;
`turn : out = ~a;
default: out = 8'h0;
endcase
end
endmodule
// Module Name: ALU_simu
`timescale 1ns / 1ps
module ALU_simu;
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(opcode,a,b,out);
endmodule