1

気まぐれに作ったこのコードを取得しようとしています。ほとんどの場合、モジュール自体は問題ないと思います。すべてのエラーを吐き出しているのはテストベンチです。

コード全体は次のとおりです。

/*
Primitive code to control a stepper motor using FPGA
It will run as a seconds hand
9 June 2016
dwiref024
*/

module clock_divider(clock, reset, clock_div);

input clock;
input reset;

output clock_div;
reg [25:0]counter = 26'd0;

// Assuming a clock frequency of 40Mhz
// log2(40M) = 25.25
// Therefore 40MHz corresponds to MOD25
always@(posedge clock, negedge reset)   begin
    if(!reset) begin
        counter <= 26'd0;   
    end

    if(counter == 26'd40000000) begin
        counter <= 26'd0;
    end

    else begin
    counter <= counter + 1;
    end

end

assign clock_div = counter[24]; // Gives you a clock signal 'clock_div'of approximate frequency 1Hz

initial begin
    $dumpvars(0, clock, reset, counter);
end
endmodule

module count_seconds (
input clock_div, reset
);
reg [5:0]seconds = 6'd0;

always@(posedge clock_div, negedge reset) begin
    if (!reset) begin
        seconds <= 0;
    end
    else if (seconds == 6'd60) begin
        seconds <= 0;
    end

    else begin
        seconds <= seconds + 1;
    end
end
initial begin
    $dumpvars (0, clock_div, seconds);
end

endmodule

module get_servo(
input clock_div,
output reg servoPin = 0, 
output reg ding
);

always@(posedge clock_div)  begin
    if(clock_div)
        ding <= 1;
    else
        ding <= 0;
end
always@(ding)   begin

    if (ding) begin
        servoPin = 1'b1;
    end
    else servoPin = 1'b0;
end


initial begin
    $dumpvars (0, servoPin);
end

endmodule

module clk_tb;
reg clock;
reg reset;
reg servoPin;
reg clock_div;
reg ding;
initial begin
    clock = 0;
    reset = 0;  
    repeat(2) #10 clock = ~clock;
    reset = 1;
    forever #10 clock = ~clock; 
end

clock_divider DUT1 (clock, reset, clock_div);
get_servo DUT2 (clock_div, servoPin, ding);

initial begin
    servoPin = 1'b1;
    #1 clock_div = 1'b0;
    $finish;
end

endmodule

実行すると

$ icarusverilog -o servo servo.v

次のエラーが表示されます。

servo.v:105: error: reg clock_div; cannot be driven by primitives or continuous assignment.
servo.v:105: error: Output port expression must support continuous assignment.
servo.v:105:      : Port 3 (clock_div) of clock_divider is connected to clock_div
servo.v:106: error: reg servoPin; cannot be driven by primitives or continuous assignment.
servo.v:106: error: Output port expression must support continuous assignment.
servo.v:106:      : Port 2 (servoPin) of get_servo is connected to servoPin
servo.v:106: error: reg ding; cannot be driven by primitives or continuous assignment.
servo.v:106: error: Output port expression must support continuous assignment.
servo.v:106:      : Port 3 (ding) of get_servo is connected to ding
6 error(s) during elaboration.

ここでボード全体を調べたところ、これを回避するためにテストベンチ モジュールでいつ、どこで reg を使用するかを指定する質問がありました。

<variable name> is not a valid l-value in foo

それは私が得た最初のエラーの1つでした。それを避けようとして、私はこれらに行き着きました。誰かがこれらのエラーの根本原因とその発生源を指摘できれば、これを修正して、その過程で何か新しいことを学ぶことができるかもしれません.

4

1 に答える 1

2

信号clock_divは、複数のドライバーservoPinによって駆動されます。モジュールおよびテストベンチ自体からの出力として駆動しました。これは違法です。servoPinget_servoclk_tb

についてclock_divは、次の図を参照してください。

ポート接続規則

モジュールの出力はワイヤに接続する必要があります。ここでは、モジュールclock_divの出力ポートであり、ワイヤ タイプである必要があります。次に、その出力ワイヤを、モジュールを駆動するロジックの入力として使用できます。以下は、テストベンチ コードのスニペットです。clock_dividerservoPin

reg clock;
reg reset;
reg servoPin;
// reg clock_div; // remove this
wire clock_div_w, clock_div_w2;
assign clock_div_w2 = clock_div_w; // drive output from one module to input to another
//...
clock_divider DUT1 (clock, reset, clock_div_w); // wire output
get_servo DUT2 (clock_div_w2, servoPin, ding);  // another wire input
//...
initial begin
    // servoPin = 1'b1; // donot drive from here, module output
    #1 clock_div = 1'b0;
    $finish;
end

ポートについても同様dingです。

IEEE 1800-2012のセクション 23.3.3を参照:

各ポート接続は、ソースからシンクへの連続的な割り当てであり、接続された 1 つのアイテムは信号ソースであり、もう 1 つは信号シンクです。割り当ては、入力ポートまたは出力ポートのソースからシンクへの連続的な割り当てでなければなりません。

ポートがインスタンス化で他のポートに接続されている場合、それは一定の割り当てであるため、常にターゲット ポートがネットである必要があります。

詳細については、ポート接続ルールの質問を参照してください。

于 2016-06-09T07:02:21.560 に答える