/********************************************** _ _ Cook Darwin __
_ descript:
out of order
author : Cook.Darwin Version: VERA.0.0 creaded: 2017/3/30 madified: ***********************************************/ `timescale 1ns/1ps module axi4_merge_wr #(
parameter MAX = 8 //MUST LARGER THAN 2
)(
axi_inf.slaver_wr slaver, //Out of Last axi_inf.master_wr master //Out of Last
);
logic clock,rst_n;
assign clock = slaver.axi_aclk; assign rst_n = slaver.axi_aresetn;
typedef enum {IDLE,GET_BASE,CHECK_NEXT,MIX,WR_DOMN} STATUS;
STATUS nstate,cstate;
always@(posedge clock,negedge rst_n)
if(~rst_n) cstate <= IDLE; else cstate <= nstate;
logic [slaver.ASIZE-1:0] base_addr; logic [master.LSIZE-1:0] base_len;
logic [slaver.ASIZE-1:0] curr_addr; logic [slaver.LSIZE-1:0] curr_len; logic [$clog2(MAX)-1:0] cnt; logic enough_slaver; logic alone_aux; logic aux_fifo_wren; logic resp_fifo_full; logic resp_fifo_empty;
logic next_serial;
assign next_serial = curr_addr+curr_len+1 == slaver.axi_awaddr && !enough_slaver;
always_comb begin
case(cstate) IDLE: if(slaver.axi_awvalid && slaver.axi_awready) nstate = GET_BASE; else nstate = IDLE; GET_BASE: if(alone_aux) nstate = WR_DOMN; else if(slaver.axi_awvalid)begin if(next_serial) nstate = MIX; else nstate = WR_DOMN; end else nstate = GET_BASE; CHECK_NEXT: if(alone_aux) nstate = WR_DOMN; else if(slaver.axi_awvalid)begin if(next_serial) nstate = MIX; else nstate = WR_DOMN; end else nstate = CHECK_NEXT; MIX: if(slaver.axi_awvalid && slaver.axi_awready) nstate = CHECK_NEXT; else nstate = MIX; WR_DOMN: if(!resp_fifo_full) nstate = IDLE; else nstate = WR_DOMN; default: nstate = IDLE; endcase
end
always@(posedge clock,negedge rst_n)
if(~rst_n) slaver.axi_awready <= 1'b0; else case(nstate) IDLE,MIX: slaver.axi_awready <= 1'b1; default:slaver.axi_awready <= 1'b0; endcase
always@(posedge clock,negedge rst_n)
if(~rst_n) base_addr <= '0; else case(nstate) GET_BASE: base_addr <= slaver.axi_awaddr; default:base_addr <= base_addr; endcase
always@(posedge clock,negedge rst_n)
if(~rst_n) base_len <= '0; else case(nstate) GET_BASE: base_len <= slaver.axi_awlen; MIX: if(slaver.axi_awvalid) base_len <= slaver.axi_awaddr + slaver.axi_awlen + 1; else base_len <= base_len; default:base_len <= base_len; endcase
always@(posedge clock,negedge rst_n)
if(~rst_n) cnt <= '0; else case(nstate) GET_BASE: cnt <= '0; MIX: if(slaver.axi_awvalid) cnt <= cnt + 1; else cnt <= cnt; default:cnt <= cnt; endcase
always@(posedge clock,negedge rst_n)
if(~rst_n) enough_slaver <= '0; else case(nstate) GET_BASE: enough_slaver <= '0; MIX: if(slaver.axi_awvalid) enough_slaver <= cnt == MAX-2; else enough_slaver <= enough_slaver; default:enough_slaver <= enough_slaver; endcase
always@(posedge clock,negedge rst_n)
if(~rst_n) curr_addr <= '0; else case(nstate) GET_BASE,CHECK_NEXT: curr_addr <= slaver.axi_awaddr; default:curr_addr <= curr_addr; endcase
always@(posedge clock,negedge rst_n)
if(~rst_n) curr_len <= '0; else case(nstate) GET_BASE,CHECK_NEXT: curr_len <= slaver.axi_awlen; default:curr_len <= curr_len; endcase
always@(posedge clock,negedge rst_n)
if(~rst_n) aux_fifo_wren <= '0; else case(nstate) WR_DOMN: aux_fifo_wren <= 1'b1; default:aux_fifo_wren <= 1'b0; endcase
//—>> ALONE <<———————- logic [5:0] alone_cnt;
always@(posedge clock,negedge rst_n)
if(~rst_n) alone_cnt <= '0; else case(nstate) GET_BASE,CHECK_NEXT: alone_cnt <= alone_cnt + 1'b1; default:alone_cnt <= '0; endcase
always@(posedge clock,negedge rst_n)
if(~rst_n) alone_aux <= '0; else alone_aux <= &alone_cnt;
//—<< ALONE >>———————- common_fifo #(
.DEPTH (4 ), .DSIZE (master.ASIZE + master.LSIZE)
)aux_common_fifo_inst( /* input */ .clock (clock ), /* input */ .rst_n (rst_n ), /* input [DSIZE-1:0] */ .wdata ({base_addr,base_len}), /* input */ .wr_en (aux_fifo_wren ), /* output logic */ .rdata ({master.axi_awaddr,master.axi_awlen}), /* input */ .rd_en (master.axi_awready ), /* output logic */ .count (), /* output logic */ .empty (aux_fifo_empty ), /* output logic */ .full (aux_fifo_full ) );
assign master.axi_awvalid = !aux_fifo_empty; assign master.axi_awid = '0; //——>> READ BEAK AUX <<——————- logic master_burst_1; logic [slaver.LSIZE-1:0] master_len; logic master_fifo_full; logic master_fifo_empty;
common_fifo #(
.DEPTH (MAX ), .DSIZE (1+master.LSIZE)
)master_common_fifo_inst( /* input */ .clock (clock ), /* input */ .rst_n (rst_n ), /* input [DSIZE-1:0] */ .wdata ({(master.axi_awlen=='0),master.axi_awlen}), /* input */ .wr_en ((master.axi_awvalid && master.axi_awready) ), /* output logic */ .rdata ({master_burst_1,master_len} ), /* input */ .rd_en ((master.axi_wvalid && master.axi_wready && master.axi_wlast) ), /* output logic */ .count (), /* output logic */ .empty (master_fifo_empty ), /* output logic */ .full (master_fifo_full ) );
always@(posedge clock,negedge rst_n)
if(~rst_n) master.axi_wlast <= 1'b0; else begin if(master.axi_wvalid && master.axi_wready && master.axi_wlast) master.axi_wlast <= 1'b0; else if(!master_fifo_empty && master_burst_1) master.axi_wlast <= 1'b1; else if(master.axi_wvalid && master.axi_wready && master.axi_wcnt == (master_len-1)) master.axi_wlast <= 1'b1; else master.axi_wlast <= master.axi_wlast; end
assign master.axi_wdata = slaver.axi_wdata; assign master.axi_wvalid = slaver.axi_wvalid && !master_fifo_empty; assign slaver.axi_wready = master.axi_wready && !master_fifo_empty; // assign master.axi_wid = '0; //——<< READ BEAK AUX >>——————- //——>> SLAVER RESP <<—————————- logic [slaver.LSIZE-1:0] resp_len; logic [slaver.IDSIZE-1:0] resp_aid; logic resp_burst_1;
common_fifo #(
.DEPTH (MAX ), .DSIZE (slaver.IDSIZE)
)slaver_resp_common_fifo_inst( /* input */ .clock (clock ), /* input */ .rst_n (rst_n ), /* input [DSIZE-1:0] */ .wdata (slaver.axi_awid ), /* input */ .wr_en ((slaver.axi_awvalid && slaver.axi_awready) ), /* output logic */ .rdata (slaver.axi_bid ), /* input */ .rd_en (slaver.axi_bready ), /* output logic */ .count (), /* output logic */ .empty (resp_fifo_empty ), /* output logic */ .full (resp_fifo_full ) );
assign slaver.axi_bvalid = !resp_fifo_empty; //——<< SALVER RESP >>—————————- assign master.axi_bready = 1'b1;
endmodule