Перейти к содержанию
    

Lattice Diamond + Active-HDL

Делаю симуляцию в указанной выше связки.

Симуляцию выполняю в режиме Post-Route Gate-Level + Timing.

Симулирую проект квадратурного декодера на verilog.

Вот код


module quad(
	input wire clk,
	input  wire quadA,
	input  wire quadB,
    input  wire quadZ,
    input  wire [31:0] val,
	input  wire wr_en,
    input  wire i_rst,
	output reg [31:0] cnt,
    output reg [31:0] zMark
);

reg [2:0]  quadA_delayed, quadB_delayed, quadZ_delayed;

always @(posedge clk or posedge i_rst)
begin
    if(i_rst)
        begin
            quadA_delayed <= 3'd0;
            quadB_delayed <= 3'd0;
            quadZ_delayed <= 3'd0;
        end
    else
        begin
            quadA_delayed <= {quadA_delayed[1:0], quadA};
            quadB_delayed <= {quadB_delayed[1:0], quadB};
            quadZ_delayed <= {quadZ_delayed[1:0], quadZ};
        end
end

reg count_enable;
reg count_direction;
reg z_pulse; 

always @(posedge clk)
begin
    count_direction <= quadA_delayed[1] ^ quadB_delayed[2];
    count_enable    <= quadA_delayed[1] ^ quadA_delayed[2] ^ quadB_delayed[1] ^ quadB_delayed[2];
    z_pulse <= ~quadZ_delayed[2] & quadZ_delayed[1]; 
end

always @(posedge clk or posedge i_rst)
begin
    if(i_rst)
        begin
            cnt <= 32'd0;
            zMark <= 32'd0;
        end
    else
    begin
        if(wr_en)
            cnt <= val;
        else
            begin
                if(count_enable)
                begin
                    if (count_direction) 
                        cnt <= cnt + 32'd1; 
                    else 
                        cnt <= cnt - 32'd1;
                end
                if(z_pulse) zMark <= cnt; 
            end
     end
end

endmodule

 

Кот тест бенча



// TOOL:     vlog2tf
// DATE:     Tue Jun 25 11:42:01 2019
 
// TITLE:    Lattice Semiconductor Corporation
// MODULE:   top_level
// DESIGN:   top_level
// FILENAME: qdecoder_tf.v
// PROJECT:  Unknown
// VERSION:  2.0
// This file is auto generated by the Diamond

`timescale 1 ns / 1 ns

// Define Module for Test Fixture
module qdec_sim_tf();

// Inputs
    reg clock_50;
    reg wrn;
    reg rdn;
    reg rst;
    reg [3:0] addr;
    reg qA1, qB1, qA2, qB2, qA3, qB3, qZ1, qZ2, qZ3;

// Outputs
    wire led_2;
    wire led_3;
    wire led_4;

// Bidirs
    reg [15:0] quad_io;
    wire [15:0] val_io;

// Instantiate the UUT
// Please check and add your parameters manually
    top_level UUT (
        .clock_50(clock_50),
		.rst(rst),
        .led_2(led_2),
        .led_3(led_3), 
        .led_4(led_4), 
        .wrn(wrn), 
        .rdn(rdn), 
        .quad_io(val_io),
        .addres(addr),
        .qA1(qB1), 
        .qB1(qA1), 
        .qZ1(qZ1), 
        .qA2(qA2), 
        .qB2(qB2), 
        .qZ2(qZ2), 
        .qA3(qA3),
        .qB3(qB3),
        .qZ3(qZ3)
        );

// Initialize Inputs
// You can add your stimulus here
    initial begin
            clock_50 = 0;
            wrn = 1;
            rdn = 1;
            quad_io = 0;
            rst = 0;
            qA1 = 0;
            qB1 = 0;
            qA2 = 0;
            qB2 = 0;
            qA3 = 0;
            qB3 = 0;
            qZ1 = 0;
            qZ2 = 0;
            qZ3 = 0;            
    end

    assign val_io = (wrn == 0) ? quad_io : 16'bZ;
	always 
		#10  clock_50 <= ~ clock_50;    //creating clk	
 
/**/
 always
        begin
            #3500 addr = 0;
            #50  rdn = 0;
            #40  rdn = 1;
            #1   addr = 1;
            #50  rdn = 0;
            #40  rdn = 1;
            #3500 addr = 6;
            #50  rdn = 0;
            #40  rdn = 1;
            #1   addr = 7;
            #50  rdn = 0;
            #40  rdn = 1;
        end
        
    always
    begin
         #2000 qA1 = 1;
         #2000 qB1 = 1;
         #2000 qA1 = 0;
         #2000 qB1 = 0;
    end
    
    always
    begin
        #80000 qZ1 = 1;
        #2000  qZ1 = 0;
    end

initial begin          
		#2000  rst = 1;
		#50    rst = 0;    
		#150    rst = 1; 
		#50    rst = 0;     
		#1350  quad_io = 100;
        #1020  addr = 0;
        #180    wrn = 0;
        #30    wrn = 1;
        #20    addr = 1;
        #5      quad_io = 670;
        #30    wrn = 0;
        #30    wrn = 1;
        #1350  quad_io = 200;
        #1020  addr = 0;
        #180    wrn = 0;
        #30    wrn = 1;
        #20    addr = 1;
        #5      quad_io = 170;
        #30    wrn = 0;
        #30    wrn = 1;
        #1350  quad_io = 55;
        #1020  addr = 0;
        #180    wrn = 0;
        #30    wrn = 1;
        #20    addr = 1;
        #30    wrn = 0;
        #30    wrn = 1;
        #1350  quad_io = 03;
        #1020  addr = 0;
        #180    wrn = 0;
        #30    wrn = 1;
        #20    addr = 1;
        #5      quad_io = 60000;
        #30    wrn = 0;
        #30    wrn = 1;
    end

endmodule // top_level_tf

 

Если счет импульсов идет в сторону увеличения значения счетчика, то все симулируется корректно.

Если в обратно, то появляются какие-то сбои.Счетчик перепрыгивает значения.

wave.thumb.JPG.1ba02077510441beaa33d74c1b6a71b7.JPG

image.thumb.png.6111f3e7a0dc4f1395352fbaa3377bc7.png

Это ошибки в коде или глюк симулятора ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

56 минут назад, dimka76 сказал:

Вот код

 

Кот тест бенча




// TOOL:     vlog2tf
// DATE:     Tue Jun 25 11:42:01 2019
 
// TITLE:    Lattice Semiconductor Corporation
// MODULE:   top_level
// DESIGN:   top_level
// FILENAME: qdecoder_tf.v
// PROJECT:  Unknown
// VERSION:  2.0
// This file is auto generated by the Diamond

`timescale 1 ns / 1 ns

