Verilog Зарегистрируйтесь для вывода

Я работаю с отладочной платой Altera DE2 и хочу прочитать информацию о переключателях. Это хранится в регистрах. На основе счетчика эти регистры увеличиваются. Затем предполагается, что регистры будут выводиться на семисегментные дисплеи через преобразователь B2D. Но я не могу передать регистр функции.

wire [26:0] Q,Q2,Q3,Q4;
wire [3:0] one,two,three,four;
reg SecInc,MinInc,HrInc;
reg [3:0] M1,M2,H1,H2;

assign one = SW[3:0];
assign two = SW[7:4];
assign three = SW[11:8];
assign four = SW[15:12];

always begin
    M1 = SW[3:0];
    M2 = SW[7:4];
    H1 = SW[11:8];
    H2 = SW[15:12];
end

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

    //increment seconds from 0 to 60
counter seconds (SecInc,KEY[0],Q2);
defparam seconds.n = 8;
defparam seconds.mod = 60;

    always @ (negedge CLOCK_50) begin
      if (Q2 >= 60) begin
        MinInc = 1;
        M1 <= M1 + 1'b1;
        if(M1 >= 9) begin
          M1 <= 0;
          M2 <= M2 + 1'b1;
        end
        end else begin
          MinInc = 0;
        end
      end

Мы хотим отобразить результат на SSD.

    hex(M1,HEX4);
    hex(M2,HEX5);
    hex(H1,HEX6);
    hex(H2,HEX7);

Вот в чем проблема. Это не разрешено в Verilog. Мне нужен способ отправить мои регистры в функцию, которая отображает числа от 0 до 9, используя некоторое преобразование B2D.

Я скажу, что у меня никогда раньше не было формального введения в verilog, и я перепробовал все, что мог придумать. Я даже пытался создать новый модуль, в котором я бы передал один, два, три, четыре и заставлял модуль увеличивать их, как это происходит с Q2 для счетчика, который я показал. Любые предложения или помощь очень ценятся!

По запросу вот шестнадцатеричный модуль:

    module hex(BIN, SSD);
    input [15:0] BIN;
    output reg [0:6] SSD;

    always begin
      case(BIN)
        0:SSD=7'b0000001;
        1:SSD=7'b1001111;
        2:SSD=7'b0010010;
        3:SSD=7'b0000110;
        4:SSD=7'b1001100;
        5:SSD=7'b0100100;
        6:SSD=7'b0100000;
        7:SSD=7'b0001111;
        8:SSD=7'b0000000;
        9:SSD=7'b0001100;
      endcase
    end
  endmodule

Заранее спасибо!


person Michael Miner    schedule 18.11.2013    source источник
comment
Можете ли вы показать реализацию функции «шестнадцатеричный»?   -  person alex.forencich    schedule 19.11.2013
comment
@alex.forencich был включен шестнадцатеричный модуль. Может ли сам модуль когда-либо принимать регистр в качестве аргумента?   -  person Michael Miner    schedule 19.11.2013
comment
Вам нужно давать имена модулям при их создании. Попробуйте hex hex4 (M1, HEX4);   -  person alex.forencich    schedule 19.11.2013
comment
@alex.forencich делает это, я получаю сообщение об ошибке Ошибка (10031): Сеть M1[0] в part3.v(22) уже управляется входным портом SW[0] и не может управляться другим сигналом Это дано для M1 [2] M1[3] и M1[4], это происходит для всех M   -  person Michael Miner    schedule 19.11.2013
comment
Я бы изменил output reg [0:6] SSD на output reg [6:0] SSD в шестнадцатеричном формате модуля.   -  person Morgan    schedule 19.11.2013
comment
Мне кажется, что ваша проблема не в шестнадцатеричном модуле, а в том, что сигналы M и H назначаются двумя разными всегда блоками. Попробуйте удалить экземпляр шестнадцатеричного модуля. Затем поработайте над перемещением назначения M и H внутри одного всегда блока и сделайте его условным, чтобы оно получало значения при сбросе или каком-либо триггере и увеличивалось в противном случае.   -  person Chris Stratton    schedule 19.11.2013


Ответы (2)


Ваш модуль hex не является функцией, это модуль, и поэтому он должен быть создан с таким именем экземпляра:

hex digit0(.BIN(M1), .SSD(HEX4));
hex digit1(.BIN(M2), .SSD(HEX5));
hex digit2(.BIN(H1), .SSD(HEX6));
hex digit3(.BIN(H2), .SSD(HEX7));
person nguthrie    schedule 19.11.2013
comment
Я также попробовал это, и я получаю ту же ошибку, что и выше, M1 [n] уже управляется входным портом и не может управляться дважды. - person Michael Miner; 19.11.2013

В дополнение к тому, что nguthrie был прав, вам нужно создать экземпляр вашего шестнадцатеричного преобразователя в качестве модуля, вы управляете M1 из состояния гонки в своем всегда блоке. Неблокирующие назначения будут оцениваться одновременно внутри блока (или, по существу, одновременно). Это не программа, где все происходит по порядку. Что может работать лучше:

always @ (negedge CLOCK_50) begin
if (Q2 >= 60) begin
    MinInc = 1;
    if (M1 < 9) begin
        M1 <= M1 + 1'b1;
    end else begin
      M1 <= 0;
      M2 <= M2 + 1'b1;
    end
    end else begin
      MinInc = 0;
    end
end

Вы также потенциально можете получить неожиданные результаты от ваших блокирующих назначений MinInc, но поскольку я не вижу, где это читается, трудно сказать, что произойдет. Ознакомьтесь с блокирующими (=) и неблокирующими (‹=) назначениями в Verilog. Это одна из самых хитрых концепций языка, и неправильное использование двух операций является причиной 90% самых подлых ошибок, которые я когда-либо видел. РЕДАКТИРОВАТЬ: При перечитывании вашего вопроса кажется, что вы пытаетесь управлять M1-4 как минимум из трех мест. Вы действительно не можете иметь непрерывный блок always begin и тактовый (always @ (negedge clock) begin), управляющий одним и тем же регистром. Это вызовет у вашего компилятора истерику.

person IWantAnalogHDL    schedule 19.11.2013