查表法
查表法的应用范围非常之广,利用查表法,我们可以实现任意的组合逻辑功能,甚至可以实现任意的时序逻辑功能
只要系统提供的存储空间(可以是FPGA内部的或外部的)足够大,查表法可以帮助我们实现任何想实现的逻辑功能,这也是为什么我们说查表法是“万能的”了。
当然了,对于FPGA设计者来说,通常我们使用查表法,都是为了解决组合逻辑方面的问题,例如,实现任意波形发生器,或者实现任意函数求解器,等等。采用查表法来实现组合逻辑的优点是——逻辑功能实现起来相对较为简单(核心技术就是数据的存储与读取而已),且整个组合逻辑的延迟也相对较小且固定(无论功能复杂还是简单,基于查找表的逻辑延迟仅取决于存储器的地址总线到数据输出总线之间的延迟);不过其缺点就是会消耗过多的系统存储空间(存储空间大小与组合逻辑的输入端口数呈二的整数次幂关系)。因此,虽然查表法是“万能”的,但是在进行FPGA项目开发时,我们不能把它当成万能膏药,到处乱贴,只有对于那些适合的情况,才应该予以考虑,从而达到出其不意的绝妙效果。那么,本章节接下来以几个示例来为大家简单的介绍一下查表法的使用。
正弦波发生器示例
现假设FPGA外部有一块DA芯片,我们要利用这块DA芯片向外界发送一路频率为1MHz的模拟正弦波。
已知FPGA内部主时钟频率为10MHz,外部DA芯片接收8bits并行数字信号并将其转换为电压值,其中数字信号取值范围为整数0255,而DA芯片会将其均匀转换到对应的模拟电压-1.51.5V之间。
在不倍频的前提下,10MHz的时钟信号就代表发送给DA芯片的数字序列采样率最高为10MHz,因此采样间隔为100ns。而1MHz的正弦波的周期为1000ns,正好1个正弦波周期可以被10MHz的采样率均匀的采上10个点。综上所述,我们可以从正弦波的一个周期中均匀的取出10个样点的值(初始相位不同,结果也会有不同,本例以0弧度作为起始相位), 然后对其进行放大、直流偏移、整数近似等操作,进而得出10个介于0~255之间的正弦波采样点。最后,以10MHz的频率循环发送这10个采样点给DA芯片,便可实现发送1路1MHz模拟正弦波的需求。
// Verilog example
module SinWave(
input clk,
input rst,
output toDAClk,
output [7:0] toDAData
);
reg [7:0] ROM [9:0];
reg [3:0] addr;
initial begin
ROM[0] = 8'd128; ROM[1] = 8'd203; ROM[2] = 8'd249; ROM[3] = 8'd249;
ROM[4] = 8'd203; ROM[5] = 8'd128; ROM[6] = 8'd53; ROM[7] = 8'd7;
ROM[8] = 8'd7; ROM[9] = 8'd53;
end
always@(posedge clk)
begin
if(rst == 1'b1)
begin
addr <= 4'd0;
end
else
begin
if(addr == 4'd9)
begin
addr <= 4'd0;
end
else
begin
addr <= addr + 1'b1;
end
end
end
assign toDAClk = ~ clk;
assign toDAData = ROM[addr];
endmodule