【问题标题】:How do I connect my different Verilog modules?如何连接不同的 Verilog 模块?
【发布时间】:2023-03-11 01:38:01
【问题描述】:

我正在制作一个反应计时器。我之前已经制作了单独的模块,现在剩下的就是集体使用它们。

在其他语言中,它们被用作返回值的函数。在这里,我了解模块已实例化。我知道如何实例化,就像我为 LFSR 所做的那样,但对于 LED 多路复用器,我不知道如何。

这是我的 LFSR 代码,它将被实例化到主模块中:

module LFSR(
    input clock,
    input reset,
    output [29:0] rnd
    );

wire feedback = rnd[29] ^ rnd[5] ^ rnd[3] ^ rnd[0]; 

reg [29:0] random;

always @ (posedge clock or posedge reset)
begin
    if (reset)
        random <= 30'hF;
    else
        random <= {random[28:0], feedback};
end

assign rnd = random;

endmodule

这里是主模块。在某些地方,我必须调用 LED 电路来显示“Hi”,然后再显示秒表。我已经用 cmets 标记了它们。我该怎么做?

module reaction(
    input clock,
    input reset,
    input start,
    input stop,
    output a,
    output b,
    output c,
    output d,
    output e,
    output f,
    output g,
    output h,
    output dp,
    output led
    );

reg [29:0] random;

LFSR random_gen(.clock(clock), .reset(reset), .rnd(random));

localparam [1:0]
                        idle = 2'b00,
                        start = 2'b01,
                        time_it = 2'b10,
                        stop = 2'b11;

reg state_reg, state_next;
reg [29:0] count_reg, count_next;

always @ (posedge clock or posedge reset)
begin
    if(reset)
        begin 
            state_reg <= idle;
            count_reg <= 0;
        end
    else
        state_reg <= state_next;
        count_reg <= count_next;
end

always @ (*)
begin
    state_next = state_reg; //default state stays the same
    count_next = count_reg;

    case(state_reg)
        idle:
                //"DISPLAY HI HERE .......... HOW??
                if(start)
                begin
                    count_next = random;
                    state_next = start;
                end

        start:
                if(count_next == 750000000) // 750M equals a delay of 15 seconds.
                begin
                    led = 1'b1;
                    state_next = time_it;
                end

                else
                    count_next = count_reg + 1;

        time_it:
                    //START STOPWATCH????????

现在我已经制作了一个可以工作的秒表。它写在下面:

module stopwatch(
    input clock,
    input reset,
    input start,
    output a, b, c, d, e, f, g, dp,
    output [3:0] an
    );

reg [3:0] reg_d0, reg_d1, reg_d2, reg_d3; //registers that will hold the individual counts
reg [22:0] ticker; //23 bits needed to count up to 5M bits
wire click;


//the mod 5M clock to generate a tick ever 0.1 second

always @ (posedge clock or posedge reset)
begin
    if(reset)

        ticker <= 0;

    else if(ticker == 5000000) //if it reaches the desired max value reset it
        ticker <= 0;
    else if(start) //only start if the input is set high
        ticker <= ticker + 1;
end

assign click = ((ticker == 5000000)?1'b1:1'b0); //click to be assigned high every 0.1 second

always @ (posedge clock or posedge reset)
begin
    if (reset)
        begin
            reg_d0 <= 0;
            reg_d1 <= 0;
            reg_d2 <= 0;
            reg_d3 <= 0;
        end

    else if (click) //increment at every click
        begin
            if(reg_d0 == 9) //xxx9 - the 0.1 second digit
            begin  //if_1
                reg_d0 <= 0;

                if (reg_d1 == 9) //xx99 
                begin  // if_2
                    reg_d1 <= 0;
                    if (reg_d2 == 5) //x599 - the two digit seconds digits
                    begin //if_3
                        reg_d2 <= 0;
                        if(reg_d3 == 9) //9599 - The minute digit
                            reg_d3 <= 0;
                        else
                            reg_d3 <= reg_d3 + 1;
                    end
                    else //else_3
                        reg_d2 <= reg_d2 + 1;
                end

                else //else_2
                    reg_d1 <= reg_d1 + 1;
            end 

            else //else_1
                reg_d0 <= reg_d0 + 1;
        end
end

//The Circuit for Multiplexing - Look at my other post for details on this

localparam N = 18;

reg [N-1:0]count;

always @ (posedge clock or posedge reset)
    begin
        if (reset)
            count <= 0;
        else
            count <= count + 1;
    end

reg [6:0]sseg;
reg [3:0]an_temp;
reg reg_dp;
always @ (*)
    begin
        case(count[N-1:N-2])

            2'b00 : 
                begin
                    sseg = reg_d0;
                    an_temp = 4'b1110;
                    reg_dp = 1'b1;
                end

            2'b01:
                begin
                    sseg = reg_d1;
                    an_temp = 4'b1101;
                    reg_dp = 1'b0;
                end

            2'b10:
                begin
                    sseg = reg_d2;
                    an_temp = 4'b1011;
                    reg_dp = 1'b1;
                end

            2'b11:
                begin
                    sseg = reg_d3;
                    an_temp = 4'b0111;
                    reg_dp = 1'b0;
                end
        endcase
    end
