USRP_N210R4 verilog代码分析一:gpio_atr模块

2019-07-14 03:18发布

本文有hitter整理编辑,如需引用请注明出处。   总述:... 1 一、.. 原始代码以及RTL视图... 1 1    gpio_atr模块源码... 1 2    gpio_atr模块RTL视图... 3 3    setting_reg模块源码... 4 4    setting_reg模块源码... 5 二、. gpio_atr中次级模块例化分析... 6 三、. gpio_atr内实现功能分析... 7 1    输入,输出数据选择... 7 2    执行in/out选择以及赋值... 8 3    回读功能分析... 9 四、. gpio_atr其他输入引脚说明... 10 1     set_stb引脚... 10 2     set_addr[7:0]引脚... 10 3     set_addr[31:0]引脚... 10  
  总述:射频子板控制verilog模块为gpio_atr模块,其实现的功能即为:与控制与子板的通信,包括16个输入引脚,以及16个输出引脚。都为该模块控制。下文中将具体分析其控制的逻辑。   一、   原始代码以及RTL视图 其代码中例化setting_reg模块,现现将两部分源码以及RTL级视图如下: 1        gpio_atr模块源码 module gpio_atr  #(parameter BASE = 0,    parameter WIDTH = 32)   (input clk, input reset,    input set_stb, input [7:0] set_addr, input [31:0] set_data,    input rx, input tx,    inout [WIDTH-1:0] gpio,    output reg [31:0] gpio_readback    );      wire [WIDTH-1:0]   ddr, in_idle,in_tx, in_rx, in_fdx;   reg [WIDTH-1:0]    rgpio, igpio;       setting_reg #(.my_addr(BASE+0),.width(WIDTH)) reg_idle     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),      .out(in_idle),.changed());     setting_reg #(.my_addr(BASE+1), .width(WIDTH)) reg_rx     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),      .out(in_rx),.changed());     setting_reg #(.my_addr(BASE+2), .width(WIDTH)) reg_tx     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),      .out(in_tx),.changed());     setting_reg #(.my_addr(BASE+3), .width(WIDTH)) reg_fdx     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),      .out(in_fdx),.changed());     setting_reg #(.my_addr(BASE+4), .width(WIDTH)) reg_ddr     (.clk(clk),.rst(reset),.strobe(set_stb),.addr(set_addr), .in(set_data),      .out(ddr),.changed());     always @(posedge clk)     case({tx,rx})       2'b00: rgpio <= in_idle;       2'b01: rgpio <= in_rx;       2'b10: rgpio <= in_tx;       2'b11: rgpio <= in_fdx;     endcase // case ({tx,rx})      integer            n;   always @*     for(n=0;n  2        gpio_atr模块RTL视图
图1
  3        setting_reg模块源码 module setting_reg   #(parameter my_addr = 0,     parameter width = 32,     parameter at_reset=32'd0)     (input clk, input rst, inputstrobe, input wire [7:0] addr,      input wire [31:0] in, outputreg [width-1:0] out, output reg changed);       always @(posedge clk)      if(rst)        begin          out <= at_reset;          changed <= 1'b0;        end      else        if(strobe &(my_addr==addr))         begin            out <= in;            changed <= 1'b1;         end        else         changed <= 1'b0;    endmodule // setting_reg 4        setting_reg模块源码
图2
  二、   gpio_atr中次级模块例化分析
图3 图3中在gpio_atr中对setting_reg模块进行了5次例化调用。其逻辑视图见图1所示。 这5次例化分别实现了不同的功能。分别是reg_idle(空闲状态),reg_rx(接收状态), reg_tx(发送状态),reg_fdx(全双工状态),reg_ddr(引脚输入输出转换)
图 4 5个状态的例化代码如图4。其中重点要看.out变量的例化,有不同。该模块调用之后的输出分别输出到模块中不同的变量中。 在者,每次例化都对模块的my_addr地址进行了更改(my_addr中分别代表了该模块的地址,再下文中将具体说明),其地址分别为: reg_idle BASE+0 reg_rx BASE+1 reg_tx BASE+2 reg_fdx BASE+3 reg_ddr BASE+4 表 1(BASE=184,下文紧接着给出BASE值出处)
图 5 其中BASE在gpio_atr模块例化调用的程序中可以找到其具体值 可以看到例化该模块时将SR_GPIO给了BASE,及BASE=184,并且刚好留有5个地址位,对应着上述的5个工作状态。 三、   gpio_atr内实现功能分析 前文已经说明,该模块实现了对射频子板接口的输入、输出数据的控制,该部分将分析其中代码,分析其工作原理。 1        输入,输出数据选择
图 6 该部分代码如图6所示,其通过两个输入tx、rx实现了数据位的选择。从RTL视图中可以看出其中tx、rx分别来自相同模块vita_tx_chain、vita_rx_chain中的run引脚得到。如下图7位vita_tx_chain模块
图 7 2        执行in/out选择以及赋值
图 8 图8位该部分代码,其主要实现的功能室根据ddr变量的值不同对引脚进行幅值,其中gpio为32位的inout型。追溯到其例化程序(图5)可以看到其例化过程中,前16位是tx,后16位是rx。所以在这里猜测,ddr的数据为,前16位是’1’,后16位是’0’。即gpio的前16位(tx)根据rgpio的值进行输出赋值,而后16位(rx)保持高阻态作为输入引脚等待数据输入。 同时在RTL视图中,我们也可以看到,gpio最终分别连接在了FPGA硬件的io_tx和io_rx引脚上。
图 9 3        回读功能分析 该部分代码比较简单,每当时钟上升沿来临时,读取一次gpio的值,然后输出给settings_fifo_ctrl模块进行进一步的处理。
  四、   gpio_atr其他输入引脚说明 1       set_stb引脚 该引脚在setting_reg模块中例化,为状态控制引脚,只有在该引脚输入为1的时候,setting_reg中才会对输出变量赋值。 其状态settings_bus_crossclock模块控制。 2       set_addr[7:0]引脚 该引脚为地址输入引脚,该数据同样有settings_bus_crossclock中的set_addr_o引脚控制 3       set_addr[31:0]引脚 该引脚为地址输入引脚,该数据同样有settings_bus_crossclock中的set_data_o引脚控制