FPGA Verilog 问题

  • USRP 的 FPGA Verilog 代码可以被修改吗?

是的,可以被修改。FPGA 的 Verilog 的顶层文件可以在 usrp/fpga/toplevel/usrp_std/usrp_std.v 找到,其它的代码在 usrp/fpga/sdr_lib/*.v
  • 想通过重新编译所有的 FPGA 的 Verilog 文件以便对每个模块的功用有更好的理解。这些代码是用 Quartus II 进行编译的,对吗?

如果想从源代码来构建 FPGA 的 .rbf 文件(这其实没有必要,在 usrp/fpga/rbf 的目录下已经提供预编译好的 .rbf 文件),便需要 Altera 公司的免费工具软件 Qutarus II。我们使用的是 Quartus II Web 版。
项目文件是 usrp/fpga/toplevel/usrp_std/usrp_std.qpf。FPGA 的 Verilog 的顶层文件可以在 usrp/fpga/toplevel/usrp_std/usrp_std.v 找到,其它的代码在 usrp/fpga/sdr_lib/*.v
  • FPGA是如何掌控数据入出 AD9862 的?

对于FPGA 接收(RX )链路而言,DC 偏置 (DC offset) 去除的过程中,其输入被赋值如下:

adc_interface.v 代码中, 不难发现 rx_dcoffset 模块的输入被赋值如下:
.adc_in({adc0[11],adc0,3'b0})
其中,1位符号延伸,12位原始数据位,然后3位0标志。

对于FPGA 的发射(TX)链路而言,可参看 [source:gnuradio/trunk/usrp/fpga/toplevel/usrp_std/usrp_std.v#L179 usrp_std.v]  usrp_std.v, 来自于 tx_chain 模块的 16 位的数据流被分割成一个 2 位的单元然后被传出到 DACs。
  • tx_chain.v 用到 phase_acc 模块。它用一个7 位串行地址和 32 位串行数据作为输入并且输出 32位相位。有人了解它在发射链路(tx_china)中的功用和目的吗?

它没有被使能(激活)。如果被激活的话,它将替代 AD9862 中的 DUC 在 FPGA 中起上变频的作用。请注意,此代码多年都没有做过任何测试,(所以对它想做些工作)是有些困难的。
  • 正在研究 serial_io.v 模块,不解其功用和目的?

serial_io.v 仅仅用于读写 FPGA 的寄存器。
  • 数据流以串行输入方式(从 USB 总线)进入 FX2 芯片。然后通过 GPIF 总线以16 位并行方式进入 FPGA 。在 FPGA 内该输入信号被命名为 usb_data。然而在研读 verilog 的 serial_io.v 模块的代码时,似乎此模块在把 SDI (串行数据输入)输入的串行数据变换成并行数据并且把它放入一个 32 位的串行数据输出寄存器中。纳闷的是 FX2 芯片把来自 USB 串行数据变为并行数据还是以串行数据进入 FPGA 后,由 FPGA 内部的 Verilog 的模块把它转换成并行数据。所以,不确定数据从 USB 到 usrp_std.v 模块是 16 位的 usb_data 输入还是 SDI(串行数据)输入。

真实的进出 DACs/ADCs (DUCs/DDCs) 的数据是通过 16-位 GPIF 总线。(#帮帮我# 我没有回答这儿的所有的问题!)
  • 正在研究顶层模块 usrp_std.v。个人理解从 PC 送出的数据或者接收送往 PC 的数据是 “usb 类的数据” 的入出信号。其它入出信号 io_tx_a, io_tx_b, io_rx_a 和 io_rx_b 是同子板关联的。但还是纳闷下列输入信号:rx_a_a, rx_b_a, rx_a_b, rx_b_b 和输出信号:tx_a, tx_b 的功用?

参考: AD9862 Data Sheet.   #FIXME: cannot reference attachments of other objects
  • 正在研究发射缓存器的 verilog 代码(tx_buffer.v)。 它好像用到两个时钟信号。txclk 用于读取 fifo_4k,usbclk 用于写入 fifo_4k。这些时钟信号的频率如何?

USB 的时钟由 FX2 提供,它的频率是 48 MHz。
  • usrp_std 模块的一个输入是 SDI (串行数据输入)。它的源头何处?

8051 位拆裂的(bit-bangs -软件替代专职硬件的串行通信的技术产生的) SDI (串行数据输入)、时钟、及选通脉冲信号。相比 FPGA 的其它功用它的响应很“慢”,源码参考:usrp/firmware/src/usrp2/spi.c
  • tx_buffer 和 rx_buffer 里的 FIFO 存储器的容量分配是其容量的两倍,Quartus 的编译报告显示 65K '位'(8192 字节)。这其中有什么奥秘?

FIFO 段的长度是 4K行,每行是 16 位。
  • 在 cordic.v 中,16 位的向量 xi, yi 和 zi 是作为输入传输的。cordic 的常量是预定义的。诸如:wire [bitwidth+1:0] xi_ext = {{2{xi[bitwidth-1]}},xi}; 此类操作。这仅仅是一般意义的级联和赋值吗?

是的,我们使用 xi 的符号延伸.
  • 就 @posedg 时钟而言,在复位的情况下,x0, y0, z0 被初始化为‘0’。其次,如果被使能,z0 除头两位外其余都被赋值。头两位用于状态标志位。在此,它们被用于标志四象限和用xi_ext 和 yi_ext 标志四象限的90、180、270 或 360 度的调整角。此理解正确吗?

正确。
  • cordic_stage 的过程都被定义了,它们一般用来传输输入的参数 x0, y0, z0 及常数 c00 等。我还是不明白 #(bitwidth+2,zwidth-1,0) 的含义?

#( ) 是用来把参数传给被例程的模块。
  • 在 cordic_stage.v 中,如果复位,x0, y0, z0 便被赋值为0。如果被使能,便检查 z 值。我是这样理解 cordic 逻辑的:如果说目前的角度是45,希望值是20,从希望值中减去,然后根据相应的调整去调整相应的 x 轴和 y 轴的数值。这段代码检查, if "z_is_pos" 便进行下一步. 我不太清楚 xi - {{shift+1{yi[bitwidth-1]}}, yi[bitwidth-2:shift]} 的功用。我的理解 CORDIC 是基于角度的调整,把 x 和 y 轴偶数化。{ } 的语句是用来在 Verilog 内级联。

符号延伸
  • 在 cordic.v 中,xo, yo 和 zo 连续不断的每次相应地以 x12, y12 或 z12 为增(减)值变化。但是还是不太清楚 cordic.v 是如何达到想要的准确的变化角的。研究表明算法是不停的调整当前的角度来趋近希望的角度,但是我没有清楚它是如何在 cordic.v 中实现的。

它的调整原理如下。如果角度是正值便减少;如果角度是负值便增加。它是不停地趋近零值。
  • 如何对 tx_chain.v 写测试用例(test bench)?

写测试用例 (testbench),必须恰当的设置内插频率。如果想用 CORDIC 还必须设置好相位累积器。应当把(选通)采样频率设置为 Fs。其 Fs 是小于时钟频率并且满足 Fs x interp_rate = the clock rate。这样一来以频率 Fs 把采样数据(选通)送往链路。

还应当确认内插频率(定时或同步的选通脉冲)和采样频率(定时或同步的选通脉冲)的一致连贯性 -- 比如说:每 15 个时钟(补插和采样一次)。不能随机设置或撤销。

并不需要一组(测试)频率。只需这么一些频率,这些频率之间应当具有2*PI 的相位差,而每个 CORDIC 的采样频率值是处于 231-1 之内。可能需要 sine 函数波形或者一些滤波信号,尝试一下脉冲链{1,0,1,0,...}或者下载 [source:gnuradio/branches/developers/zhuochen/simulations/burst_test/math_real.v math_real.v]  模块,如下的测试用例 [source:gnuradio/branches/developers/zhuochen/simulations/burst_test/test_chan_fifo_reader.v test_chan_fifo_reader.v] 可以被用来产生一些 sine 和 cosines 函数。
  • 可以把自己的 Verilog 代码烧入去测试吗?

对于前期综合、RTL仿真和测试,使用 Linux 版本的 ICARUS Verilog 和 GTKWave。 (这里)值得注意的是,如若计划使用 ICARUS Verilog,需参阅最新的开发者指导简介,因为此前编写的代码在使用中发现有些纰漏。

在这里肯定得不到赞同的是,在对自己所做的事情没有把握的情况下,却简单地把这些代码下载到 FPGA 去运行它。精确地建模会节约大量的诊错时间。
  • 浏览邮件列表后发现目前的 Verilog/VHDL 的代码构建占据了 FPGA 的 95% 的资源。然而有些邮件指出,简化接收机的功能可以节省一些 FPGA 的资源。这是如何实现?

头文件 config.vh(骨架?)掌控着配置的构建而且是功能化的。修改它来使用文件: ../include/common_config_1rxhb_1tx.vh  便是方法(如下):
// Uncomment this for 1 RX channel (w/ halfband) & 1 transmit channel
@include "../include/common_config_1rxhb_1tx.vh"
这样便可节省出 FPGA 大量的资源!
  • 在 rx_chain.v 中, 下面信号 - sample_strobe, decimator_strobe, hb_strobe, serial_addr, serial_data, serial_strobe, debugdata, debugctrl 的功用如何?

sample_strobe 是在 ADC 全采样之后,用于抽取器-级联积分梳状滤波器(CIC Filters)输入。

decimator_strobe 是由抽取器-级联积分梳状滤波器(CIC Filters)产生,用于特定和抽取频率下用。如果抽取系数为N,你会得到一个 1/N 周期的采样。这个比率在此链路中一直被保存。

hb_strobe 来自于半带(HB FIR)滤波器。它是一个抽取系数为常数 2 ,在半带(HB FIR) 滤波器需要把数据送出 RX 链路时被使能。serial_*

serial_* (serial_addr, serial_data, serial_strobe)是用来写寄存器的接口。如果你想在模块内修改任何寄存器,简单的串行接口 FX2 -> FPGA 便能改变它们。在这种情况下,他们一般被用于 FPGA 的 CORDIC 的相位累加器相关联的寄存器。

debug* (debugdata, debugctrl )正如名字暗示是用于诊错。在目前的构架中,它好像是输入到半带(HB FIR) 滤波器是诊错总线的输出(#帮帮我,可能有错#)

仅用作提供一点信息,插值选通(interpolation strobes)和滤波模块可参考 [source:gnuradio/trunk/usrp/fpga/sdr_lib/master_control.v master_control.v]。

一旦串行数据被恰当写入,寄存器便被更新。strobe_gen 是个倒计数器,一旦计数减到零,便被复位到比率计数器的输入值。
  • CORDIC 模块输出有效的数据需占有多少时钟,为何 cordic 算法的构建(cordic.v 中)要固定为12层迭代呢?

管道流水线模块(pipeline module)全速的采样信号,它需 12 个管道流水线阶段并输出旋转向量(rotated vector)。为何是12,仅仅是用于生成寄存器并表示阶段用。也可以表现更深的管道流水线(更多的管道流水线阶段),甚至用变量表现管道流水线阶段。TODO 在此被建议用来关联变量的长度 - 不太确定是运行还是构建阶段,无论如何值得去尝试。
  • 可以使用 Altera 的巨集(megacell)模块吗?

是的、可以, 比如,在构建 tx_usb_fifo 和 rx_usb_fifo 中,可以让 Quartus 产生一个合适的双时钟 FIFO 巨集(megacell)。基于此,Matt 已经产生 fifo_2k 和 fifo_4k 模块。参考Quartus的手册和《Cyclone Device Handbook》。
  • setting_reg 模块如下。

module setting_reg(input clock, input reset, input strobe, input wire [6:0] addr,
input wire [31:0] in, output reg [31:0] out, output reg changed);

[source:gnuradio/trunk/usrp/fpga/sdr_lib/master_control.v master_control.v] 所谈及的模块中, 发现 setting_reg 被如下方式调用:

setting_reg #(`FR_MASTER_CTRL) sr_mstr_ctrl(.clock(master_clk),.reset(1'b0),.strobe(serial_strobe),
.addr(serial_addr),.in(serial_data),.out(master_controls));

然而,在[source:gnuradio/trunk/usrp/fpga/sdr_lib/setting_reg.v setting_reg.v] 所涉及的模块中, setting_reg 模块有一个输出信号被称为 "changed". 有人能告诉我 "changed" 信号的情况吗?

“changed” 已不使用, 被淘汰了.


















注:FPGA Verilog Questions(原文出处,翻译整理仅供参考!)