// Define Module for Test Fixture
module qdec_sim_tf();

// Inputs
    reg clock_50;
    reg wrn;
    reg rdn;
    reg rst;
    reg [3:0] addr;
    reg qA1, qB1, qA2, qB2, qA3, qB3, qZ1, qZ2, qZ3;

// Outputs
    wire led_2;
    wire led_3;
    wire led_4;

// Bidirs
    reg [15:0] quad_io;
    wire [15:0] val_io;

// Instantiate the UUT
// Please check and add your parameters manually
    top_level UUT (
        .clock_50(clock_50),
		.rst(rst),
        .led_2(led_2),
        .led_3(led_3), 
        .led_4(led_4), 
        .wrn(wrn), 
        .rdn(rdn), 
        .quad_io(val_io),
        .addres(addr),
        .qA1(qB1), 
        .qB1(qA1), 
        .qZ1(qZ1), 
        .qA2(qA2), 
        .qB2(qB2), 
        .qZ2(qZ2), 
        .qA3(qA3),
        .qB3(qB3),
        .qZ3(qZ3)
        );

// Initialize Inputs
// You can add your stimulus here
    initial begin
            clock_50 = 0;
            wrn = 1;
            rdn = 1;
            quad_io = 0;
            rst = 0;
            qA1 = 0;
            qB1 = 0;
            qA2 = 0;
            qB2 = 0;
            qA3 = 0;
            qB3 = 0;
            qZ1 = 0;
            qZ2 = 0;
            qZ3 = 0;            
    end

    assign val_io = (wrn == 0) ? quad_io : 16'bZ;
	always 
		#10  clock_50 <= ~ clock_50;    //creating clk	
 
/**/
 always
        begin
            #3500 addr = 0;
            #50  rdn = 0;
            #40  rdn = 1;
            #1   addr = 1;
            #50  rdn = 0;
            #40  rdn = 1;
            #3500 addr = 6;
            #50  rdn = 0;
            #40  rdn = 1;
            #1   addr = 7;
            #50  rdn = 0;
            #40  rdn = 1;
        end
        
    always
    begin
         #2000 qA1 = 1;
         #2000 qB1 = 1;
         #2000 qA1 = 0;
         #2000 qB1 = 0;
    end
    
    always
    begin
        #80000 qZ1 = 1;
        #2000  qZ1 = 0;
    end

initial begin          
		#2000  rst = 1;
		#50    rst = 0;    
		#150    rst = 1; 
		#50    rst = 0;     
		#1350  quad_io = 100;
        #1020  addr = 0;
        #180    wrn = 0;
        #30    wrn = 1;
        #20    addr = 1;
        #5      quad_io = 670;
        #30    wrn = 0;
        #30    wrn = 1;
        #1350  quad_io = 200;
        #1020  addr = 0;
        #180    wrn = 0;
        #30    wrn = 1;
        #20    addr = 1;
        #5      quad_io = 170;
        #30    wrn = 0;
        #30    wrn = 1;
        #1350  quad_io = 55;
        #1020  addr = 0;
        #180    wrn = 0;
        #30    wrn = 1;
        #20    addr = 1;
        #30    wrn = 0;
        #30    wrn = 1;
        #1350  quad_io = 03;
        #1020  addr = 0;
        #180    wrn = 0;
        #30    wrn = 1;
        #20    addr = 1;
        #5      quad_io = 60000;
        #30    wrn = 0;
        #30    wrn = 1;
    end

endmodule // top_level_tf

 

Просто к слову. Вы знаете такое слово - task?

Если не знаете, то могу рассказать...

Напишите таск и тестбенч станет намного понятнее...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

48 minutes ago, iosifk said:

Просто к слову. Вы знаете такое слово - task?

Если не знаете, то могу рассказать...

Напишите таск и тестбенч станет намного понятнее...

Спасибо. Расскажите, если не сложно.

Но ваше замечание заставило меня еще раз внимательно вглядеться в код моего тестбенча. И таким образом обнаружилась ошибка, которая приводила к сбоям.

always 
		#10  clock_50 <= ~ clock_50;    //creating clk

Т.е. частота получается 50 МГц и на выходе PLL симулятор выдавал 250 МГц.

А должно быть на входе 25, на выходе 125 МГц.

Да и временной анализ мне показывал, что достижимая частота в моем проекте 170 МГц.

Итак, все глюки из-за неправильной входной частоты.

Исправил и поведение исправилось.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...