/********************************************** _ _ Cook Darwin __
_ descript: author : Cook.Darwin Version: VERA.0.0 creaded: 2017/2/23 madified: ***********************************************/ `timescale 1ns/1ps module axi4_partition_rd #(
parameter PSIZE = 128, parameter real ADDR_STEP = 1
)(
axi_inf.slaver_rd axi_in, axi_inf.master_rd axi_out
);
logic clock,rst_n;
assign clock = axi_in.axi_aclk; assign rst_n = axi_in.axi_aresetn;
typedef enum {IDLE,GET_IP_A,P_A,P_R,O_A,O_R,UP_LAST,L_A,L_R} STATUS;
STATUS nstate,cstate;
always@(posedge clock,negedge rst_n)begin
if(~rst_n) cstate <= IDLE; else cstate <= nstate;
end
logic len_overflow; logic partition_completel;
always_comb begin
case(cstate) IDLE: if(axi_in.axi_arvalid && axi_in.axi_arready) nstate = GET_IP_A; else nstate = IDLE; GET_IP_A: if(len_overflow) nstate = P_A; else nstate = O_A; P_A: if(axi_out.axi_arvalid && axi_out.axi_arready) nstate = P_R; else nstate = P_A; P_R: if(axi_out.axi_rvalid && axi_out.axi_rready && axi_out.axi_rlast)begin if(partition_completel) nstate = L_A; else nstate = P_A; end else nstate = P_R; L_A: if(axi_out.axi_arvalid && axi_out.axi_arready) nstate = L_R; else nstate = L_A; L_R: if(axi_out.axi_rvalid && axi_out.axi_rready && axi_out.axi_rlast) nstate = UP_LAST; else nstate = L_R; O_A: if(axi_out.axi_arvalid && axi_out.axi_arready) nstate = O_R; else nstate = O_A; O_R: if(axi_out.axi_rvalid && axi_out.axi_rready && axi_out.axi_rlast) nstate = UP_LAST; else nstate = O_R; UP_LAST: nstate = IDLE; default: nstate = IDLE; endcase
end //—>> UP STREAM <<————————— always@(posedge clock,negedge rst_n)
if(~rst_n) axi_in.axi_arready <= 1'b0; else case(nstate) IDLE: axi_in.axi_arready <= 1'b1; default:axi_in.axi_arready <= 1'b0; endcase
//—<< UP STREAM >>————————— //—->> DOWN STREAM <<———————— always@(posedge clock,negedge rst_n)
if(~rst_n) axi_out.axi_arvalid <= 1'b0; else case(nstate) P_A,O_A,L_A: axi_out.axi_arvalid <= 1'b1; default:axi_out.axi_arvalid <= 1'b0; endcase
//—-<< DOWN STREAM >>———————— //—->> LENDTH CTRL <<———————— logic [31:0] length; logic [axi_out.ASIZE-1:0] arlen;
always@(posedge clock,negedge rst_n)
if(~rst_n) len_overflow <= 1'b0; else begin if(axi_in.axi_arvalid && axi_in.axi_arready ) len_overflow <= axi_in.axi_arlen + 1 > PSIZE; else if(axi_in.axi_rready && axi_in.axi_rvalid && axi_in.axi_rlast) len_overflow <= 1'b0; else len_overflow <= len_overflow; end
always@(posedge clock,negedge rst_n)
if(~rst_n) length <= '0; else begin if(axi_in.axi_arvalid && axi_in.axi_arready ) length <= axi_in.axi_arlen + 1 ; else if(axi_out.axi_arvalid && axi_out.axi_arready) length <= length - PSIZE; else length <= length; end
always@(posedge clock,negedge rst_n)
if(~rst_n) partition_completel <= 1'b0; else begin partition_completel <= (length <= PSIZE); end
always@(posedge clock,negedge rst_n)
if(~rst_n) arlen <= '0; else begin // if(axi_in.axi_arvalid && axi_in.axi_arready)begin // if(axi_in.axi_arlen + 1 > PSIZE) // arlen <= PSIZE-1; // else arlen <= axi_in.axi_arlen; // end else if(axi_out.axi_arvalid && axi_out.axi_arready)begin if(length>=PSIZE) arlen <= PSIZE-1; else arlen <= length-1; // end else arlen <= arlen; end
assign axi_out.axi_arlen = arlen; //—-<< LENDTH CTRL >>———————— //—->> ADDR CTRL <<———————— logic araddr;
always@(posedge clock,negedge rst_n)
if(~rst_n) araddr <= '0; else begin if(axi_in.axi_arvalid && axi_in.axi_arready) araddr <= axi_in.axi_araddr; else if(axi_out.axi_arvalid && axi_out.axi_arready) araddr <= araddr + int'(PSIZE*ADDR_STEP); else araddr <= araddr; end
assign axi_out.axi_araddr = araddr; //—-<< ADDR CTRL >>———————— //—->> DATA STREAM <<———————— logic pass_last;
always@(posedge clock,negedge rst_n)
if(~rst_n) pass_last <= 1'b0; else case(nstate) L_R,O_R: pass_last <= 1'b1; default:pass_last <= 1'b0; endcase
axi_stream_inf #(
.DSIZE(axi_out.DSIZE)
)axis_in(
.aclk (axi_out.axi_aclk ), .aresetn (axi_out.axi_aresetn ), .aclken (1'b1 )
);
axi_stream_inf #(
.DSIZE(axi_in.DSIZE)
)axis_out(
.aclk (axi_in.axi_aclk ), .aresetn (axi_in.axi_aresetn ), .aclken (1'b1 )
);
// axi_stream_partition axi_stream_partition_inst( // /* input */ .valve (valve ), // /* input [31:0] */ .partition_len (PSIZE-1 ), //[0] mean 1 len // /* output */ .req_new_len ( ), //it is usefull, when last stream length is only one // /* axi_stream_inf.slaver */ .axis_in (axis_in ), // /* axi_stream_inf.master */ .axis_out (axis_out ) // );
axis_connect_pipe axis_connect_pipe_inst( /* axi_stream_inf.slaver */ .axis_in (axis_in ), /* axi_stream_inf.master */ .axis_out (axis_out ) );
assign axis_in.axis_tvalid = axi_out.axi_rvalid; assign axis_in.axis_tdata = axi_out.axi_rdata; assign axis_in.axis_tlast = axi_out.axi_rlast && pass_last; assign axis_in.axis_tkeep = '1; assign axis_in.axis_tuser = '0; assign axi_out.axi_rready = axis_in.axis_tready;
assign axi_in.axi_rvalid = axis_out.axis_tvalid; assign axi_in.axi_rdata = axis_out.axis_tdata; assign axi_in.axi_rlast = axis_out.axis_tlast; assign axis_out.axis_tready= axi_in.axi_rready; //—-<< DATA STREAM >>———————— endmodule