alexeyey_0
Newbie

Hello everyone, I'm currently writing an image processing project on systemverilog (somewhat similar to MIPI DSI). When working with the Xilinx ip block, I encountered such a problem that the data is not displayed at the moment specified in the specification. I decided to compare the implementation on systemverilog and on vhdl. The result: there is a 0.1 ps delay on sv, and data is displayed strictly in clock cycles on vhdl. I want to get the result as on vhdl, that is, without delays in sending data to the output transmission line. What could be the problem and how to solve it? I am attaching 2 testbench, one is written strictly on sv, the other on vhdl. I also attach 2 time charts.: 1 - sv, 2 - vhdl
1. sv tb
2. vhdl tb
1. sv tb
Code:
`timescale 1ns / 1ps
module tb_dvi;
logic clk = 0;
logic clk_x5 = 0;
logic [9:0] data = 10'b0;
logic reset = 1;
logic serial;
logic shift1;
logic shift2;
logic ce_delay;
logic [7:0] reset_delay;
localparam time clock_period = 20;
// Master OSERDESE2
OSERDESE2 #(
.DATA_RATE_OQ("DDR"),
.DATA_RATE_TQ("DDR"),
.DATA_WIDTH(10),
.INIT_OQ(1'b1),
.INIT_TQ(1'b1),
.SERDES_MODE("MASTER"),
.SRVAL_OQ(1'b0),
.SRVAL_TQ(1'b0),
.TBYTE_CTL("FALSE"),
.TBYTE_SRC("FALSE"),
.TRISTATE_WIDTH(1)
) master_serdes (
.OFB(),
.OQ(serial),
.SHIFTOUT1(),
.SHIFTOUT2(),
.TBYTEOUT(),
.TFB(),
.TQ(),
.CLK(clk_x5),
.CLKDIV(clk),
.D1(data[0]),
.D2(data[1]),
.D3(data[2]),
.D4(data[3]),
.D5(data[4]),
.D6(data[5]),
.D7(data[6]),
.D8(data[7]),
.OCE(ce_delay),
.RST(reset),
.SHIFTIN1(shift1),
.SHIFTIN2(shift2),
.T1(1'b0),
.T2(1'b0),
.T3(1'b0),
.T4(1'b0),
.TBYTEIN(1'b0),
.TCE(1'b0)
);
// Slave OSERDESE2
OSERDESE2 #(
.DATA_RATE_OQ("DDR"),
.DATA_RATE_TQ("DDR"),
.DATA_WIDTH(10),
.INIT_OQ(1'b1),
.INIT_TQ(1'b1),
.SERDES_MODE("SLAVE"),
.SRVAL_OQ(1'b0),
.SRVAL_TQ(1'b0),
.TBYTE_CTL("FALSE"),
.TBYTE_SRC("FALSE"),
.TRISTATE_WIDTH(1)
) slave_serdes (
.OFB(),
.OQ(),
.SHIFTOUT1(shift1),
.SHIFTOUT2(shift2),
.TBYTEOUT(),
.TFB(),
.TQ(),
.CLK(clk_x5),
.CLKDIV(clk),
.D1(1'b0),
.D2(1'b0),
.D3(data[8]),
.D4(data[9]),
.D5(1'b0),
.D6(1'b0),
.D7(1'b0),
.D8(1'b0),
.OCE(ce_delay),
.RST(reset),
.SHIFTIN1(1'b0),
.SHIFTIN2(1'b0),
.T1(1'b0),
.T2(1'b0),
.T3(1'b0),
.T4(1'b0),
.TBYTEIN(1'b0),
.TCE(1'b0)
);
always_ff @(posedge clk) begin
ce_delay <= ~reset;
end
initial forever #(clock_period / 4) clk = ~clk;
initial forever #(clock_period / 20) clk_x5 = ~clk_x5;
initial begin
#200 reset = 0;
#200 data = 10'b1100010101; // 10'h315
#20 data = 10'b1100110101; // 10'h335
#20 data = 10'b1100100100; // 10'h324
#20 $finish;
end
endmodule
2. vhdl tb
Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library UNISIM;
use UNISIM.VComponents.all;
ENTITY tb_ser IS
END tb_ser;
ARCHITECTURE behavior OF tb_ser IS
signal clk : std_logic := '0';
signal clk_x5 : std_logic := '0';
signal data : std_logic_vector(9 downto 0) := (others => '0');
signal reset : std_logic := '1'; -- Начальное состояние '1'
signal serial : std_logic := '0';
signal shift1 : std_logic := '0';
signal shift2 : std_logic := '0';
signal ce_delay : std_logic := '0';
signal reset_delay : std_logic_vector(7 downto 0) := (others => '0');
constant clock_period : time := 20 ns;
BEGIN
master_serdes : OSERDESE2
generic map (
DATA_RATE_OQ => "DDR", -- DDR, SDR
DATA_RATE_TQ => "DDR", -- DDR, BUF, SDR
DATA_WIDTH => 10, -- Parallel data width (2-8,10,14)
INIT_OQ => '1', -- Initial value of OQ output (1'b0,1'b1)
INIT_TQ => '1', -- Initial value of TQ output (1'b0,1'b1)
SERDES_MODE => "MASTER", -- MASTER, SLAVE
SRVAL_OQ => '0', -- OQ output value when SR is used (1'b0,1'b1)
SRVAL_TQ => '0', -- TQ output value when SR is used (1'b0,1'b1)
TBYTE_CTL => "FALSE", -- Enable tristate byte operation (FALSE, TRUE)
TBYTE_SRC => "FALSE", -- Tristate byte source (FALSE, TRUE)
TRISTATE_WIDTH => 1 -- 3-state converter width (1,4)
)
port map (
OFB => open,
OQ => serial,
SHIFTOUT1 => open,
SHIFTOUT2 => open,
TBYTEOUT => open,
TFB => open,
TQ => open,
CLK => clk_x5,
CLKDIV => clk,
D1 => data(0),
D2 => data(1),
D3 => data(2),
D4 => data(3),
D5 => data(4),
D6 => data(5),
D7 => data(6),
D8 => data(7),
OCE => ce_delay,
RST => reset,
SHIFTIN1 => SHIFT1,
SHIFTIN2 => SHIFT2,
T1 => '0',
T2 => '0',
T3 => '0',
T4 => '0',
TBYTEIN => '0',
TCE => '0'
);
slave_serdes : OSERDESE2
generic map (
DATA_RATE_OQ => "DDR",
DATA_RATE_TQ => "DDR",
DATA_WIDTH => 10,
INIT_OQ => '1',
INIT_TQ => '1',
SERDES_MODE => "SLAVE",
SRVAL_OQ => '0',
SRVAL_TQ => '0',
TBYTE_CTL => "FALSE",
TBYTE_SRC => "FALSE",
TRISTATE_WIDTH => 1
)
port map (
OFB => open,
OQ => open,
SHIFTOUT1 => shift1,
SHIFTOUT2 => shift2,
TBYTEOUT => open,
TFB => open,
TQ => open,
CLK => clk_x5,
CLKDIV => clk,
D1 => '0',
D2 => '0',
D3 => data(8),
D4 => data(9),
D5 => '0',
D6 => '0',
D7 => '0',
D8 => '0',
OCE => ce_delay,
RST => reset,
SHIFTIN1 => '0',
SHIFTIN2 => '0',
T1 => '0',
T2 => '0',
T3 => '0',
T4 => '0',
TBYTEIN => '0',
TCE => '0'
);
delay_ce: process(clk)
begin
if rising_edge(clk) then
ce_delay <= not reset;
end if;
end process;
-- Генерация основного тактового сигнала (clk 50 MHz)
clock_process : process
begin
while true loop
clk <= '0';
wait for clock_period / 4;
clk <= '1';
wait for clock_period / 4;
end loop;
end process;
-- Генерация быстрого тактового сигнала (clk_x5 250 MHz)
clock_x5_process : process
begin
while true loop
clk_x5 <= '0';
wait for clock_period / 20;
clk_x5 <= '1';
wait for clock_period / 20;
end loop;
end process;
-- Стимулы для тестирования
stim_proc: process
begin
wait for 200 ns;
reset <= '0'; -- Сброс выключен
wait for 200 ns;
-- Подача данных на вход
data <= "1100010101"; -- 10'h315 в двоичном формате
wait for 20 ns;
data <= "1100110101"; -- 10'h335
wait for 20 ns;
data <= "1100100100"; -- 10'h324
wait for 20 ns;
wait;
end process;
END behavior;