aurora协议中,默认是大端模式,但可在定制IP的时候选择小端支持,如下图所示:
小端模式
尽管如此,产生的示例逻辑,还是有部分地方使用了大端的表示方法:
例如顶层:
代码语言:javascript复制 // User I/O
input RESET;
input INIT_CLK_P;
input INIT_CLK_N;
input DRP_CLK_IN;
input GT_RESET_IN;
output HARD_ERR;
output SOFT_ERR;
output [0:7] ERR_COUNT;
output [0:1] LANE_UP;
output CHANNEL_UP;
// Clocks
input GTXQ0_P;
input GTXQ0_N;
// GT Serial I/O
input [0:1] RXP;
input [0:1] RXN;
output [0:1] TXP;
output [0:1] TXN;
//**************************External Register Declarations****************************
reg HARD_ERR;
reg SOFT_ERR;
reg [0:7] ERR_COUNT;
reg [0:1] LANE_UP;
reg CHANNEL_UP;
例如,用户接口逻辑:
代码语言:javascript复制 // User Interface
output [0:31] TX_D;
output TX_SRC_RDY_N;
input TX_DST_RDY_N;
那小端体现在哪里了呢?
可以在AXI接口中看到:
代码语言:javascript复制 // AXI4-Stream TX Interface
output [(DATA_WIDTH-1):0] AXI4_S_OP_TDATA;
output [(STRB_WIDTH-1):0] AXI4_S_OP_TKEEP;
output AXI4_S_OP_TVALID;
output AXI4_S_OP_TLAST;
input AXI4_S_IP_TREADY;
既然如此,我们就可以直接操作axi_stream接口,在axi_stream中,我们能用到的信号有:
代码语言:javascript复制 // AXI4-S output signals
.AXI4_S_OP_TVALID(tx_tvalid_i),
.AXI4_S_OP_TDATA(tx_data_i),
.AXI4_S_OP_TKEEP(),
.AXI4_S_OP_TLAST(),
.AXI4_S_IP_TREADY(tx_tready_i)
就是这里面有信号接出以及接入的部分,我们可以设计一个用户模块,使用这几个信号即可根据规则产生用户逻辑:
代码语言:javascript复制module user_logic_top(
//用户时钟以及复位
input wire sys_reset, //该reset用于用户逻辑复位等
input wire user_clk,
//axi 接口
output wire [31:0] s_axi_tx_tdata,
output reg s_axi_tx_tvalid,
input wire s_axi_tx_tready,
input wire [31:0] m_axi_rx_tdata,
input wire m_axi_rx_tvalid,
input wire channel_up
);
如果要发送数据,我们在s_axi_tx_tready有效且channel_up有效的情况下,直接产生tvalid以及tdata即可,简单到有手就行,例如:
代码语言:javascript复制 // 下面请使用小端模式生成用户逻辑
//复位处理
wire reset_c;
wire dly_data_xfer;
reg [4:0] channel_up_cnt;
always @ (posedge user_clk) begin
if(sys_reset)
channel_up_cnt <= 5'd0;
else if(channel_up)
if(&channel_up_cnt)
channel_up_cnt <= channel_up_cnt;
else
channel_up_cnt <= channel_up_cnt 1'b1;
else
channel_up_cnt <= 5'd0;
end
assign dly_data_xfer = (&channel_up_cnt);
//Generate RESET signal when Aurora channel is not ready
assign reset_c = sys_reset || !dly_data_xfer;
//先产生一个用于测试的计数逻辑
reg [15:0] test_cnt;
always@(posedge user_clk or posedge reset_c) begin
if(reset_c) begin
s_axi_tx_tvalid <= 1'b0;
test_cnt <= 16'd0;
end
else if(s_axi_tx_tready) begin
s_axi_tx_tvalid <= 1'b1;
test_cnt <= test_cnt 16'd1;
end
end
assign s_axi_tx_tdata = {2{test_cnt}};
产生一个计数的计数器,作为数据发送出去。