/********************************************** _ _ Cook Darwin __
_ descript: author : Cook.Darwin Version: VERA.0.0 creaded: 2017/2/22 madified: ***********************************************/ `timescale 1ns/1ps module axi4_partition_wr #(
parameter PSIZE = 128, parameter real ADDR_STEP = 1
)(
axi_inf.slaver_wr axi_in, axi_inf.master_wr 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_W,P_B,O_A,O_W,O_B,UP_B,L_A,L_W,L_B} STATUS;
STATUS nstate,cstate;
logic len_overflow; logic partition_complete;
always@(posedge clock,negedge rst_n)
if(~rst_n) cstate <= IDLE; else cstate <= nstate;
always_comb
case(cstate) IDLE: if(axi_in.axi_awvalid && axi_in.axi_awready) 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_awvalid && axi_out.axi_awready) nstate = P_W; else nstate = P_A; P_W: if(axi_out.axi_wvalid && axi_out.axi_wready && axi_out.axi_wlast) nstate = P_B; else nstate = P_W; P_B: if(axi_out.axi_bvalid && axi_out.axi_bready)begin if(partition_complete) nstate = L_A; else nstate = P_A; end else nstate = P_B; L_A: if(axi_out.axi_awvalid && axi_out.axi_awready) nstate = L_W; else nstate = L_A; L_W: if(axi_out.axi_wvalid && axi_out.axi_wready && axi_out.axi_wlast) nstate = L_B; else nstate = L_W; L_B: if(axi_out.axi_bvalid && axi_out.axi_bready)begin nstate = UP_B; end else nstate = L_B; O_A: if(axi_out.axi_awvalid && axi_out.axi_awready) nstate = O_W; else nstate = O_A; O_W: if(axi_out.axi_wvalid && axi_out.axi_wready && axi_out.axi_wlast) nstate = O_B; else nstate = O_W; O_B: if(axi_out.axi_bvalid && axi_out.axi_bready) nstate = UP_B; else nstate = O_B; UP_B: if(axi_in.axi_bvalid && axi_in.axi_bready) nstate = IDLE; else nstate = UP_B; default: nstate = IDLE; endcase
//—->> UP STREAM <<————————– always@(posedge clock,negedge rst_n)
if(~rst_n) axi_in.axi_awready <= 1'b0; else case(nstate) IDLE: axi_in.axi_awready <= 1'b1; default:axi_in.axi_awready <= 1'b0; endcase
always@(posedge clock,negedge rst_n)
if(~rst_n) axi_in.axi_bvalid <= 1'b0; else case(nstate) UP_B: axi_in.axi_bvalid <= 1'b1; default:axi_in.axi_bvalid <= 1'b0; endcase
//—-<< UP STREAM >>————————– //—->> DOWN STREAM <<———————— always@(posedge clock,negedge rst_n)
if(~rst_n) axi_out.axi_awvalid = 1'b0; else case(nstate) P_A,O_A,L_A: axi_out.axi_awvalid <= 1'b1; default:axi_out.axi_awvalid <= 1'b0; endcase
always@(posedge clock,negedge rst_n)
if(~rst_n) axi_out.axi_bready <= 1'b0; else case(nstate) P_B,O_B,L_B: axi_out.axi_bready <= 1'b1; default:axi_out.axi_bready <= 1'b0; endcase
//—-<< DOWN STREAM >>———————— //—->> LENDTH CTRL <<———————— logic [31:0] length; logic [axi_out.ASIZE-1:0] awlen;
always@(posedge clock,negedge rst_n)
if(~rst_n) len_overflow <= 1'b0; else begin if(axi_in.axi_awvalid && axi_in.axi_awready ) len_overflow <= axi_in.axi_awlen + 1 > PSIZE; else if(axi_in.axi_bready && axi_in.axi_bvalid) 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_awvalid && axi_in.axi_awready ) length <= axi_in.axi_awlen + 1 ; else if(axi_out.axi_awvalid && axi_out.axi_awready) length <= length - PSIZE; else length <= length; end
always@(posedge clock,negedge rst_n)
if(~rst_n) partition_complete <= 1'b0; else begin // case(nstate) // P_B: partition_complete <= (length <= PSIZE); // default:partition_complete <= partition_complete; // endcase end
always@(posedge clock,negedge rst_n)
if(~rst_n) awlen <= '0; else begin // if(axi_in.axi_awvalid && axi_in.axi_awready)begin // if(axi_in.axi_awlen + 1 > PSIZE) // awlen <= PSIZE-1; // else awlen <= axi_in.axi_awlen; // end else if(axi_out.axi_awvalid && axi_out.axi_awready)begin if(length>=PSIZE) awlen <= PSIZE-1; else awlen <= length-1; // end else awlen <= awlen; end
assign axi_out.axi_awlen = awlen; //—-<< LENDTH CTRL >>———————— //—->> ADDR CTRL <<———————— logic awaddr;
always@(posedge clock,negedge rst_n)
if(~rst_n) awaddr <= '0; else begin if(axi_in.axi_awvalid && axi_in.axi_awready) awaddr <= axi_in.axi_awaddr; else if(axi_out.axi_awvalid && axi_out.axi_awready) awaddr <= awaddr + int'(PSIZE*ADDR_STEP); else awaddr <= awaddr; end
assign axi_out.axi_awaddr = awaddr; //—-<< ADDR CTRL >>———————— //—->> DATA STREAM <<———————— logic valve;
always@(posedge clock,negedge rst_n)
if(~rst_n) valve <= 1'b0; else case(nstate) P_W,O_W,L_W: valve <= 1'b1; default:valve <= 1'b0; endcase
axi_stream_inf #(
.DSIZE(axi_in.DSIZE)
)axis_in(
.aclk (axi_in.axi_aclk ), .aresetn (axi_in.axi_aresetn ), .aclken (1'b1 )
);
axi_stream_inf #(
.DSIZE(axi_out.DSIZE)
)axis_out(
.aclk (axi_out.axi_aclk ), .aresetn (axi_out.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 ) );
assign axis_in.axis_tvalid = axi_in.axi_wvalid; assign axis_in.axis_tdata = axi_in.axi_wdata; assign axis_in.axis_tlast = axi_in.axi_wlast; assign axis_in.axis_tkeep = '1; assign axis_in.axis_tuser = '0; assign axi_in.axi_wready = axis_in.axis_tready;
assign axi_out.axi_wvalid = axis_out.axis_tvalid; assign axi_out.axi_wdata = axis_out.axis_tdata; assign axi_out.axi_wlast = axis_out.axis_tlast; assign axis_out.axis_tready= axi_out.axi_wready; //—-<< DATA STREAM >>———————— endmodule