Basically I want to provide delay of 15 clock cycles for writing and reading through axi4 bus .Is it possible?
Hello,
I am sorry very much for many time revising.I have revised 2 parts of my codes.One is for the write and another is for the read.
(1) Write
always@(posedge CLK) begin if(~ARESETN) FIRST_WDATA_MASK <= 1; else if(WADDR_DONE & (wcounter==4'hf)) FIRST_WDATA_MASK <= 0; else if((wcounter==4'h0) & WREADY) FIRST_WDATA_MASK <= 1; end
(2) Read
always@(posedge CLK) begin if(~ARESETN) next_rlast <= 0; else if (rcounter == 4'h1) next_rlast <= 1; else if ((rcounter == 4'h0) & masked_RREADY) next_rlast <= 0; end
Best regards,Yasuhiko Koumoto.
Sir
I will do it today and let you know. Can we talk on hangout?It will be a lot easier.
Let me explain you the code behaviour I am following:
My memory controller block is using the axi bridges to communicate with the MCB
CPU-AXI bridges(here are my channels)-MCB
Now I am not using any simulator. Rather I am using the xilinx SDK and EDK(EMBEDDED development kit). I change the hardware in EDK and then run the memory writing code in SDK and check if the data I write is being written to memory with delay or not. Note I havenot generated testbench for the my write channel or read channel as there are a lot of signals involved.
Following is my write channel code :
//
// File name: axi_mcb_w_channel.v
// Description:
///////////////////////////////////////////////////////////////////////////////
`timescale 1ps/1ps
`default_nettype none
module axi_mcb_w_channel #
(
// Parameter Definitions
// Width of AXI xDATA and MCB xx_data
// Range: 32, 64, 128.
parameter integer C_DATA_WIDTH = 32,
// Width of beat counter, limits max transaction size.
// Range: 1-6 (-> 2-64 beat transactions)
parameter integer C_CNT_WIDTH = 4,
// Pipelines the wr_full signal from mcb by using
// wr_count. Does not add write latency.
parameter integer C_PL_WR_FULL = 1,
// Pipelines the wvalid and wready handshake used for
// counting. May add one cycle of latency.
parameter integer C_PL_WHANDSHAKE = 1,
// Pipelines the intermodule signal w_complete. May add
// 1 cycle of latency.
parameter integer C_PL_W_COMPLETE = 1
)
// Port Declarations
input wire clk ,
input wire reset ,
input wire [C_DATA_WIDTH-1:0] wdata,
input wire [C_DATA_WIDTH/8-1:0] wstrb,
input wire wlast,
input wire wvalid,
output wire wready,
output wire wr_en,
output wire [C_DATA_WIDTH/8-1:0] wr_mask,
output wire [C_DATA_WIDTH-1:0] wr_data,
input wire wr_full,
input wire wr_empty,
input wire [6:0] wr_count,
input wire wr_underrun,
input wire wr_error,
input wire calib_done,
output wire w_complete,
input wire w_trans_cnt_full
);
////////////////////////////////////////////////////////////////////////////////
// Local parameters
localparam integer P_MCB_FULL_CNT = 64;
// Wire and register declarations
wire whandshake;
reg [C_CNT_WIDTH-1:0] cnt;
reg subburst_last;
wire w_complete_ns;
wire w_complete_i;
wire wready_i;
wire wlast_i;
wire whandshake_i;
// BEGIN RTL
assign wready = wready_i;
assign wr_en = whandshake;
assign wr_mask = ~wstrb;
assign wr_data = wdata;
assign whandshake = wvalid & wready;
generate
if (C_PL_WR_FULL) begin : PL_WR_FULL
reg [6:0] wr_count_d1;
wire wr_afull_ns;
reg wready_r;
// Calculate almost full from wr_count instead of using wr_full for timing
// closure
always @(posedge clk) begin
wr_count_d1 <= wr_count;
end
assign wr_afull_ns = (wr_count_d1 > (P_MCB_FULL_CNT-3));
if (reset) begin
wready_r <= 1'b0;
end else begin
wready_r <= ~wr_afull_ns & calib_done & ~w_trans_cnt_full;
assign wready_i = wready_r;
else
begin : NO_PL_WR_FULL
assign wready_i = ~wr_full & calib_done & ~w_trans_cnt_full;
endgenerate
if (C_PL_WHANDSHAKE) begin : PL_WHANDSHAKE
reg wlast_d1;
reg whandshake_d1;
// Count the number of beats we have
// Use delayed values of the incoming signals for better timing
wlast_d1 <= wlast;
whandshake_d1 <= whandshake;
assign wlast_i = wlast_d1;
assign whandshake_i = whandshake_d1;
else begin : NO_PL_WHANDSHAKE
assign wlast_i = wlast;
assign whandshake_i = whandshake;
if (w_complete_ns | reset) begin
cnt <= {C_CNT_WIDTH{1'b1}};
end else if (whandshake_i) begin
cnt <= cnt - 1'b1;
// Determines have reached a subburst boundary
if (reset | w_complete_ns) begin
subburst_last <= 1'b0;
end else if ((cnt == {{C_CNT_WIDTH-1{1'b0}},1'b1}) & whandshake_i) begin
subburst_last <= 1'b1;
assign w_complete_ns = whandshake_i & (wlast_i | subburst_last);
if (C_PL_W_COMPLETE) begin : PL_W_COMPLETE
reg w_complete_r;
// latch the output of w_complete
w_complete_r <= w_complete_ns;
assign w_complete_i = w_complete_r;
else begin : NO_PL_W_COMPLETE
assign w_complete_i = w_complete_ns;
assign w_complete = w_complete_i;
endmodule
`default_nettype wire
Regards
Preet Kaur Walia
I want not to talk on hangout, because I will not support until you will succeed.I can only give you hints.I did my best by proposing an example which can work well in a certain environmentNow, I would like to finish the conversation.
By the way, if you have the AXI bridge, how about adding the following logics into the bridge?As the wready can be generated independently with wvalid, any latches will not be needed.
assign wtimer_trigger = wvalid & wready_i;assign wready = (wtimer == 5'h1) & wready_i;
always @(posedge clk) beginif(reset) wtimer <= 5'h0;else if(wtime != 5'h1) wtimer <= wrimer - 1;else if(wtimer_trigger & (wtimer == 5'h0)) wtimer <= 5'h10;else if(wready) wtimer <= 5'h0;end
Best regards,
Yasuhiko Koumoto.
Thank you so much for all the suggestions you have provided me.. You have really brought me this far. I have tried the write (with latches ) it does not seem to work. Some last doubts to end the conversation. Please let me if your write channel is similar to mine and the test bench you have used to test it. I have tried the bridge suggestion as well. But that does not delay my data.
I cannot judge whether your axi_mcb_w_channel logic would be correct or not.It seems to have a lot of strange parts for me.Honestry speaking, I wonder why my proposal for the bridge did not work.
I have tried the bridge suggestion as well. But that does not delay my data.
Is your data modification done between the bridge and the slave?My assumption is that it would be done between CPU and the bridge.
Yes sir I have made the modifications between bridge and the slave as I do not have access to the CPU part of the code. You can have a look at the attachment(axi_mcb_w_channel.v) to see where I have made the changes. Also I have attached axi bridge(axi_mcb.v). Sir, can you please tell me which particular simulator have you used.
I am working on the latch code sent by you.
I am afraid that you would insert the delay logic into the axi_mcb_{aw,w,b}_channel_0. It would be to very complex and difficult.
I recommend to put my logic on between the register slice and the axi_mcb_{aw,w,b}_channel_0.
I was trying this approach but the code you sent, in that only wvalid was masked. And in the diagram you have sent wready,wvalid and awraedy all are masked. So I am confused what all I need to mask.
my block diagram has the assumption that the axi_mcb_{aw,w,b}_channel_0 are original (i.e. no modification).
Please remove the wready generation logic from the axi_mcb_w_channel_0.
let me give an additional comments.
To insert 15 cycle delay would be the easiest to do in the slave.
In a slave, we can easily control READY signal.
However, to do it outside of a slave would be a little difficult.
I had been looking at the outside solution.
Because the axi_mcb_{aw,w,b}_channel_0 would be a slave, I think that it would be enough to control only the wwreay signal.
However, you did the other signal (e.g. the awreay, etc.) controlling in the slave. It is not my intention.
Therefore, I proposed the bridge solution which the control would be put between master (or the register slice) and the slave under the condition which any modification would be added to he axi_mcb_{aw,w,b}_channel_0.
Yes I did that.
Hi
I have made a bridge between the register slice and write channel and added the delay code in that. That is I am delaying the wready signal in that. My doubt was that will delaying workif we only delay the wready signal. Others would not be required.
Preet
don't you want to delay only the wdata for a slave, do you?
Do you want to add delay for the other signals?
Could you tell me the reason why the delaying won't work if we only delay the wready signal?
My write delay is working fine if I delay wready in my write channel. I have a doubt. If I am doing continous write and then I read continously, it is working fine(my each data word is getting delayed) but not in the case when I perform single read and single write. Is it that if I am not performing bursts(I do a single write and I read single data) the flow of data between different modules in AXI different to that to a single read and single write.
Regard
I think your code might support only the 4 burst case from the description below.
always @(posedge clk) begin if (w_complete_ns | reset) begin cnt <= {C_CNT_WIDTH{1'b1}}; end else if (whandshake_i) begin cnt <= cnt - 1'b1; end end always @(posedge clk) begin if (reset | w_complete_ns) begin subburst_last <= 1'b0; end else if ((cnt == {{C_CNT_WIDTH-1{1'b0}},1'b1}) & whandshake_i) begin subburst_last <= 1'b1; end end