1、axi_hp0_wr.v 模块代码解析
该模块实现 AXI HP 总线写入数据到 DDR3 的操作。该模块的接口如下。rst_n 为系统复位信号;i_clk、i_data_rst_n、i_data_en 和 i_data 为 FPGA 逻辑需要写入到 DDR3 的数据输入接口。i_clk 为同步时钟信号,i_data_rst_n 用于复位 FIFO,i_data_en 拉高表示数据总线 i_data有效,将被写入到 FIFO 中缓存。余下的 AXI_*信号为 AXI HP 总线接口,读取 FIFO 中的数据,送往 DDR3 的指定地址空间。
module axi_hp0_wr#(
parameter STAR_ADDR = 32'h0100_0000)
(
//系统信号
input rst_n,
//写入DDR3的数据
input i_clk,
input i_data_rst_n,
input i_data_en,
input[15:0] i_data,
//AXI总线时钟
input AXI_clk,
//AXI写地址通道
output reg[31:0] AXI_awaddr,
output[3:0] AXI_awlen,
output[2:0] AXI_awsize,
output[1:0] AXI_awburst,
output[1:0] AXI_awlock,
output[3:0] AXI_awcache,
output[2:0] AXI_awprot,
output[3:0] AXI_awqos,
output reg AXI_awvalid,
input AXI_awready,
//AXI写数据通道
output[63:0] AXI_wdata,
output[7:0] AXI_wstrb,
output reg AXI_wlast,
output reg AXI_wvalid,
input AXI_wready,
//AXI写响应通道
input[5:0] AXI_bid,
input[1:0] AXI_bresp,
input AXI_bvalid,
output AXI_bready
);
以下代码定义内部信号。
//内部信号申明
wire[7:0] wrfifo_data_count; //FIFO可读数据数量
reg wrfifo_rden; //FIFO读数据使能信号
reg[7:0] wrdata_num; //写入DDR3数据计数器
reg[3:0] cstate,nstate; //状态寄存器
parameter AXI_BURST_LEN = 16;
parameter STATE_RST = 4'h0;
parameter STATE_IDLE = 4'h1;
parameter STATE_WADD = 4'h2;
parameter STATE_WDAT = 4'h3;
parameter WRITE_DONE = 4'h4;
FIFO
例化如下。写入位宽
16bit
,读出位宽
64bit
。该
FIFO
缓存
FPGA
逻辑送来的数据,
通过
AXI HP
总线,按照
burst
数量写入到
DDR3
中。
//缓存 FIFO,将数据从 i_clk 转到 AXI_clk 时钟域,位宽从 16bit 转到 64bit
fifo_generator_0 uut_fifo_generator_0 (
.rst(~i_data_rst_n), // input wire rst
.wr_clk(i_clk), // input wire wr_clk
.rd_clk(AXI_clk), // input wire rd_clk
.din(i_data), // input wire [15 : 0] din
.wr_en(i_data_en), // input wire wr_en
.rd_en(wrfifo_rden), // input wire rd_en
.dout(AXI_wdata), // output wire [63 : 0] dout
.full(), // output wire full
.empty(), // output wire empty
.rd_data_count(wrfifo_data_count) // output wire [7 : 0] rd_data_count
);
输入复位信号打一拍,从
i_clk
时钟域同步到
AXI_clk
时钟域。
//将i_data_rst_n在AXI_clk时钟域打一拍
reg w_data_rst_n;
always @(posedge AXI_clk)
w_data_rst_n <= i_data_rst_n;
以下状态机设计,根据复位信号的变化,从复位状态
STATE_RST
到空闲状态
STATE_IDLE
, 判断当 FIFO
中数据数量满足
1
次
burst
写入要求时,依次从空闲状态
STATE_IDLE -->
写地状态 STATE_WADD -->
写数据状态
STATE_WDAT -->
写入完成状态
STATE_DONE -->
空闲状态STATE_IDLE,如此往复。
//AXI写状态机
always @(posedge AXI_clk or negedge rst_n) begin
if(~rst_n)begin
cstate <= STATE_RST;
end
else begin
cstate <= nstate;
end
end
always @( * ) begin
case(cstate)
STATE_RST: begin
if(w_data_rst_n) nstate = STATE_IDLE;
else nstate = STATE_RST;
end
STATE_IDLE: begin
if(!w_data_rst_n) nstate = STATE_RST;
else if(wrfifo_data_count >= 8'd16) nstate = STATE_WADD;
else nstate = STATE_IDLE;
end
STATE_WADD: begin
if(AXI_awvalid && AXI_awready) nstate = STATE_WDAT;
else nstate = STATE_WADD;
end
STATE_WDAT: begin
if(wrdata_num >= (AXI_BURST_LEN+1)) nstate = WRITE_DONE;
else nstate = STATE_WDAT;
end
WRITE_DONE: begin
nstate = STATE_IDLE;
end
default: begin
nstate = STATE_RST;
end
endcase
end
以下逻辑在写数据状态
STATE_WDAT
下,对数据写入数量进行计数。
//1 个 burst 写入数据的个数计数
always @(posedge AXI_clk) begin
if (!rst_n) wrdata_num <= 'b0;
else if(cstate == STATE_WDAT) begin
if(wrdata_num == 8'd0) wrdata_num <= wrdata_num + 1'b1;
else if((wrdata_num <= AXI_BURST_LEN) && AXI_wready && AXI_wvalid)
wrdata_num <= wrdata_num + 1'b1;
else wrdata_num <= wrdata_num;
end
else wrdata_num <= 'b0;
end
以下逻辑控制产生
FIFO
读数据信号的产生,配合
AXI HP
总线写入数据的时序要求。
//FIFO 读取使能信号产生
always @(*) begin
if (cstate == STATE_WDAT) begin
if(wrdata_num == 8'd0) wrfifo_rden <= 1'b1;
else if((wrdata_num >= 8'd1) && (wrdata_num < AXI_BURST_LEN) && AXI_wready
&& AXI_wvalid) wrfifo_rden <= 1'b1;
else wrfifo_rden <= 1'b0;
end
else wrfifo_rden <= 1'b0;
end
以下逻辑产生
AXI HP
总线的写地址
AXI_awaddr
、写地址有效信号
AXI_awvalid
和最后一个写入数据指示信号 AXI_wlast
。
//AXI总线写数据时序产生
//写地址产生
always @(posedge AXI_clk)begin
if(cstate == STATE_RST) AXI_awaddr <= STAR_ADDR;
else if(AXI_awvalid && AXI_awready) AXI_awaddr <= AXI_awaddr + AXI_BURST_LEN * 8;
end
//写地址有效信号产生
always @(posedge AXI_clk) begin
if (!rst_n) AXI_awvalid <= 1'b0;
else if(cstate == STATE_WADD) begin
if(AXI_awvalid && AXI_awready) AXI_awvalid <= 1'b0;
else AXI_awvalid <= 1'b1;
end
else AXI_awvalid <= 1'b0;
end
//写数据有效信号产生
always @(posedge AXI_clk) begin
if (!rst_n) AXI_wvalid <= 1'b0;
else if((wrdata_num >= 8'd1) && (wrdata_num < AXI_BURST_LEN)) AXI_wvalid <= 1'b1;
else if((wrdata_num == AXI_BURST_LEN) && !AXI_wready) AXI_wvalid <= 1'b1;
else AXI_wvalid <= 1'b0;
end
//写最后一个数据有效信号产生
always @(posedge AXI_clk) begin
if (!rst_n) AXI_wlast <= 1'b0;
else if((wrdata_num == (AXI_BURST_LEN - 1)) && AXI_wready && AXI_wvalid) AXI_wlast <= 1'b1;
else if((wrdata_num == AXI_BURST_LEN) && !AXI_wready) AXI_wlast <= 1'b1;
else AXI_wlast <= 1'b0;
end
以下逻辑对
AXI HP
总线的一些信号赋常量值。
//-----------------------------------------------------------------------------
--
//AXI HP 总线固定赋值设置
assign AXI_awsize = 3'b011; //8 Bytes per burst
assign AXI_awburst = 2'b01;
assign AXI_awlock = 2'b00;
assign AXI_awcache = 4'b0010;
assign AXI_awprot = 3'h0;
assign AXI_awqos = 4'h0;
assign AXI_wstrb = 8'hff;
assign AXI_bready = 1'b1;
assign AXI_awlen = AXI_BURST_LEN - 1;
axi_hp0_wr.v
module axi_hp0_wr#(
parameter STAR_ADDR = 32'h0100_0000)
(
//系统信号
input rst_n,
//写入DDR3的数据
input i_clk,
input i_data_rst_n,
input i_data_en,
input[15:0] i_data,
//AXI总线时钟
input AXI_clk,
//AXI写地址通道
output reg[31:0] AXI_awaddr,
output[3:0] AXI_awlen,
output[2:0] AXI_awsize,
output[1:0] AXI_awburst,
output[1:0] AXI_awlock,
output[3:0] AXI_awcache,
output[2:0] AXI_awprot,
output[3:0] AXI_awqos,
output reg AXI_awvalid,
input AXI_awready,
//AXI写数据通道
output[63:0] AXI_wdata,
output[7:0] AXI_wstrb,
output reg AXI_wlast,
output reg AXI_wvalid,
input AXI_wready,
//AXI写响应通道
input[5:0] AXI_bid,
input[1:0] AXI_bresp,
input AXI_bvalid,
output AXI_bready
);
//------------------------------------------------------------------------------------
//内部信号申明
wire[7:0] wrfifo_data_count; //FIFO可读数据数量
reg wrfifo_rden; //FIFO读数据使能信号
reg[7:0] wrdata_num; //写入DDR3数据计数器
reg[3:0] cstate,nstate; //状态寄存器
parameter AXI_BURST_LEN = 16;
parameter STATE_RST = 4'h0;
parameter STATE_IDLE = 4'h1;
parameter STATE_WADD = 4'h2;
parameter STATE_WDAT = 4'h3;
parameter WRITE_DONE = 4'h4;
//-------------------------------------------------------------------------------
//缓存FIFO,将数据从i_clk转到AXI_clk时钟域,位宽从16bit转到64bit
fifo_generator_0 uut_fifo_generator_0 (
.rst(~i_data_rst_n), // input wire rst
.wr_clk(i_clk), // input wire wr_clk
.rd_clk(AXI_clk), // input wire rd_clk
.din(i_data), // input wire [15 : 0] din
.wr_en(i_data_en), // input wire wr_en
.rd_en(wrfifo_rden), // input wire rd_en
.dout(AXI_wdata), // output wire [63 : 0] dout
.full(), // output wire full
.empty(), // output wire empty
.rd_data_count(wrfifo_data_count) // output wire [7 : 0] rd_data_count
);
//------------------------------------------------------------------------------------
//将i_data_rst_n在AXI_clk时钟域打一拍
reg w_data_rst_n;
always @(posedge AXI_clk)
w_data_rst_n <= i_data_rst_n;
//-------------------------------------------------------------------------------
//AXI写状态机
always @(posedge AXI_clk or negedge rst_n) begin
if(~rst_n)begin
cstate <= STATE_RST;
end
else begin
cstate <= nstate;
end
end
always @( * ) begin
case(cstate)
STATE_RST: begin
if(w_data_rst_n) nstate = STATE_IDLE;
else nstate = STATE_RST;
end
STATE_IDLE: begin
if(!w_data_rst_n) nstate = STATE_RST;
else if(wrfifo_data_count >= 8'd16) nstate = STATE_WADD;
else nstate = STATE_IDLE;
end
STATE_WADD: begin
if(AXI_awvalid && AXI_awready) nstate = STATE_WDAT;
else nstate = STATE_WADD;
end
STATE_WDAT: begin
if(wrdata_num >= (AXI_BURST_LEN+1)) nstate = WRITE_DONE;
else nstate = STATE_WDAT;
end
WRITE_DONE: begin
nstate = STATE_IDLE;
end
default: begin
nstate = STATE_RST;
end
endcase
end
//1个burst写入数据的个数计数
always @(posedge AXI_clk) begin
if (!rst_n) wrdata_num <= 'b0;
else if(cstate == STATE_WDAT) begin
if(wrdata_num == 8'd0) wrdata_num <= wrdata_num + 1'b1;
else if((wrdata_num <= AXI_BURST_LEN) && AXI_wready && AXI_wvalid) wrdata_num <= wrdata_num + 1'b1;
else wrdata_num <= wrdata_num;
end
else wrdata_num <= 'b0;
end
//-------------------------------------------------------------------------------
//FIFO读取使能信号产生
always @(*) begin
if (cstate == STATE_WDAT) begin
if(wrdata_num == 8'd0) wrfifo_rden <= 1'b1;
else if((wrdata_num >= 8'd1) && (wrdata_num < AXI_BURST_LEN) && AXI_wready && AXI_wvalid) wrfifo_rden <= 1'b1;
else wrfifo_rden <= 1'b0;
end
else wrfifo_rden <= 1'b0;
end
//-------------------------------------------------------------------------------
//AXI总线写数据时序产生
//写地址产生
always @(posedge AXI_clk)begin
if(cstate == STATE_RST) AXI_awaddr <= STAR_ADDR;
else if(AXI_awvalid && AXI_awready) AXI_awaddr <= AXI_awaddr + AXI_BURST_LEN * 8;
end
//写地址有效信号产生
always @(posedge AXI_clk) begin
if (!rst_n) AXI_awvalid <= 1'b0;
else if(cstate == STATE_WADD) begin
if(AXI_awvalid && AXI_awready) AXI_awvalid <= 1'b0;
else AXI_awvalid <= 1'b1;
end
else AXI_awvalid <= 1'b0;
end
//写数据有效信号产生
always @(posedge AXI_clk) begin
if (!rst_n) AXI_wvalid <= 1'b0;
else if((wrdata_num >= 8'd1) && (wrdata_num < AXI_BURST_LEN)) AXI_wvalid <= 1'b1;
else if((wrdata_num == AXI_BURST_LEN) && !AXI_wready) AXI_wvalid <= 1'b1;
else AXI_wvalid <= 1'b0;
end
//写最后一个数据有效信号产生
always @(posedge AXI_clk) begin
if (!rst_n) AXI_wlast <= 1'b0;
else if((wrdata_num == (AXI_BURST_LEN - 1)) && AXI_wready && AXI_wvalid) AXI_wlast <= 1'b1;
else if((wrdata_num == AXI_BURST_LEN) && !AXI_wready) AXI_wlast <= 1'b1;
else AXI_wlast <= 1'b0;
end
//-------------------------------------------------------------------------------
//AXI HP总线固定赋值设置
assign AXI_awsize = 3'b011; //8 Bytes per burst
assign AXI_awburst = 2'b01;
assign AXI_awlock = 2'b00;
assign AXI_awcache = 4'b0010;
assign AXI_awprot = 3'h0;
assign AXI_awqos = 4'h0;
assign AXI_wstrb = 8'hff;
assign AXI_bready = 1'b1;
assign AXI_awlen = AXI_BURST_LEN - 1;
endmodule
2、axi_hp0_rd.v 模块代码解析
该模块实现 AXI HP 总线从 DDR3 读数据的操作。该模块的接口如下。rst_n 为系统复位信号;i_clk、i_data_rst_n、i_data_rden 和 o_data 为 FPGA 逻辑从该模块读取 DDR3 的控制和数据接口。i_clk 为同步时钟信号,i_data_rst_n 用于复位 FIFO,i_data_rden 拉高表示读取 FIFO 中的数据,随后 i_data 上将输出 FIFO 中缓存的数据。余下的 AXI_*信号为 AXI HP 总线接口,写入数据到 FIFO 中供读取。module axi_hp0_rd(
//系统信号
input rst_n,
//写入DDR3的数据
input i_clk,
input i_data_rst_n,
input i_data_rden,
output[15:0] o_data,
//AXI总线时钟
input AXI_clk,
//AXI读地址通道
output reg[31:0] AXI_araddr,
output[1:0] AXI_arburst,
output[3:0] AXI_arcache,
output[3:0] AXI_arlen,
output[1:0] AXI_arlock,
output[2:0] AXI_arprot,
output[3:0] AXI_arqos,
input AXI_arready,
output[2:0] AXI_arsize,
output reg AXI_arvalid,
//AXI读数据通道
input[63:0] AXI_rdata,
input[5:0] AXI_rid,
input AXI_rlast,
output AXI_rready,
input[1:0] AXI_rresp,
input AXI_rvalid
);
内部信号、参数的申明如下。
//参数、信号申明
parameter STAR_ADDR = 32'h0100_0000;
parameter AXI_BURST_LEN = 16;
parameter STATE_RST = 4'h0;
parameter STATE_IDLE = 4'h1;
parameter STATE_RADD = 4'h2;
parameter READ_DONE = 4'h3;
reg[3:0] cstate,nstate;
wire[7:0] fifo_wrdata_count;
将 i_data_rst_n 在 AXI_clk 时钟域打 2 拍
//将 i_data_rst_n 在 AXI_clk 时钟域打 2 拍
wire w_data_rst_n,pos_data_rst_n,neg_data_rst_n;
pulse_detection uut_pulse_detection_odrn(
.clk(AXI_clk),
.in_sig(i_data_rst_n), //输入信号
.out_sig(w_data_rst_n), //将输入信号同步到本地时钟域后的输出
.pos_sig(pos_data_rst_n),//输入信号的上升沿检测,高脉冲保持一个时钟周期
.neg_sig(neg_data_rst_n)//输入信号的下降沿检测,高脉冲保持一个时钟周期
);
以下状态机实现
AXI HP
总线读取
DDR3
数据的控制。上电初始为复位状态
STATE_RST
,复位结束后(wr_data_rst=1
),进入空闲状态
STATE_IDLE
,若
FIFO
中数据数量少于
128
个
(
fifo_wrdata_counter<128
),则进入写地址状态
STATE_RADD
,该状态产生
AXI HP
总线写入
DDR3
要读取数据所在的地址,写入成功后(
AXI_arready=1
),进入读数据状
STATE_DONE
,
该状态下所有读取到的数据送入
FIFO
中,最后一个数据输出完成(
AXI_rlast=1
),回到空闲
状态,如此反复。
//AXI读状态机
always @(posedge AXI_clk or negedge rst_n)begin
if(~rst_n)begin
cstate <= STATE_RST;
end
else begin
cstate <= nstate;
end
end
always @( * )begin
case(cstate)
STATE_RST: begin
if(w_data_rst_n) nstate = STATE_IDLE;
else nstate = STATE_RST;
end
STATE_IDLE: begin
if(!w_data_rst_n) nstate = STATE_RST;
else if(fifo_wrdata_count < 8'd128) nstate = STATE_RADD;
else nstate = STATE_IDLE;
end
STATE_RADD: begin
if(AXI_arready) nstate = READ_DONE;
else nstate = STATE_RADD;
end
READ_DONE: begin
if(AXI_rlast) nstate = STATE_IDLE;
else nstate = READ_DONE;
end
default: begin
nstate = STATE_RST;
end
endcase
end
以下逻辑产生读数据的地址
AXI_araddr
和地址有效信号
AXI_arvalid
。
//AXI HP读时序产生
//读地址有效信号产生
always @(posedge AXI_clk)begin
if(nstate == STATE_RADD) AXI_arvalid <= 1'b1;
else AXI_arvalid <= 1'b0;
end
//读地址产生
always @(posedge AXI_clk)begin
if(cstate == STATE_RST) AXI_araddr <= STAR_ADDR;
else if(AXI_arvalid && AXI_arready) AXI_araddr <= AXI_araddr + AXI_BURST_LEN * 8;
end
FIFO
例化如下。
//DDR3读出数据缓存到FIFO,LCD显示模块读取FIFO数据,位宽从64bit转16bit
fifo_generator_2 uut_fifo_generator_2 (
.rst(~i_data_rst_n), // input wire rst
.wr_clk(AXI_clk), // input wire wr_clk
.rd_clk(i_clk), // input wire rd_clk
.din(AXI_rdata), // input wire [63 : 0] din
.wr_en(AXI_rvalid), // input wire wr_en
.rd_en(i_data_rden), // input wire rd_en
.dout(o_data), // output wire [15 : 0] dout
.full(full), // output wire full
.empty(empty), // output wire empty
.wr_data_count(fifo_wrdata_count) // output wire [7 : 0] wr_data_count
);
以下逻辑对
AXI HP
总线的一些信号赋常量值。
//AXI HP总线固定配置
assign AXI_arsize = 3'b011; //8 Bytes per burst
assign AXI_arburst = 2'b01;
assign AXI_arlock = 2'b00;
assign AXI_arcache = 4'b0010;
assign AXI_arprot = 3'h0;
assign AXI_arqos = 4'h0;
assign AXI_rready = 1'b1;
assign AXI_arlen = AXI_BURST_LEN - 1;
axi_hp0_rd.v
module axi_hp0_rd(
//系统信号
input rst_n,
//写入DDR3的数据
input i_clk,
input i_data_rst_n,
input i_data_rden,
output[15:0] o_data,
//AXI总线时钟
input AXI_clk,
//AXI读地址通道
output reg[31:0] AXI_araddr,
output[1:0] AXI_arburst,
output[3:0] AXI_arcache,
output[3:0] AXI_arlen,
output[1:0] AXI_arlock,
output[2:0] AXI_arprot,
output[3:0] AXI_arqos,
input AXI_arready,
output[2:0] AXI_arsize,
output reg AXI_arvalid,
//AXI读数据通道
input[63:0] AXI_rdata,
input[5:0] AXI_rid,
input AXI_rlast,
output AXI_rready,
input[1:0] AXI_rresp,
input AXI_rvalid
);
//------------------------------------------------------------------------------------
//参数、信号申明
parameter STAR_ADDR = 32'h0100_0000;
parameter AXI_BURST_LEN = 16;
parameter STATE_RST = 4'h0;
parameter STATE_IDLE = 4'h1;
parameter STATE_RADD = 4'h2;
parameter READ_DONE = 4'h3;
reg[3:0] cstate,nstate;
wire[7:0] fifo_wrdata_count;
//------------------------------------------------------------------------------------
//将i_data_rst_n在AXI_clk时钟域打2拍
wire w_data_rst_n,pos_data_rst_n,neg_data_rst_n;
pulse_detection uut_pulse_detection_odrn(
.clk(AXI_clk),
.in_sig(i_data_rst_n), //输入信号
.out_sig(w_data_rst_n), //将输入信号同步到本地时钟域后的输出
.pos_sig(pos_data_rst_n), //输入信号的上升沿检测,高脉冲保持一个时钟周期
.neg_sig(neg_data_rst_n) //输入信号的下降沿检测,高脉冲保持一个时钟周期
);
//-------------------------------------------------------------------------------
//AXI读状态机
always @(posedge AXI_clk or negedge rst_n)begin
if(~rst_n)begin
cstate <= STATE_RST;
end
else begin
cstate <= nstate;
end
end
always @( * )begin
case(cstate)
STATE_RST: begin
if(w_data_rst_n) nstate = STATE_IDLE;
else nstate = STATE_RST;
end
STATE_IDLE: begin
if(!w_data_rst_n) nstate = STATE_RST;
else if(fifo_wrdata_count < 8'd128) nstate = STATE_RADD;
else nstate = STATE_IDLE;
end
STATE_RADD: begin
if(AXI_arready) nstate = READ_DONE;
else nstate = STATE_RADD;
end
READ_DONE: begin
if(AXI_rlast) nstate = STATE_IDLE;
else nstate = READ_DONE;
end
default: begin
nstate = STATE_RST;
end
endcase
end
//------------------------------------------------------------------------------------
//AXI HP读时序产生
//读地址有效信号产生
always @(posedge AXI_clk)begin
if(nstate == STATE_RADD) AXI_arvalid <= 1'b1;
else AXI_arvalid <= 1'b0;
end
//读地址产生
always @(posedge AXI_clk)begin
if(cstate == STATE_RST) AXI_araddr <= STAR_ADDR;
else if(AXI_arvalid && AXI_arready) AXI_araddr <= AXI_araddr + AXI_BURST_LEN * 8;
end
//------------------------------------------------------------------------------------
//DDR3读出数据缓存到FIFO,LCD显示模块读取FIFO数据,位宽从64bit转16bit
fifo_generator_2 uut_fifo_generator_2 (
.rst(~i_data_rst_n), // input wire rst
.wr_clk(AXI_clk), // input wire wr_clk
.rd_clk(i_clk), // input wire rd_clk
.din(AXI_rdata), // input wire [63 : 0] din
.wr_en(AXI_rvalid), // input wire wr_en
.rd_en(i_data_rden), // input wire rd_en
.dout(o_data), // output wire [15 : 0] dout
.full(full), // output wire full
.empty(empty), // output wire empty
.wr_data_count(fifo_wrdata_count) // output wire [7 : 0] wr_data_count
);
//------------------------------------------------------------------------------------
//AXI HP总线固定配置
assign AXI_arsize = 3'b011; //8 Bytes per burst
assign AXI_arburst = 2'b01;
assign AXI_arlock = 2'b00;
assign AXI_arcache = 4'b0010;
assign AXI_arprot = 3'h0;
assign AXI_arqos = 4'h0;
assign AXI_rready = 1'b1;
assign AXI_arlen = AXI_BURST_LEN - 1;
endmodule
pulse_detection.v
//对输入信号打2拍,做边沿检测
module pulse_detection(
input clk,
input in_sig, //输入信号
output out_sig, //将输入信号同步到本地时钟域后的输出
output pos_sig, //输入信号的上升沿检测,高脉冲保持一个时钟周期
output neg_sig //输入信号的下降沿检测,高脉冲保持一个时钟周期
);
reg[1:0] in_sig_r;
always @(posedge clk)
in_sig_r <= {in_sig_r[0],in_sig};
assign pos_sig = ~in_sig_r[1] & in_sig_r[0];
assign neg_sig = in_sig_r[1] & ~in_sig_r[0];
assign out_sig = in_sig_r[1];
endmodule