assign an = an_temp;

reg [6:0] sseg_temp;    
always @ (*)
    begin
        case(sseg)
            4'd0 : sseg_temp = 7'b1000000;
            4'd1 : sseg_temp = 7'b1111001;
            4'd2 : sseg_temp = 7'b0100100;
            4'd3 : sseg_temp = 7'b0110000;
            4'd4 : sseg_temp = 7'b0011001;
            4'd5 : sseg_temp = 7'b0010010;
            4'd6 : sseg_temp = 7'b0000010;
            4'd7 : sseg_temp = 7'b1111000;
            4'd8 : sseg_temp = 7'b0000000;
            4'd9 : sseg_temp = 7'b0010000;
            default : sseg_temp = 7'b0111111; //dash
        endcase
    end
assign {g, f, e, d, c, b, a} = sseg_temp;   
assign dp = reg_dp;


endmodule

我希望我能够解释我的问题。

感谢您的阅读

更新代码:

module reaction(
    input clock,
    input reset,
    input start,
    input stop,
    output a,
    output b,
    output c,
    output d,
    output e,
    output f,
    output g,
    output dp,
     output [3:0] an,
    output reg led
    );

wire [29:0] random;
reg go_hi, go_start;

//instantiate the random number generator
LFSR random_gen(.clock(clock), .reset(reset), .rnd(random));

//inistantiate module to display hi
say_hi sayhi(.clock(clock), .reset(reset), .go(go_hi), .a(a), .b(b), .c(c), .d(d), 
                    .e(e), .f(f), .g(g), .dp(dp), .an(an));

//instantiate the millisecond timer
stopwatch timer(.clock(clock), .reset(reset), .start(go_start), .a(a), .b(b), .c(c), .d(d), 
                    .e(e), .f(f), .g(g), .dp(dp), .an(an));

localparam [1:0]
                        idle = 2'b00,
                        starting = 2'b01,
                        time_it = 2'b10;
                        //stop = 2'b11;

reg state_reg, state_next;
reg [29:0] count_reg, count_next;

always @ (posedge clock or posedge reset)
begin
    if(reset)
        begin 
            state_reg <= idle;
            count_reg <= 0;
        end
    else
        state_reg <= state_next;
        count_reg <= count_next;
end

always @ (*)
begin
    state_next = state_reg; //default state stays the same
    count_next = count_reg;

    case(state_reg)
        idle:
            begin
                //DISPLAY HI HERE
                go_hi = 1;
                if(start)
                begin
                    go_hi = 0;  //dont display hi anymore
                    count_next = random;
                    state_next = starting;
                end
            end
        starting:
            begin
                if(count_next == 750) // 750M equals a delay of 15 seconds.
                begin                           //and starting from 'rand' ensures a random delay
                    led = 1'b1;
                    state_next = time_it;
                end

                else
                    count_next = count_reg + 1;
            end     
        time_it:
            begin
                    go_start = 1;
                    if(stop)
                        go_start = 0;
            end

        endcase

end

endmodule

【问题讨论】:

标签: hardware verilog fpga hdl


【解决方案1】:

在某些地方,我必须调用 LED 电路来显示“Hi”,然后再显示秒表。我已经用 cmets 标记了它们。我该怎么做?

如果您想了解 verilog,您必须打破“调用”模块的想法。模块不会仅在您希望它们存在时才存在。在您的情况下,您需要实例化一个秒表模块,并将端口连接起来(LFSR 实例化下方的行可能是执行此操作的合适位置)。

执行此操作时,请意识到您的秒表始终驱动输出 LED,而不仅仅是在某些状态下。如果你想改变显示模式(显示像 Hi 这样的字符串,或者显示秒表时间),你应该有一个输入到你的秒表模块,告诉它应该显示什么。

也许可以使用display_mode 之类的输入,其中 2'd0 表示显示“hi”,2'd1 表示显示秒表时间,2'd2 表示显示舞蹈模式等。

然后,您可以在主反应模块中的适当位置更改 display_mode 的值,这将更改 stopwatch 驱回的内容。

【讨论】:

  • 谢谢。这确实有助于澄清一些事情。我想澄清的另一件事是两个模块可以连接到相同的输出吗?我不知道如何实现您的 display_mode 实现。但是我设法将它连接在一起。但是模拟没有给出任何输出。更新的代码在上面的编辑中给出。如果您能对此发表评论,我将不胜感激。谢谢
  • 每根线应该只有一个驱动器,你需要的是一个多路复用器。将stopwatch sseg 输出连接到一个复用器端口,将say_hi sseg 输出连接到另一个复用器端口,然后使用选择信号选择输出。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多