/********************************************** _ _ Cook Darwin __
_ descript:
simple slaver to multi master
author : Cook.Darwin Version: VERA.0.0
build from data_pipe_interconnect_MM_S0
Version: VERA.1.0
add lazy data
creaded: 2016/12/28 madified: ***********************************************/ `timescale 1ns/1ps module data_pipe_interconnect_S2M_A1 #(
parameter DSIZE = 8, parameter NUM = 8, parameter NSIZE = $clog2(NUM), parameter LAZISE= 1
)(
input clock, input rst_n, input clk_en, input [NSIZE-1:0] addr, // sync to s00.valid // output logic[2:0] curr_path, output[LAZISE-1:0] m00_lazy_data [NUM-1:0], input [LAZISE-1:0] s00_lazy_data , data_inf.master m00 [NUM-1:0], data_inf.slaver s00
);
//–>> PARH DEF
logic [NSIZE-1:0] from_up_path; logic [NSIZE-1:0] to_down_path; logic [NSIZE-1:0] over_buf_path;
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 from_down_ready; logic to_down_vld; 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 = to_down_data; assign m00[KK].valid = to_down_vld_array[KK]; assign from_down_ready_array[KK] = m00[KK].ready;
end endgenerate
assign from_down_ready = from_down_ready_array;
typedef enum {
IDLE , EM_CN_EM_BUF ,// empty connector,empty buffer VD_CN_EM_BUF ,// valid connector,empty buffer 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 over_flow_buffer; wire empty_buffer; wire full_buffer; reg connector_vld;
always@(*)
case(cstate) IDLE: nstate = EM_CN_EM_BUF; EM_CN_EM_BUF: if(from_up_vld && to_up_ready && clk_en) nstate = VD_CN_EM_BUF; else nstate = EM_CN_EM_BUF; VD_CN_EM_BUF: if(from_up_vld && to_up_ready && clk_en)begin if(from_down_ready || !connector_vld) nstate = VD_CN_EM_BUF; else nstate = VD_CN_VD_BUF_CLD_OPU; end else begin if(!connector_vld) nstate = EM_CN_EM_BUF; else nstate = VD_CN_EM_BUF; end VD_CN_VD_BUF_CLD_OPU: if(over_flow_buffer) nstate = OVER_FLOW; //else if(from_up_vld && to_up_ready && clk_en) else if(full_buffer && clk_en) nstate = VD_CN_VD_BUF_OPD_CLU; else nstate = VD_CN_VD_BUF_CLD_OPU; VD_CN_VD_BUF_OPD_CLU: if(empty_buffer && clk_en) nstate = VD_CN_EM_BUF; else nstate = VD_CN_VD_BUF_OPD_CLU; OVER_FLOW: nstate = OVER_FLOW; default: nstate = IDLE; endcase
//—>> current path <<——————— // logic curr_path_vld; // // always@(posedge clock/*,negedge rst_n*/) // if(~rst_n) curr_path <= 3'd0; // else // case(nstate) // IDLE,EM_CN_EM_BUF: // curr_path <= sw; // default:curr_path <= curr_path; // endcase // // always@(posedge clock/*,negedge rst_n*/) // if(~rst_n) curr_path_vld <= 1'd0; // else // case(nstate) // IDLE,EM_CN_EM_BUF: // curr_path_vld <= sw_vld; // default:curr_path_vld <= curr_path_vld; // endcase //—<< current path >>——————— //—>> to up ready signal <<————— reg to_u_ready_reg; reg over_buf_vld; 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: if(clk_en) to_up_ready <= 1'b1; else to_up_ready <= to_up_ready; VD_CN_VD_BUF_CLD_OPU:begin if(clk_en)begin if(from_up_vld && to_up_ready) to_up_ready <= 1'b0; else to_up_ready <= to_up_ready; end else to_up_ready <= to_up_ready; end default:to_up_ready<= 1'b0; endcase end
// assign to_up_ready = to_u_ready_reg; //—<< to up ready signal >>————— //—>> CONNECTOR <<—————— reg [DSIZE-1:0] connector; // reg connector_vld; reg [DSIZE-1:0] over_buf; always@(posedge clock/*,negedge rst_n*/)
if(~rst_n) connector <= {DSIZE{1'b0}}; else case(nstate) VD_CN_EM_BUF: if(from_up_vld && to_up_ready && clk_en) connector <= from_up_data; else connector <= connector; VD_CN_VD_BUF_OPD_CLU: if(from_down_ready && to_down_vld && clk_en) connector <= over_buf; else connector <= connector; IDLE,EM_CN_EM_BUF: connector <= {DSIZE{1'b0}}; default:connector <= connector; endcase
always@(posedge clock/*,negedge rst_n*/)
if(~rst_n) connector_vld <= 1'b0; else case(nstate) VD_CN_EM_BUF: if(~(from_up_vld & to_up_ready) && from_down_ready && clk_en) connector_vld <= 1'b0; else connector_vld <= 1'b1; VD_CN_VD_BUF_OPD_CLU: if(clk_en) connector_vld <= 1'b1; else connector_vld <= connector_vld; default:connector_vld <= 1'b0; endcase
//—<< CONNECTOR >>—————— //—–>> BUFFER <<——————— always@(posedge clock/*,negedge rst_n*/)begin:BUFFER_BLOCK
if(~rst_n)begin over_buf <= {DSIZE{1'b0}}; end else begin case(nstate) VD_CN_VD_BUF_CLD_OPU:begin if(from_up_vld && !over_buf_vld && clk_en) over_buf <= from_up_data; else over_buf <= over_buf; end VD_CN_VD_BUF_OPD_CLU:begin if(from_down_ready && to_down_vld && clk_en)begin over_buf <= {DSIZE{1'b0}}; end end default:; endcase
end end
always@(posedge clock/*,negedge rst_n*/)
if(~rst_n) over_buf_vld <= 1'b0; else case(nstate) VD_CN_VD_BUF_CLD_OPU: if(clk_en) over_buf_vld <= from_up_vld; else over_buf_vld <= over_buf_vld; VD_CN_VD_BUF_OPD_CLU: if(from_down_ready && to_down_vld && clk_en) over_buf_vld <= 1'b0; else over_buf_vld <= over_buf_vld; default: over_buf_vld <= 1'b0; endcase
assign empty_buffer = !over_buf_vld; assign full_buffer = over_buf_vld; always@(posedge clock/*,negedge rst_n*/)
if(~rst_n) over_flow_buffer <= 1'b0; else case(nstate) VD_CN_VD_BUF_CLD_OPU: if( over_buf_vld && to_up_ready && from_up_vld && clk_en) over_flow_buffer <= 1'b1; else over_flow_buffer <= 1'b0; default: over_flow_buffer <= 1'b0; endcase
//—–<< BUFFER >>——————— //—–>> to down data <<————— reg to_d_wr_en_reg;
// always@(posedge clock/*,negedge rst_n*/) // if(~rst_n) to_d_wr_en_reg <= 1'b0; // else // case(nstate) // VD_CN_EM_BUF: // if(~(from_up_vld & to_up_ready) && from_down_ready && clk_en) // to_d_wr_en_reg <= 1'b0; // else to_d_wr_en_reg <= 1'b1; // VD_CN_VD_BUF_OPD_CLU: // if(clk_en) // to_d_wr_en_reg <= 1'b1; // else to_d_wr_en_reg <= to_d_wr_en_reg; // default:to_d_wr_en_reg <= 1'b0; // endcase
always@(posedge clock/*,negedge rst_n*/)
if(~rst_n) to_down_vld_array <= {NUM{1'b0}}; else begin to_down_vld_array <= {NUM{1'b0}}; case(nstate) VD_CN_EM_BUF: if(~(from_up_vld & to_up_ready) && from_down_ready && clk_en) to_down_vld_array[to_down_path] <= 1'b0; else to_down_vld_array[from_up_path] <= 1'b1; VD_CN_VD_BUF_OPD_CLU: if(clk_en) to_down_vld_array[to_down_path] <= 1'b1; else to_down_vld_array[to_down_path] <= to_down_vld_array[to_down_path]; default: to_down_vld_array[to_down_path] <= 1'b0; endcase end
//—–<< to down data >>————— assign to_down_data = connector; // assign to_down_vld = to_d_wr_en_reg; assign to_down_vld = to_down_vld_array;
//—>> PATH CTRL <<——————- always@(posedge clock/*,negedge rst_n*/)
if(~rst_n) to_down_path <= {(NSIZE){1'b0}}; else case(nstate) VD_CN_EM_BUF: if(from_up_vld && to_up_ready && clk_en) to_down_path <= addr; else to_down_path <= to_down_path; VD_CN_VD_BUF_OPD_CLU: if(from_down_ready && to_down_vld && clk_en) to_down_path <= over_buf_path; else to_down_path <= to_down_path; default:to_down_path <= to_down_path; endcase
always@(posedge clock/*,negedge rst_n*/)begin:BUFFER_PATH_BLOCK
if(~rst_n)begin over_buf_path <= {(NSIZE){1'b0}}; end else begin case(nstate) VD_CN_VD_BUF_CLD_OPU:begin if(from_up_vld && !over_buf_vld && clk_en) over_buf_path <= addr; else over_buf_path <= over_buf_path; end VD_CN_VD_BUF_OPD_CLU:begin if(from_down_ready && to_down_vld && clk_en)begin over_buf_path <= {(NSIZE){1'b0}}; end end default:; endcase
end end
assign from_up_path = addr; //—<< PATH CTRL >>——————- //—>> LAZY CONNECTOR <<—————— reg [LAZISE-1:0] lazy_connector; // reg connector_vld; reg [LAZISE-1:0] lazy_over_buf; always@(posedge clock/*,negedge rst_n*/)
if(~rst_n) lazy_connector <= '0; else case(nstate) VD_CN_EM_BUF: if(from_up_vld && to_up_ready && clk_en) lazy_connector <= s00_lazy_data; else lazy_connector <= lazy_connector; VD_CN_VD_BUF_OPD_CLU: if(from_down_ready && to_down_vld && clk_en) lazy_connector <= lazy_over_buf; else lazy_connector <= lazy_connector; IDLE: lazy_connector <= {DSIZE{1'b0}}; default:lazy_connector <= lazy_connector; endcase
//—<< LAZY CONNECTOR >>—————— //—–>> LAZY BUFFER <<——————— always@(posedge clock/*,negedge rst_n*/)begin:LAZY_BUFFER_BLOCK
if(~rst_n)begin lazy_over_buf <= '0; end else begin case(nstate) VD_CN_VD_BUF_CLD_OPU:begin if(from_up_vld && !over_buf_vld && clk_en) lazy_over_buf <= s00_lazy_data; else lazy_over_buf <= lazy_over_buf; end VD_CN_VD_BUF_OPD_CLU:begin if(from_down_ready && to_down_vld && clk_en)begin lazy_over_buf <= {DSIZE{1'b0}}; end end default:; endcase
end end //—–<< LAZY BUFFER >>———————
generate for(KK=0;KK<NUM;KK++)begin
assign m00_lazy_data[KK] = lazy_connector;
end endgenerate
endmodule