/********************************************** _ _ Cook Darwin __
_ descript:
simple slaver to multi master
author : Cook.Darwin Version: VERA.0.0
build from data_pipe_interconnect_MM_S0
Version: VERA.0.1 2017/4/20
addr must smaller than num
Version: VERB.0.0 2017/8/4
rebuild
creaded: 2016/12/28 madified: ***********************************************/ `timescale 1ns/1ps module data_pipe_interconnect_S2M_verb #(
parameter NUM = 8, parameter NSIZE = $clog2(NUM)
)(
input clock, input rst_n, input clk_en, input [NSIZE-1:0] addr, // sync to s00.valid // output logic[2:0] curr_path, data_inf.master m00 [NUM-1:0], data_inf.slaver s00
);
//–>> PARH DEF
logic from_up_vld; logic from_up_data; logic to_up_ready;
// logic to_up_ready_array; logic [NUM-1:0] to_down_vld_array; logic [NUM-1:0] from_down_ready_array;
logic to_down_data;
assign from_up_vld = s00.valid; assign from_up_data = s00.data; assign s00.ready = to_up_ready;
int II; genvar KK; generate for(KK=0;KK<NUM;KK++)begin
assign m00[KK].data = m00[KK].valid? to_down_data : '0; assign m00[KK].valid = to_down_vld_array[KK]; assign from_down_ready_array[KK] = m00[KK].ready;
end endgenerate
typedef enum {
IDLE , EM_CN_EM_BUF ,// empty connector,empty buffer VD_CN_EM_BUF ,// valid connector,empty buffer BURST_VD_CN_EM_BUF ,// LAT_VD_CN_EM_BUF ,// RE_VD_CN_EM_BUF ,// OVER -> VD_CN_EM_BUF VD_CN_VD_BUF_CLD_OPU,// valid connector,valid buffer,close down stream ,open upstream VD_CN_VD_BUF_OPD_CLU,// valid connector,valid buffer,open down stream ,close upstream OVER_FLOW // error
} STATUS;
STATUS cstate,nstate;
always@(posedge clock/*,negedge rst_n*/)
if(~rst_n) cstate <= IDLE; else cstate <= nstate;
reg [NUM-1:0] connector_vld_array;
always@(*)
case(cstate) IDLE: nstate = EM_CN_EM_BUF; EM_CN_EM_BUF: if(from_up_vld && to_up_ready && clk_en && (addr < NUM)) nstate = VD_CN_EM_BUF; else nstate = EM_CN_EM_BUF; VD_CN_EM_BUF: if(~clk_en) nstate = VD_CN_EM_BUF; else if(|(from_down_ready_array & to_down_vld_array) )begin if(from_up_vld && to_up_ready && (addr < NUM)) nstate = BURST_VD_CN_EM_BUF; else nstate = EM_CN_EM_BUF; end else if(from_up_vld && to_up_ready && (addr < NUM))begin if(|(from_down_ready_array & to_down_vld_array) ) nstate = BURST_VD_CN_EM_BUF; else nstate = VD_CN_VD_BUF_CLD_OPU; end else begin if( !(|connector_vld_array) ) nstate = EM_CN_EM_BUF; else nstate = LAT_VD_CN_EM_BUF; end RE_VD_CN_EM_BUF: if(~clk_en) nstate = RE_VD_CN_EM_BUF; else if(|(from_down_ready_array & to_down_vld_array) )begin if(from_up_vld && to_up_ready && (addr < NUM)) nstate = BURST_VD_CN_EM_BUF; else nstate = EM_CN_EM_BUF; end else if(from_up_vld && to_up_ready && (addr < NUM))begin if(|(from_down_ready_array & to_down_vld_array) ) nstate = BURST_VD_CN_EM_BUF; else nstate = VD_CN_VD_BUF_CLD_OPU; end else begin if( !(|connector_vld_array) ) nstate = EM_CN_EM_BUF; else nstate = LAT_VD_CN_EM_BUF; end LAT_VD_CN_EM_BUF: if(~clk_en) nstate = LAT_VD_CN_EM_BUF; else if(|(from_down_ready_array & to_down_vld_array) )begin if(from_up_vld && to_up_ready && (addr < NUM)) nstate = BURST_VD_CN_EM_BUF; else nstate = EM_CN_EM_BUF; end else if(from_up_vld && to_up_ready && (addr < NUM))begin if(|(from_down_ready_array & to_down_vld_array) ) nstate = BURST_VD_CN_EM_BUF; else nstate = VD_CN_VD_BUF_CLD_OPU; end else begin if( !(|connector_vld_array) ) nstate = EM_CN_EM_BUF; else nstate = LAT_VD_CN_EM_BUF; end BURST_VD_CN_EM_BUF: if(~clk_en) nstate = BURST_VD_CN_EM_BUF; else if(|(from_down_ready_array & to_down_vld_array) )begin if(from_up_vld && to_up_ready && (addr < NUM)) nstate = BURST_VD_CN_EM_BUF; else nstate = EM_CN_EM_BUF; end else if(from_up_vld && to_up_ready && (addr < NUM))begin if(|(from_down_ready_array & to_down_vld_array) ) nstate = BURST_VD_CN_EM_BUF; else nstate = VD_CN_VD_BUF_CLD_OPU; end else begin if( !(|connector_vld_array) ) nstate = EM_CN_EM_BUF; else nstate = LAT_VD_CN_EM_BUF; end VD_CN_VD_BUF_CLD_OPU: if(clk_en) nstate = VD_CN_VD_BUF_OPD_CLU; else nstate = VD_CN_VD_BUF_CLD_OPU; VD_CN_VD_BUF_OPD_CLU: if(|(from_down_ready_array & to_down_vld_array) && clk_en) nstate = RE_VD_CN_EM_BUF; else nstate = VD_CN_VD_BUF_OPD_CLU; // OVER_FLOW: nstate = OVER_FLOW; default: nstate = IDLE; endcase
//—>> to up ready signal <<————— always@(posedge clock/*,negedge rst_n*/)
if(~rst_n) to_up_ready <= 1'd0; else begin to_up_ready <= 1'd0; case(nstate) EM_CN_EM_BUF,VD_CN_EM_BUF,RE_VD_CN_EM_BUF,LAT_VD_CN_EM_BUF,BURST_VD_CN_EM_BUF: to_up_ready <= 1'b1; default:to_up_ready<= 1'b0; endcase end
//—<< to up ready signal >>————— //—>> CONNECTOR <<—————— reg [s00.DSIZE-1:0] connector; // reg connector_vld; reg [s00.DSIZE-1:0] over_buf; always@(posedge clock/*,negedge rst_n*/)
if(~rst_n) connector <= '0; else case(nstate) VD_CN_EM_BUF,BURST_VD_CN_EM_BUF: connector <= from_up_data; RE_VD_CN_EM_BUF: connector <= over_buf; IDLE,EM_CN_EM_BUF: connector <= '0; default:connector <= connector; endcase
logic [NUM-1:0] over_buf_vld_array; logic [NSIZE-1:0] record_vld_addr;
always@(posedge clock/*,negedge rst_n*/)
if(~rst_n) connector_vld_array <= '0; else case(nstate) VD_CN_EM_BUF,BURST_VD_CN_EM_BUF:begin connector_vld_array <= '0; // connector_vld_array[addr] <= 1'b1; if(addr < NUM ) connector_vld_array[addr] <= 1'b1; end RE_VD_CN_EM_BUF: connector_vld_array <= over_buf_vld_array; IDLE,EM_CN_EM_BUF: connector_vld_array <= '0; VD_CN_VD_BUF_CLD_OPU: connector_vld_array <= '0; VD_CN_VD_BUF_OPD_CLU: connector_vld_array[record_vld_addr] <= 1'b1; default: connector_vld_array <= connector_vld_array; endcase
always@(posedge clock/*,negedge rst_n*/)
if(~rst_n) record_vld_addr <= '0; else case(nstate) VD_CN_VD_BUF_CLD_OPU: foreach(connector_vld_array[i]) if(connector_vld_array[i]) record_vld_addr <= i; default: record_vld_addr <= record_vld_addr; endcase
//—<< CONNECTOR >>—————— //—–>> BUFFER <<——————— always@(posedge clock/*,negedge rst_n*/)begin:BUFFER_BLOCK
if(~rst_n)begin over_buf <= '0; end else begin case(nstate) VD_CN_VD_BUF_CLD_OPU: over_buf <= from_up_data; RE_VD_CN_EM_BUF: over_buf <= '0; default:; endcase
end end
always@(posedge clock/*,negedge rst_n*/)
if(~rst_n) over_buf_vld_array <= '0; else case(nstate) VD_CN_VD_BUF_CLD_OPU:begin over_buf_vld_array <= '0; if(addr < NUM ) over_buf_vld_array[addr] <= 1'b1; end RE_VD_CN_EM_BUF: over_buf_vld_array <= '0; VD_CN_VD_BUF_OPD_CLU: over_buf_vld_array <= over_buf_vld_array; default: over_buf_vld_array <= '0; endcase
//—–<< BUFFER >>——————— //—–>> to down data <<————— assign to_down_vld_array = connector_vld_array; //—–<< to down data >>————— assign to_down_data = connector;
endmodule