读时序图(手册)
数据迟于命令若干周期出来,手册读时序:From ug586 page of 167。
读模块
读时有读命令fifo和读数据fifo,类似于写,但是读比写简单很多。
模块时序信息
1.模块的时钟时MIG输出ui_clk;
2.当外给一个周期的a7_rd_start信号后模块开始工作;
3.app_en在app_rdy && data_cnt == rd_bl - 1’b1 时拉低,指示读模块共工作使能;
//*************************************************************************//
//读模块的总体思路是先从命令fifo里面读指令,然后根据指令对数据fifo进行操作
//后续会有仲裁器判断读写模块哪个先执行
//*************************************************************************//
module a7_rd_ctrl #(
parameter BL_WIDTH = 7,
parameter ADDR_WIDRH = 28,
parameter DATA_WIDTH = 128,
)
(
input wire sclk , //模块工作时钟,连接到ui_clk即可
input wire sys_rst ,
input wire a7_rd_start ,
input wire [2:0] a7_rd_cmd , //直传给MIG的读写指令
input wire [BL_WIDTH-1:0] a7_rd_bl , //命令fifo读出的突发长度
input wire [ADDR_WIDRH-1:0] a7_rd_init_addr ,
//
input wire app_rdy ,//指示向UI提供的数据是是否能被接收
input wire app_rd_data_valid ,
input wire [DATA_WIDTH-1:0] app_rd_data ,
//OUTPUT
output wire app_en ,
output reg app_cmd ,
output reg [ADDR_WIDRH-1:0] app_addr ,
output wire [DATA_WIDTH-1:0] a7_rd_data , //输出给数据fifo的数据
output wire a7_rd_data_valid ,
output reg rd_end //所有数据传输完成指示
);
//-----------------中间变量定义------------------------------------------//
reg [BL_WIDTH-1:0] data_cnt;//输入数据个数计数器
reg [6:0] cmd_cnt ;//命令计数器
reg [BL_WIDTH-1:0] rd_bl ;
//app_en,app_cmd,
always @(posedge sclk)
begin
if (sys_rst)
begin
rd_bl <= {BL_WIDTH{1'b0}} ;
app_addr <= {ADDR_WIDRH{1'b0}};
a7_rd_cmd <= 3'b000 ;
app_en <= 1'b0 ;
end
else if (a7_rd_start)
begin
app_addr <= a7_rd_init_addr ;
rd_bl <= a7_rd_bl ;
app_cmd <= a7_rd_cmd ;
app_en <= 1'b1 ;
end if (app_rdy && cmd_cnt == rd_bl - 1'b1)
begin
app_addr <= app_addr + 4'd8 ;
app_en <= 1'b0 ;
end
end
//app_addr
always @(posedge sclk)
begin
if (sys_rst)
begin
app_addr <= {ADDR_WIDRH{1'b0}};
end
else if (a7_rd_start)
begin
app_addr <= a7_rd_init_addr ;
end
end if (app_rdy && cmd_cnt == rd_bl - 1'b1)
begin
app_addr <= {ADDR_WIDRH{1'b0}};
end
else if (app_en && app_rdy)
begin
app_addr <= app_addr + 4'd8 ;
end
end
//a7_rd_data,a7_rd_data_valid
assign a7_rd_data = app_rd_data_valid ? app_rd_data : 128'd0;
assign a7_rd_data_valid = app_rd_data_valid ;
//data_cnt
always @(posedge sclk)
begin
if (sys_rst)
begin
data_cnt <= {BL_WIDTH{1'b0}} ;
end
else if (rd_data_valid && data_cnt == rd_bl - 1'b1)
begin
data_cnt <= {BL_WIDTH{1'b0}} ;
end
else if (rd_data_valid)
begin
data_cnt <= data_cnt + 1'b1 ;
end
end
//cmd_cnt
always @(posedge sclk)
begin
if (sys_rst)
begin
cmd_cnt <= {BL_WIDTH{1'b0}} ;
end
else if (app_en && app_rdy && cmd_cnt == rd_bl - 1'b1) //??此处和教程不一样
begin
cmd_cnt <= {BL_WIDTH{1'b0}} ;
end
else if (app_en && app_rdy)
begin
cmd_cnt <= cmd_cnt + 1'b1 ;
end
end
//rd_end
always @(posedge sclk)
begin
if (sys_rst)
begin
rd_end <= 1'b0 ;
end
else if (app_en && app_rdy && data_cnt == rd_bl - 1'b1) //??此处和教程不一样,实际到底传了多少个数据
begin
rd_end <= 1'b1 ;
end
else
begin
rd_end <= 1'b0 ;
end
end
endmodule