您的位置:首页 > 其它

简单组合逻辑电路的verilog实现(包括三态门、3-8译码器、8-3优先编码器、8bit奇偶校验器)

2013-06-14 16:49 645 查看
2013-06-14 15:20:28

简单组合逻辑电路的verilog实现,包括三态门、3-8译码器、8-3优先编码器、8bit奇偶校验器,测试功能正确、可综合。

小结:

assign与always都可实现组合逻辑,有什么区别?

组合逻辑用数据流描述(一般将用assign描述的称为数据流描述)或者RTL描述(一般将用always描述的称为数据流描述)都可以实现;

当组合逻辑较为简单时(如用一句话就可以实现的求反、求和assign sum = a + b; assign dout = ~din;等),用assign比较方便;

若组合逻辑比较复杂,则用always比较合适。

组合逻辑用always实现时,敏感列表一定要写全;

写代码时,脑子里要有硬件的的概念,这是与C语言等软件语言的重要区别之一;

为防止锁存器,对if语句要加上else,对case语句,要加上default

如下面的就会产生锁存器:

always@(din)
begin
if(din[7] == 1'b1) dout = 3'b111;
else if(din[6] == 1'b1) dout = 3'b110;
else if(din[5] == 1'b1) dout = 3'b101;
else if(din[4] == 1'b1) dout = 3'b100;
else if(din[3] == 1'b1) dout = 3'b011;
else if(din[2] == 1'b1) dout = 3'b010;
else if(din[1] == 1'b1) dout = 3'b001;
else if(din[0] == 1'b1) dout = 3'b000;
else dout = dout;
end


改为如下,则不会有锁存器:

always@(din)
begin
if(din[7] == 1'b1) dout = 3'b111;
else if(din[6] == 1'b1) dout = 3'b110;
else if(din[5] == 1'b1) dout = 3'b101;
else if(din[4] == 1'b1) dout = 3'b100;
else if(din[3] == 1'b1) dout = 3'b011;
else if(din[2] == 1'b1) dout = 3'b010;
else if(din[1] == 1'b1) dout = 3'b001;
else dout = 3'b000;  //防止产生锁存器,将上面两行换为这一行
end


简单门电路的门级、数据流、RTL描述

实现组合逻辑:f = ~(ab)|(bcd)

代码:

odule simple_gate(
a,
b,
c,
d,
f
);

input a;
input b;
input c;
input d;

output f;
/*
//门级描述
nand (f1,a,b);
and (f2,b,c,d);

or(f,f1,f2);

//数据流描述
assign f = ~(a & b) | (b & c & d);
*/
//RTL描述
reg f;
always@(a,b,c,d)
begin
f = ~(a & b) | (b & c & d);
end

endmodule


门级描述综合后得到的RTL级电路:



数据流描述综合后得到的RTL级电路:



RTL描述综合后得到的RTL级电路与数据流描述综合后得到的RTL级电路完全相同。

三态门的门级、数据流、RTL描述:

代码:

module tri_gate(
din,
en,
dout
);

input din;
input en;

output dout;

//门级描述
//bufif1 (dout,din,en);

//数据流描述
//assign dout = en ? din : 1'bz;

//RTL描述
reg dout;

always@(din,en)
if(en)
dout = din;
else
dout = 1'bz;

endmodule


门级描述综合,RTL图:



数据流描述综合,RTL图与门级的完全相同。

RTL描述综合,RTL图同样与门级的完全相同。

3-8译码器的verilog实现

RTL描述,用case语句或if...if 语句实现,如下:

module decode_3to8(
din,
dout
);

input [2:0] din;
output [7:0] dout;

reg [7:0] dout;

//case语句实现
always@(din)
case(din)
3'b000 : dout = 8'b0000_0001;
3'b001 : dout = 8'b0000_0010;
3'b010 : dout = 8'b0000_0100;
3'b011 : dout = 8'b0000_1000;
3'b100 : dout = 8'b0001_0000;
3'b101 : dout = 8'b0010_0000;
3'b110 : dout = 8'b0100_0000;
3'b111 : dout = 8'b1000_0000;
endcase
/*
//if...if语句实现
always@(din)
begin
if (din == 3'b000)  dout = 8'b0000_0001;
if (din == 3'b001)  dout = 8'b0000_0010;
if (din == 3'b010)  dout = 8'b0000_0100;
if (din == 3'b011)  dout = 8'b0000_1000;
if (din == 3'b100)  dout = 8'b0001_0000;
if (din == 3'b101)  dout = 8'b0010_0000;
if (din == 3'b110)  dout = 8'b0100_0000;
if (din == 3'b111)  dout = 8'b1000_0000;
end
*/
endmodule


用case语句或if语句时:

综合选项中Decoder Extraction设为YES,自动综合为用器件本身的硬件译码器实现,如下:



若综合选项Decoder Extraction设为NO,用case语句或if语句,综合RTL图为:

是用8bitROM实现的



8-3优先编码器的verilog实现

RTL描述,用if...else的特点实现优先编码,如下:

module encoder_8to3(
din,
dout
);

input [7:0] din;
output [2:0] dout;

reg [2:0] dout;

//if语句中仅仅判断1个bit即可
always@(din)
begin
if(din[7] == 1'b1) dout = 3'b111;
else if(din[6] == 1'b1) dout = 3'b110;
else if(din[5] == 1'b1) dout = 3'b101;
else if(din[4] == 1'b1) dout = 3'b100;
else if(din[3] == 1'b1) dout = 3'b011;
else if(din[2] == 1'b1) dout = 3'b010;
else if(din[1] == 1'b1) dout = 3'b001;
//else if(din[0] == 1'b1) dout = 3'b000;
//else dout = dout;
else dout = 3'b000;  //防止产生锁存器,将上面两行换为这一行
end

/*
//if语句中仅仅判断1个bit即可,这种是错误的
always@(din)
begin
if(din == 8'b1000_0000) dout = 3'b111;
else if(din == 8'b0100_0000) dout = 3'b110;
else if(din == 8'b0010_0000) dout = 3'b101;
else if(din == 8'b0001_0000) dout = 3'b100;
else if(din == 8'b0000_1000) dout = 3'b011;
else if(din == 8'b0000_0100) dout = 3'b010;
else if(din == 8'b0000_0010) dout = 3'b001;
else if(din == 8'b0000_0001) dout = 3'b000;
end
*/
endmodule


综合选项中Priority Encoder Extraction为YES,但是综合结果并没有使用优先编码器,原因未知。



改变代码,去掉锁存器:

//else if(din[0] == 1'b1) dout = 3'b000;
//else dout = dout;
else dout = 3'b000; //防止产生锁存器,将上面两行换为这一行

综合结果,可以看到,没有锁存器了:



奇偶校验器的verilog实现

数据流描述:

module odd_even_check(
din,
dout_even,
dout_odd
);

input [7:0] din;
output dout_even;
output dout_odd;

assign dout_odd = ^din;        //奇校验位
assign dout_even = ~dout_odd;    //偶校验位

endmodule


综合RTL图:



4选1数据选择器

可以用case或者if语句实现:

module mux(
din1,
din2,
din3,
din4,
sel,
dout
);

input din1;
input din2;
input din3;
input din4;
input [1:0] sel;

output dout;

reg dout;
/*
//用case语句实现
always@(din1,din2,din3,din4,sel)
begin
case(sel)
2'b00 : dout = din1;
2'b01 : dout = din2;
2'b10 : dout = din3;
default : dout = din4;
endcase
end
*/

//用if语句实现
always@(din1,din2,din3,din4,sel)
begin
if(sel == 2'b00) dout = din1;
else if(sel == 2'b01) dout = din2;
else if(sel == 2'b10) dout = din3;
else dout = din4;
end

endmodule


case语句与if语句描述综合结果完全相同,如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