本文节选自《从算法设计到硬件逻辑的实现》,仅供学习交流使用。
用 Verilog HDL 来描述加法器是相当容易的,只需要把运算表达式写出就可以了,见下例。
module add_4( X, Y, sum, C);
input [3 : 0] X, Y;
output [3: 0] sum;
output C;
assign {C, Sum } = X + Y;
endmodule
而 16 位加法器只需要扩大位数即可,见下例:
module add_16( X, Y, sum, C);
input [15 : 0] X, Y;
output [15 : 0] sum;
output C;
assign {C, Sum } = X + Y;
endmodule
这样设计的加法器在行为仿真时是没有延时的。借助综合器,可以根据以上 Verilog HDL源代码自动将其综合成典型的加法器电路结构。综合器有许多选项可供设计者选择,以便用来控制自动生成电路的性能。设计者可以考虑提高电路的速度,也可以考虑节省电路元件以减少电路占用硅片的面积。综合器会自动根据选项为你挑选一种基本加法器的结构。
有的高性能综合器还可以根据用户对运算速度的要求插入流水线结构,来提高运算器的性能。可见在综合工具的资源库中存有许多种基本的电路结构,通过编译系统的分析,自动为设计者选择一种电路结构,随着综合器的日益成熟它的功能将越来越强。然后设计者还需通过布局布线工具生成具有布线延迟的电路,再进行后仿真,便可知道该加法器的实际延时。根据实际的延迟便可以确定使用该运算逻辑的最高频率。若需要重复使用该运算器,则需要在控制数据流动的状态机中为其安排必要的时序。
用 Verilog HDL 来描述乘法器是相当容易的,只需要把运算表达式写出就可以了,见下例。
module mult_4( X, Y, Product);
input [3 : 0] X, Y;
output [7 : 0] Product;
assign Product = X * Y;
endmodule
而 8 位乘法器只需要扩大位数即可,见下例:
module mult_8( X, Y, Product);
input [7 : 0] X, Y;
output [15 : 0] Product;
assign Product = X * Y;
endmodule
这样设计的乘法器在行为仿真时是没有延时的。借助综合器,可以根据以上 VerilogHDL 源代码自动将其综合成典型的乘法器电路结构。综合器有许多选项可供设计者选择,以便用来控制自动生成电路的性能。设计者可以考虑提高速度,也可以考虑节省电路元件以减少电路占用硅片的面积。综合器会自动根据选项和约束文件为你挑选一种基本乘法器的结构。有的高性能综合器还可以根据用户对运算速度的要求插入流水线结构,来提高运算器的性能。随着综合工具的发展,其资源库中将存有越来越多种类的基本电路结构,通过编译系统的分析,自动为设计者选择一种更符合设计者要求的电路结构。然后设计者通过布局布线工具生成具有布线延迟的电路,再进行后仿真,便可精确地知道该乘法器的实际延时。根据实际的延迟便可以确定使用该运算逻辑的最高频率。若需要重复使用该运算器,便可以根据此数据在控制数据流动的状态机中为其安排必要的时序。所以借助于硬件描述语言和综合工具大大加快了计算逻辑电路设计的过程。
用 Verilog HDL 来设计 比较电路是很容易的。下面就是一个位数可以由用户定义的比较电路模块:
module compare_n ( X, Y, XGY, XSY, XEY);
input [width-1:0] X, Y;
output XGY, XSY, XEY;
reg XGY, XSY, XEY;
parameter width = 8;
always @ ( X or Y ) // 每当 X 或 Y 变化时
begin
if ( X = = Y )
XEY = 1; // 设置 X 等于 Y的信号为 1
else XEY = 0;
if (X > Y)
XGY = 1; // 设置 X 大于 Y的信号为 1
else XGY = 0;
if (X < Y)
XSY = 1; // 设置 X 小于 Y的信号为 1
else XSY = 0;
end
endmodule
综合工具能自动把以上原代码综合成一个八位比较器。如果在实例引用时分别改变参数width 值为 16 和 32 综合工具就能自动把以上原代码分别综合成 16 位和 32 位的比较器。
用 Verilog HDL 来设计多路选择器电路是很容易的。下面就是带使能控制信号的数据位宽可以由用户定义的八路数据选择器模块:
module Mux_8( addr,in1, in2, in3, in4, in5, in6, in7, in8, Mout, nCS);
input [2:0] addr;
input [width-1] in1, in2, in3, in4, in5, in6, in7, in8;
output [width-1] Mout;
parameter width = 8;
always @ (addr or in1 or in2 or in3 or in4 or in5 or in6 or in7 or in8)
begin
if (!ncs)
case(addr)
3’b000: Mout = in1;
3’b001: Mout = in2;
3’b010: Mout = in3;
3’b011: Mout = in4;
3’b100: Mout = in5;
3’b101: Mout = in6;
3’b110: Mout = in7;
3’b111: Mout = in8;
endcase
else
Mout = 0;
end
endmodule
综合工具能自动把以上原代码综合成一个数据位宽为 8 的八路选一数据多路器。如果在实例引用时分别改变参数 width 值为 16 和 32,综合工具就能自动把以上原代码分别综合成数据宽度为 16 位和 32 位的八选一数据多路器。
还有总线和流水线,等到以后的博文再说。