module que4 ( clk , xrst , push , push_dat , size , pop , pop_dat , outen ); // public parameter P_DATSZ = 2; // queue data size // private parameter P_DELAY = 1; parameter P_PTR = 2; // pointer size parameter P_QSZ = P_PTR + 1; // queue size input clk ; // I : input xrst ; // I : input push ; // I : input [P_DATSZ-1:0] push_dat ; // I : output [P_QSZ-1:0] size ; // O : input pop ; // I : output [P_DATSZ-1:0] pop_dat ; // O : output outen ; // O : reg [P_PTR-1:0] r_wptr ; wire [P_PTR-1:0] w_wptr ; reg [P_QSZ-1:0] r_size ; reg [P_DATSZ-1:0] r_queue00 ; reg [P_DATSZ-1:0] r_queue01 ; reg [P_DATSZ-1:0] r_queue02 ; reg [P_DATSZ-1:0] r_queue03 ; wire [P_DATSZ-1:0] w_pop_dat ; reg r_outen ; assign pop_dat = w_pop_dat; assign size = r_size; assign outen = r_outen; // // queue pointer // // r_wptr[P_PTR-1:0] always @(posedge clk or negedge xrst) begin if (!xrst) r_wptr <= #P_DELAY {P_PTR{1'b0}}; else if (push && pop) r_wptr <= #P_DELAY r_wptr; else if (push) r_wptr <= #P_DELAY r_wptr + {{(P_PTR-1){1'b0}},1'b1}; else if (pop) r_wptr <= #P_DELAY r_wptr - {{(P_PTR-1){1'b0}},1'b1}; end assign w_wptr = (pop) ? r_wptr - {{(P_PTR-1){1'b0}},1'b1} : r_wptr; // // size counter // // r_size[P_QSZ-1:0] always @(posedge clk or negedge xrst) begin if (!xrst) r_size <= #P_DELAY {P_QSZ{1'b0}}; else if (push && pop) r_size <= #P_DELAY r_size; else if (push) r_size <= #P_DELAY r_size + {{(P_QSZ-1){1'b0}},1'b1}; else if (pop) r_size <= #P_DELAY r_size - {{(P_QSZ-1){1'b0}},1'b1}; end // // queue in // // r_queue00[P_DATSZ-1:0] always @(posedge clk or negedge xrst) begin if (!xrst) r_queue00 <= #P_DELAY {P_DATSZ{1'b0}}; else if (push && w_wptr == 2'd0) r_queue00 <= #P_DELAY push_dat; else if (pop) r_queue00 <= #P_DELAY r_queue01; end // r_queue01[P_DATSZ-1:0] always @(posedge clk or negedge xrst) begin if (!xrst) r_queue01 <= #P_DELAY {P_DATSZ{1'b0}}; else if (push && w_wptr == 2'd1) r_queue01 <= #P_DELAY push_dat; else if (pop) r_queue01 <= #P_DELAY r_queue02; end // r_queue02[P_DATSZ-1:0] always @(posedge clk or negedge xrst) begin if (!xrst) r_queue02 <= #P_DELAY {P_DATSZ{1'b0}}; else if (push && w_wptr == 2'd2) r_queue02 <= #P_DELAY push_dat; else if (pop) r_queue02 <= #P_DELAY r_queue03; end // r_queue03[P_DATSZ-1:0] always @(posedge clk or negedge xrst) begin if (!xrst) r_queue03 <= #P_DELAY {P_DATSZ{1'b0}}; else if (push && w_wptr == 2'd3) r_queue03 <= #P_DELAY push_dat; else if (pop) r_queue03 <= #P_DELAY {P_DATSZ{1'b0}}; end // // queue out // // w_pop_dat[P_DATSZ-1:0] assign w_pop_dat = r_queue00; // r_outen always @(posedge clk or negedge xrst) begin if (!xrst) r_outen <= #P_DELAY 1'b0; else if (push && r_size == 3'd0) r_outen <= #P_DELAY 1'b1; else if (!push && pop && r_size == 3'd1) r_outen <= #P_DELAY 1'b0; end endmodule