/********************************************** _ _ Cook Darwin __
_ descript: author : Cook.Darwin Version: creaded: 2016/11/14 madified:2016/12/12
VD_CN_EM_BUF -> VD_CN_EM_BUF, when from_up_vld && to_up_ready && !connector_vld
***********************************************/ `timescale 1ns/1ps module data_pipe_interconnect #(
parameter DSIZE = 8
)(
input clock, input rst_n, input clk_en, input vld_sw, input [2:0] sw, output logic[2:0] curr_path, data_inf.slaver s00, data_inf.slaver s01, data_inf.slaver s02, data_inf.slaver s03, data_inf.slaver s04, data_inf.slaver s05, data_inf.slaver s06, data_inf.slaver s07, data_inf.master m00
);
logic from_up_vld; logic from_up_data; logic to_up_ready;
logic to_up_ready_array;
logic from_down_ready; logic to_down_vld; logic to_down_data;
assign from_down_ready = m00.ready; assign m00.valid = to_down_vld; assign m00.data = to_down_data;
always@(*)
case(curr_path) 0: from_up_vld = s00.valid; 1: from_up_vld = s01.valid; 2: from_up_vld = s02.valid; 3: from_up_vld = s03.valid; 4: from_up_vld = s04.valid; 5: from_up_vld = s05.valid; 6: from_up_vld = s06.valid; 7: from_up_vld = s07.valid; default: from_up_vld = s00.valid; endcase
always@(*)
case(curr_path) 0: from_up_data = s00.data; 1: from_up_data = s01.data; 2: from_up_data = s02.data; 3: from_up_data = s03.data; 4: from_up_data = s04.data; 5: from_up_data = s05.data; 6: from_up_data = s06.data; 7: from_up_data = s07.data; default: from_up_data = s00.data; endcase
// always@(*) // case(curr_path) // 0: to_up_ready = to_up_ready_array; // 1: to_up_ready = to_up_ready_array; // 2: to_up_ready = to_up_ready_array; // 3: to_up_ready = to_up_ready_array; // 4: to_up_ready = to_up_ready_array; // 5: to_up_ready = to_up_ready_array; // 6: to_up_ready = to_up_ready_array; // 7: to_up_ready = to_up_ready_array; // default: // to_up_ready = to_up_ready_array; // endcase assign to_up_ready = to_up_ready_array;
assign s00.ready = to_up_ready_array; assign s01.ready = to_up_ready_array; assign s02.ready = to_up_ready_array; assign s03.ready = to_up_ready_array; assign s04.ready = to_up_ready_array; assign s05.ready = to_up_ready_array; assign s06.ready = to_up_ready_array; assign s07.ready = to_up_ready_array;
reg [3:0] cstate,nstate; localparam IDLE = 4'd0,
EM_CN_EM_BUF = 4'd1, // empty connector,empty buffer VD_CN_EM_BUF = 4'd2, // valid connector,empty buffer VD_CN_VD_BUF_CLD_OPU = 4'd3, // valid connector,valid buffer,close down stream ,open upstream VD_CN_VD_BUF_OPD_CLU = 4'd4, // valid connector,valid buffer,open down stream ,close upstream OVER_FLOW = 4'd5; // error
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 <<——————— 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
//—<< 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_array <= 8'd0; else begin to_up_ready_array <= 8'd0; case(nstate) EM_CN_EM_BUF,VD_CN_EM_BUF: if(clk_en) to_up_ready_array[curr_path] <= vld_sw; else to_up_ready_array[curr_path] <= to_up_ready_array[curr_path] && vld_sw; VD_CN_VD_BUF_CLD_OPU:begin if(clk_en)begin if(from_up_vld && to_up_ready) to_up_ready_array[curr_path] <= 1'b0; else to_up_ready_array[curr_path] <= to_up_ready_array[curr_path] && vld_sw ; end else to_up_ready_array[curr_path] <= to_up_ready_array[curr_path] && vld_sw; end default:to_up_ready_array[curr_path] <= 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; 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
//—–<< to down data >>————— assign to_down_data = connector; assign to_down_vld = to_d_wr_en_reg;
endmodule