145 lines
3.8 KiB
Systemverilog
145 lines
3.8 KiB
Systemverilog
/* module shaper_axis_status #(
|
|
parameter int unsigned DATA_WIDTH = 128
|
|
)(
|
|
input logic clk,
|
|
input logic rst_n,
|
|
|
|
input logic [DATA_WIDTH-1:0] data_in,
|
|
input logic take,
|
|
input logic valid,
|
|
output logic ready,
|
|
|
|
output logic busy,
|
|
output logic handshake,
|
|
output logic [DATA_WIDTH-1:0] data_out
|
|
);
|
|
|
|
typedef enum logic [0:0] {
|
|
IDLE,
|
|
WAIT_TAKE
|
|
} wr_state;
|
|
|
|
wr_state state;
|
|
|
|
logic [DATA_WIDTH-1:0] data_reg;
|
|
|
|
always @(posedge clk) begin
|
|
if (!rst_n) begin
|
|
state <= IDLE;
|
|
ready <= 1'b0;
|
|
busy <= 1'b0;
|
|
handshake <= 1'b0;
|
|
data_out <= '0;
|
|
data_reg <= '0;
|
|
end else begin
|
|
case (state)
|
|
IDLE: begin
|
|
ready <= 1'b1;
|
|
if (valid) begin
|
|
busy <= 1'b0;
|
|
data_reg <= data_in;
|
|
handshake <= 1'b1;
|
|
state <= WAIT_TAKE;
|
|
end
|
|
end
|
|
WAIT_TAKE: begin
|
|
if (take) begin
|
|
data_out <= data_reg;
|
|
ready <= 1'b0;
|
|
handshake <= 1'b0;
|
|
busy <= 1'b1;
|
|
state <= IDLE;
|
|
end
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
|
|
endmodule
|
|
*/
|
|
module shaper_axis_status #(
|
|
parameter int unsigned DATA_WIDTH = 128
|
|
)(
|
|
input logic clk,
|
|
input logic rst_n,
|
|
|
|
input logic [DATA_WIDTH-1:0] data_in,
|
|
input logic take,
|
|
input logic valid,
|
|
output logic ready,
|
|
|
|
output logic busy,
|
|
output logic handshake,
|
|
output logic [DATA_WIDTH-1:0] data_out
|
|
);
|
|
|
|
typedef enum logic [0:0] {
|
|
IDLE,
|
|
WAIT_TAKE
|
|
} wr_state;
|
|
|
|
wr_state state;
|
|
|
|
logic [DATA_WIDTH-1:0] data_reg;
|
|
|
|
// Запоминаем take, если он пришёл раньше valid
|
|
logic take_pending;
|
|
|
|
// Готовы принять status только в IDLE
|
|
assign ready = (state == IDLE);
|
|
|
|
always @(posedge clk) begin
|
|
if (!rst_n) begin
|
|
state <= IDLE;
|
|
busy <= 1'b0;
|
|
handshake <= 1'b0;
|
|
data_out <= '0;
|
|
data_reg <= '0;
|
|
take_pending <= 1'b0;
|
|
end else begin
|
|
|
|
// handshake — импульс
|
|
handshake <= 1'b0;
|
|
|
|
case (state)
|
|
|
|
IDLE: begin
|
|
busy <= 1'b0;
|
|
|
|
// Запоминаем ранний take
|
|
if (take)
|
|
take_pending <= 1'b1;
|
|
|
|
// Пришёл status
|
|
if (valid && ready) begin
|
|
data_reg <= data_in;
|
|
handshake <= 1'b1;
|
|
|
|
// take был раньше ИЛИ пришёл одновременно
|
|
if (take_pending || take) begin
|
|
data_out <= data_in;
|
|
busy <= 1'b1;
|
|
take_pending <= 1'b0;
|
|
state <= IDLE;
|
|
end else begin
|
|
state <= WAIT_TAKE;
|
|
end
|
|
end
|
|
end
|
|
|
|
WAIT_TAKE: begin
|
|
busy <= 1'b1;
|
|
|
|
// take пришёл после valid
|
|
if (take) begin
|
|
data_out <= data_reg;
|
|
state <= IDLE;
|
|
end
|
|
end
|
|
|
|
endcase
|
|
end
|
|
end
|
|
|
|
endmodule |