verilog仿真外部直接输入激励对于寄存器类型不会延后一拍
问题描述
1、verilog仿真外部直接输入激励对于寄存器类型不会延后一拍
`timescale 1ns / 1ps
module video_pack_tb(
);
reg clk,rst;
reg dpack_axis_tready;
wire din_axis_tlast;
reg din_axis_tvalid;
wire din_axis_user;
reg [31:0] din_axis_tdata;
reg [16:0] cnt;
wire [63:0] dpack_axis_tdata;
wire dpack_axis_tvalid;
wire dpack_axis_tlast;
wire din_axis_tready;
always #5 clk = ~clk;
initial begin
clk=1;
rst=1;
#40
rst=0;
end
initial begin
din_axis_tvalid = 0;
repeat(100000)begin
#10 din_axis_tvalid = {$random}%2;
end
end
initial begin
dpack_axis_tready = 0;
repeat(10000)begin
#10 dpack_axis_tready = {$random}%2;
end
dpack_axis_tready = 0;
#10000
repeat(10000)begin
#10 dpack_axis_tready = {$random}%2;
end
end
always@(posedge clk )
if(rst)
cnt<=0;
else if(din_axis_tvalid && din_axis_tready)
if(cnt==16'd28)
cnt <= 0;
else
cnt <= cnt+1;
assign din_axis_user = (cnt==0);
assign din_axis_tlast = (cnt==16'd28);
initial begin
din_axis_tdata = 0;
repeat(100000)begin
#10 din_axis_tdata = {$random}%1000;
end
end
video_pack #(
.DIN_SZ (32),
.SB_SZ (8),
.DOUT_SZ (64),
.PACK_CYCLE(8)) video_pack_inst (
.clk(clk),
.rst(rst),
.din_axis_tdata(din_axis_tdata),
.din_axis_tvalid(din_axis_tvalid),
.din_axis_tlast(din_axis_tlast),
.din_axis_tuser({3'b0,din_axis_user,4'b0}), //{reserve, sof, channel}
.din_axis_tready(din_axis_tready),
.dout_axis_tdata(dpack_axis_tdata),
.dout_axis_tvalid(dpack_axis_tvalid),
.dout_axis_tlast(dpack_axis_tlast),
.dout_axis_tready(dpack_axis_tready)
);
endmodule
`timescale 1ns / 1ps
//`include "../../../rtl/aurora/v2a.vh"
module video_pack #(
// AXI4 data channel burst lengths
parameter DIN_SZ = 64,
parameter SB_SZ = 8,
parameter DOUT_SZ = 128,
parameter PACK_CYCLE = 16 //pack cycle based on output data
)
(
input wire clk,
input wire rst,
// Input Data
input wire [DIN_SZ-1:0] din_axis_tdata,
input wire din_axis_tvalid,
input wire din_axis_tlast,
input wire [SB_SZ-1:0] din_axis_tuser,
output reg din_axis_tready,
// Output Data
output reg [DOUT_SZ-1:0] dout_axis_tdata,
output reg dout_axis_tvalid,
output reg dout_axis_tlast,
input wire dout_axis_tready
);
localparam PACK_CNT_SZ = $clog2(PACK_CYCLE);
localparam D_VLD_CNT = (DOUT_SZ/DIN_SZ);
localparam D_VLD_CNT_SZ = $clog2(D_VLD_CNT);
localparam HEADER = 3'h0;
localparam DATA = 3'h1;
localparam PAD = 3'h2;
reg [2:0] state, n_state;
reg [DOUT_SZ-1:0] n_dout_axis_tdata;
reg n_dout_axis_tvalid;
reg n_dout_axis_tlast;
wire [3:0] ch_id = din_axis_tuser[3:0];
// wire eol = din_axis_tlast;
wire eol = 1'b0;
wire sof = din_axis_tuser[4];
wire eof = din_axis_tlast; //end of frame
reg [PACK_CNT_SZ-1:0] pack_cnt; //pack data counter, excluding header
reg pack_cnt_inc;
reg [D_VLD_CNT_SZ-1:0] data_vld_cnt;
reg data_vld_cnt_inc;
always @(*) begin
n_state = state;
din_axis_tready = dout_axis_tready;
n_dout_axis_tvalid = 0;
n_dout_axis_tdata = dout_axis_tdata;
n_dout_axis_tlast = 0;
pack_cnt_inc = 0;
data_vld_cnt_inc = 0;
case (state)
HEADER: begin
if (din_axis_tvalid) begin
n_state = DATA;
n_dout_axis_tvalid = 1;
n_dout_axis_tdata[7:0] = {2'b0, eol, sof, ch_id};
n_dout_axis_tdata[31:8] = 24'hCAFEAB;
n_dout_axis_tdata[DOUT_SZ-1:32] = {din_axis_tdata[DIN_SZ-1:0], {(DOUT_SZ-DIN_SZ-32){1'b0}}};
end
end
DATA: begin
if (din_axis_tvalid & sof) begin
n_dout_axis_tvalid = 1;
n_dout_axis_tdata[7:0] = {2'b0, eol, sof, ch_id};
n_dout_axis_tdata[31:8] = 24'hCAFEAB;
n_dout_axis_tdata[DOUT_SZ-1:32] = {din_axis_tdata[DIN_SZ-1:0], {(DOUT_SZ-DIN_SZ-32){1'b0}}};
end
else if (din_axis_tvalid) begin
n_dout_axis_tdata = dout_axis_tdata>>DIN_SZ | {din_axis_tdata, {(DOUT_SZ-DIN_SZ){1'b0}}};
data_vld_cnt_inc = 1;
if (pack_cnt != (PACK_CYCLE-1) && eof)begin
n_state = PAD;
pack_cnt_inc = 1;
n_dout_axis_tvalid = 1;
end
else if(data_vld_cnt == (D_VLD_CNT-1)) begin
n_dout_axis_tvalid = 1;
pack_cnt_inc = 1;
if(pack_cnt == (PACK_CYCLE-1)) begin
n_state = HEADER;
n_dout_axis_tlast = 1;
end
end
end
end
PAD: begin
pack_cnt_inc = 1;
n_dout_axis_tvalid = 1;
n_dout_axis_tdata = {(DOUT_SZ){1'b0}};
din_axis_tready = 0;
if (pack_cnt == (PACK_CYCLE-1)) begin
n_state = HEADER;
n_dout_axis_tlast = 1;
end
end
default: begin
n_state = HEADER;
end
endcase
end
always @(posedge clk) begin
if (rst) begin
state <= HEADER;
dout_axis_tvalid <= 0;
pack_cnt <= 0;
data_vld_cnt <= 0;
end
else if (dout_axis_tready) begin
state <= n_state;
dout_axis_tvalid <= n_dout_axis_tvalid;
pack_cnt <= ((state == HEADER) | sof) ? 0
: pack_cnt_inc ? (pack_cnt == PACK_CYCLE-1) ? 0 : pack_cnt+1
: pack_cnt;
data_vld_cnt <= (((state == HEADER) | sof) & din_axis_tvalid) ? 1
: data_vld_cnt_inc ? (data_vld_cnt == D_VLD_CNT-1) ? 0 : data_vld_cnt+1
: data_vld_cnt;
end
if (dout_axis_tready) begin
dout_axis_tlast <= n_dout_axis_tlast;
dout_axis_tdata <= n_dout_axis_tdata;
end
end
endmodule
输入激励dout_axis_tready信号发生变化之后state马上跳变。