本文有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引脚控制