Почему неизвестен выход таймера? - PullRequest
2 голосов
/ 17 июня 2020

Я только начал создавать таймер подсчета в Verilog и получаю неизвестный результат.

Я использую осциллятор 50 МГц и эти переменные для кода:

min: se c: 1/100 se c

ab: c d: ef

Например, я хочу, чтобы таймер был:

00:00:99 > 00:01:00
...
00:59:99 > 1:00:00
module timer    (clk,
        a,
        b,
        c,
        d,
        e,
        f,
        count);


input clk;
input [18:0]count;


output reg[3:0]a;
output reg[3:0]b;
output reg[3:0]c;
output reg[3:0]d;
output reg[3:0]e;
output reg[3:0]f;


always@(posedge clk) 
begin
    if (f == 4'b1010)       f = 4'b0000;
    else if (count == 19'd500000)   f = f+4'b0001;
end 

always@(posedge clk) 
begin
    if (e == 4'b1010)       e = 4'b0000;
    else if (f == 4'b1010)      e = e +4'b0001;
end 

always@(posedge clk) 
begin
    if (d == 4'b1010)       d = 4'b0000;
    else if (e == 4'b1010)       d = d +4'b0001;
end 

always@(posedge clk) 
begin
    if (c == 4'b1010)       c = 4'b0000;
    else if (d == 4'b1010)       c = c +4'b0001;
end 

always@(posedge clk) 
begin
    if (b == 4'b1010)       b = 4'b0000;
    else if (c == 4'b0101)      b = b +4'b0001;
end 

always@(posedge clk) 
begin
    if (a == 4'b1010)       a = 4'b0000;
    else if (c == 4'b1010)      a = a +4'b0001;
end 

endmodule

<испытательный стенд>

`timescale 1ns / 1ps

module tb_timer();

parameter clk_period = 10;
parameter N = 19;

reg clk; 
reg [N-1:0]count;

wire [3:0]a;
wire [3:0]b;
wire [3:0]c;
wire [3:0]d;
wire [3:0]e;
wire [3:0]f;

//instatiate the module 
timer U0(
    .count(count),
    .clk(clk),
    .a(a),
    .b(b),
    .c(c),
    .d(d),
    .e(e),
    .f(f));



// clk signal
always begin
 clk =0;
 forever #(clk_period/2)clk = ~clk;
end

// count signal 
always begin
f = 1'b0
count = 1'b0;
forever #clk_period count = ~count;
end

//reset signal
initial begin
reset = 1;
#12 reset = 0;
#(clk_period) reset = 0;
end

endmodule

Ответы [ 2 ]

1 голос
/ 17 июня 2020

Предполагая, что вы объявили f как wire в тестовой среде и подключили его к выходу f timer, мой симулятор выдает мне ошибку компиляции в этой строке:

f = 1'b0;

Забивать проволоку с процедурным заданием незаконно.

Ваш инстинкт прав; нужно инициализировать f. Он объявлен как reg внутри timer, что означает, что он инициализируется как X.

Обычно это делается путем добавления входного сигнала сброса к вашему проекту, который вы запускаете из своего тестового стенда. Подтвердите сброс для первых нескольких тактов, затем отпустите его. Вероятно, вам следует сбросить все свои регистры в дизайне.

always@(posedge clk or posedge reset) 
begin
    if (reset) f = 4'b0000;
    else if (f == 4'b1010)       f = 4'b0000;
    else if (count == 19'd500000)   f = f+4'b0001;
end 
0 голосов
/ 24 июня 2020

Это код Verilog, который работал. Спасибо за помощь!

module timer    (clk,
         reset,
             a,
             b,
             c,
             d,
             e,
             f,
             count);

input clk;
input reset;
input [18:0]count;

output reg[3:0]a;
output reg[3:0]b;
output reg[3:0]c;
output reg[3:0]d;
output reg[3:0]e;
output reg[3:0]f;


always@(posedge clk or negedge reset) 
begin
    if (~reset)             f <= 4'b0000;
    else if (f == 4'b1010)          f <= 4'b0000;
    else if (count == 19'd500000)   f <= f + 4'b0001;
end 

always@(posedge clk or negedge reset) 
begin   
    if (~reset)             e <= 4'b0000; 
    else if (e == 4'b1010)          e <= 4'b0000;
    else if (f == 4'b1010)          e <= e +4'b0001;
end 

always@(posedge clk or negedge reset) 
begin
    if (~reset)             d <= 4'b0000;
    else if (d == 4'b1010)          d <= 4'b0000;
    else if (e == 4'b1010)          d <= d +4'b0001;
end 

always@(posedge clk or negedge reset) 
begin
    if (~reset)             c <= 4'b0000;
    else if (c == 4'b1010)          c <= 4'b0000;
    else if (d == 4'b1010)          c <= c +4'b0001;
end 

always@(posedge clk or negedge reset) 
begin
    if (~reset)             b <= 4'b0000;
    if (b == 4'b1010)               b <= 4'b0000;
    else if (c == 4'b0101)          b <= b +4'b0001;
end 

always@(posedge clk or negedge reset) 
begin
    if (~reset)             a <= 4'b0000;
    if (a == 4'b1010)           a <= 4'b0000;
    else if (b == 4'b1010)          a <= a +4'b0001;
end 

endmodule
// <test bench>


`timescale 1ns / 1ps

module tb_timer();

parameter clk_period = 10;
parameter N = 19;

reg clk; 
reg [N-1:0]count;
reg reset;

wire [3:0]a;
wire [3:0]b;
wire [3:0]c;
wire [3:0]d;
wire [3:0]e;
wire [3:0]f;

//instatiate the module 
timer U0(
    .reset(reset),
    .count(count),
    .clk(clk),
    .a(a),
    .b(b),
    .c(c),
    .d(d),
    .e(e),
    .f(f));


//reset signal 
initial begin 
reset = 1;
#13 reset = 0;
#(clk_period)reset =1;
end

// clk signal
always begin
 clk =0;
 forever #(clk_period/2)clk = ~clk;
end

// count signal 
always begin
count = 0;
forever #(clk_period/5)count = count + 19'b0000000000000000001;
end

//reset signal
initial begin
reset = 1;
#12 reset = 0;
#(clk_period) reset = 0;
end

endmodule

<То, что я пропустил>

  1. Начальное значение Flip Flop должно быть установлено только при наличии входа сброса .
  2. В тестовой среде счетчик должен быть
// count signal 
always begin
count = 0;
forever #(clk_period/5)count = count + 19'b0000000000000000001;
end
Начальный блок выполняется только один раз и аппаратно не синтезируется.
...