如何连接不同的Verilog模块?

时间:2013-02-01 09:42:23

标签: hardware verilog fpga hdl

我正在做一个反应计时器。我以前制作了各个模块,现在剩下的就是集体使用它们了。

在其他语言中,它们用作返回值的函数。在这里,我了解模块是实例化的。我知道如何像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”,然后再显示秒表。我用评论标记了他们......我怎么能这样做?

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

1 个答案:

答案 0 :(得分:2)

  

在某些地方,我必须调用LED电路显示“Hi”,然后再显示秒表。我用评论标记了他们......我怎么能这样做?

如果你想了解verilog,你必须打破你称之为“模块”的想法。模块在您需要时不存在。在您的情况下,您需要实例化一个秒表模块,并连接端口(LFSR实例化下面的行可能是一个合适的位置)。

执行此操作时,请注意秒表始终驱动输出LED,而不仅仅是在某些状态下。如果要更改显示模式(显示 Hi 等字符串,或显示秒表时间),您应该输入秒表模块,告诉它应显示的内容。

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

在主响应模块的适当位置,您可以更改display_mode的值,然后更改stopwatch驱逐的内容。