mcupro 发表于 2011-7-14 01:41:45

【点滴积累FPGA】关于3-8译码器10种不同的表达

module decoder38_1( //使用位移操作
input a,
output y
);
assign y=1<<a;
endmodule

module decoder38_2( //使用CASE 语句
input a,
output y
);
reg y;
always @*
case (a)
0:y<=8'b0000_0001;
1:y<=8'b0000_0010;
2:y<=8'b0000_0100;
3:y<=8'b0000_1000;
4:y<=8'b0001_0000;
5:y<=8'b0010_0000;
6:y<=8'b0100_0000;
7:y<=8'b1000_0000;
endcase
endmodule




module decoder38_3( //使用if
input a,
output y
);
reg y;
always @*
if (a==0)y<='h01;else
if (a==1)y<='h02;else
if (a==2)y<='h04;else
if (a==3)y<='h08;else
if (a==4)y<='h10;else
if (a==5)y<='h20;else
if (a==6)y<='h40;else
if(a==7)y<='h80;else
y<='hx;
endmodule



module decoder38_4( //使用assign
input a,
output y
);

assign y = a==0 ;
assign y = a==1 ;
assign y = a==2 ;
assign y = a==3 ;
assign y = a==4 ;
assign y = a==5 ;
assign y = a==6 ;
assign y = a==7 ;

endmodule   


module decoder38_5( //使用位逻辑运算
input a,
output y
);

assign y = ~a & ~a & ~a ;//3'b000
assign y = ~a & ~a & a ;//3'b001
assign y = ~a & a & ~a ;//3'b010
assign y = ~a & a & a ;//3'b011
assign y = a & ~a & ~a ;//3'b100
assign y = a & ~a & a ;//3'b101
assign y = a & a & ~a ;//3'b110
assign y = a & a & a ;//3'b111

endmodule   

module decoder38_6(//使用?:表达式
input a,
output y
);
assign y = (a==0)?'h01:
         (a==1)?'h02:
         (a==2)?'h04:
         (a==3)?'h08:
         (a==4)?'h10:
         (a==5)?'h20:
         (a==6)?'h40:
         (a==7)?'h80:
         'hx;
endmodule



module decoder38_7(//使用循环
input a,
output y
);
reg y;

integer i ;//or reg i ;
always @*
for(i=0;i<=7;i=1+i)
if(a==i)y=1;else y=0;

endmodule



module decoder38_8( //使用 function 调用
input a,
output y
);
function do_dec38;
input din;
do_dec38 = 1<<din;
endfunction
assign y=do_dec38(a);
endmodule


module decoder38_9( //使用task 调用,此处可以综合
input a,
output y
);
reg y ;
task do_dec38;
input din;
y = 1<<din;
endtask

always @*
do_dec38(a);

endmodule


module decoder38_10( //例化模块实现。
input a,
output y
);

and3 y0_logic (.a0(~a),.a1(~a),.a2(~a),.b(y));
and3 y1_logic (.a0(~a),.a1(~a),.a2(a),.b(y));
and3 y2_logic (.a0(~a),.a1(a),.a2(~a),.b(y));
and3 y3_logic (.a0(~a),.a1(a),.a2(a),.b(y));
and3 y4_logic (.a0(a),.a1(~a),.a2(~a),.b(y));
and3 y5_logic (.a0(a),.a1(~a),.a2(a),.b(y));
and3 y6_logic (.a0(a),.a1(a),.a2(~a),.b(y));
and3 y7_logic (.a0(a),.a1(a),.a2(a),.b(y));
endmodule

module and3( //被例化模块:三输入与门
input a0,a1,a2,
output b
);
assign b = a0 & a1 & a2;
endmodule


1,以上所有模块都是综合并在硬件实现,并且实现功能以及逻辑资源占用量完全等效。
2,以上10个例子是比较典型的一题多解的例子,在设计中经常做这样的尝试能加深基础知识,也使思路更开阔,以及一种熟练驾驭语言的控制感。
3,decoder38_9 这个模块使用的是任务方式实现(task),是一个任务可以被综合的典型例子。
4,decoder38_8 使用了函数(fuction)。实际上所有用函数(function)能实现的功能都可以用assign来实现,因为硬件本质一样:都是门电路,不带有reg以及latch。
5,decoder38_10 和decoder38_8 书面上有点相似,但是decoder38_10共注重的是硬件的连接,表现为几个模块连接在一起组成一个新的模块。
6,对于电平敏感信号,提倡用always @* 写法,意思是包含了所有引起下述进程发生动作的敏感电平信号(注意非边缘信号)。
7,decoder38_7中使用循环了for,仅仅是告诉编译器进行怎样的处理,是一种类似脚本语言的特性。
8,decoder38_5和decoder38_10的描述方法更偏向硬件,是一种门级描述方法。
9,表达常量有2,10,16进值的形式(8进值就不要用了),要灵活选用。如decoder38_4采用10进值,decoder38_3采用16进值,decoder38_2采用2进值。
10,10中表达出一个结果,也说明了HDL描述语言不同于C之类的串行语言,如果C语言逐行扫描编译得到的汇编结果肯定是不一样,更不说2进值机器代码。"HDL = Hardware Description Language".确实是描述硬件的,告诉编译工具以及综合工具你要做什么,可以有不同的方法让它知道你要做什么。

823032003 发表于 2011-7-14 08:56:03

不错 很细。   支持支持 青岛银

jielove2003 发表于 2011-7-14 09:22:30

学习

lyl0719 发表于 2011-7-15 14:37:26

希望高手多出象这类题目。

ss_soldier 发表于 2011-7-15 19:54:34

受教。
感谢高手分享此等经验之谈。

mogong 发表于 2011-7-16 17:39:58

Verilog 看不懂,难道这里很少有人用VHDL吗??

gloryzkl 发表于 2011-7-16 20:32:15

楼主思路很开阔啊…

NJ8888 发表于 2011-7-16 20:36:24

我喜欢行为描述

sonireolxxx 发表于 2011-7-17 17:50:46

不是否定楼主的学习方式,但我觉得在一个问题上发散,不如尝试解决不同的问题收获大。

茴香豆的茴字有四种写法,不过有研究这四种写法的精力,不如再多学几个字,你觉得呢。

mcupro 发表于 2011-7-20 00:45:18

发此帖子的目的是抛砖引玉,提倡多总结。
页: [1]
查看完整版本: 【点滴积累FPGA】关于3-8译码器10种不同的表达