2016-06-09 21 views
1

Ich habe versucht, diesen Code zu bekommen, den ich aus einer Laune heraus aufpeitschte. In den meisten Fällen glaube ich, dass die Module selbst in Ordnung sind. Es ist der Prüfstand, der alle Fehler aufgibt.Rookie Test Bencher, kann nicht Kopf oder Schwanz von Fehlern machen. (Mit Icarus Verilog)

Hier ist der Code in seiner Gesamtheit:

/* 
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 
[email protected](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; 

[email protected](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 
); 

[email protected](posedge clock_div) begin 
    if(clock_div) 
     ding <= 1; 
    else 
     ding <= 0; 
end 
[email protected](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 

Nach

läuft
$ icarusverilog -o servo servo.v 

ich folgende Fehlermeldungen erhalten:

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. 

ich auf den Brettern hier und sah, Fragen, angegeben, wann und wo Sie reg in den Prüfstandsmodulen verwenden, um dies zu vermeiden:

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

Das war einer der ersten Fehler, die ich bekam. Bei dem Versuch, es zu vermeiden, bin ich bei diesen Dingen gelandet. Wenn jemand auf die Ursache dieser Fehler und deren Ursprung hinweisen könnte, könnte ich das beheben und etwas Neues lernen.

Antwort

2

Die Signale clock_div, servoPin werden von mehreren Treibern gesteuert. Sie haben servoPin als eine Ausgabe von get_servo Modul und von der Testbench, clk_tb selbst gefahren. Das ist illegal.

Bezüglich clock_div, beziehen sich auf die Abbildung unten:

Port connection rules

Der Ausgang des Moduls muss an einen Draht verbunden werden. Hier ist clock_div ein Ausgangsport, von clock_divider Modul, es muss von Drahttyp sein. Dann kann diese Ausgangsleitung als Eingang für Ihre Logik verwendet werden, um das Modul servoPin zu betreiben. Es folgt ein Ausschnitt aus dem Testbench-Code:

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 

ähnliche Anmerkungen gelten für ding Port.

zu IEEE 1800-2012 Bezug Abschnitt 23.3.3:

Jede Port-Verbindung wird eine kontinuierliche Zuordnung vonQuelle sink, sein, wo ein Punkt verbunden eine Signalquelle sein soll und die anderen soll eine Signalsenke sein. Die Zuweisung muss eine fortlaufende Zuweisung von Quelle zu Senke für Eingangs- oder Ausgangsports sein.

Wenn die Anschlüsse in einer Instanziierung verbunden sind, zu jedem anderen Port, ist es eine konstante Zuordnung und daher erfordert es immer die Zielport ein Netz zu sein.

Weitere Informationen finden Sie unter Port connection rules question.

+0

@Dwiref Oza: Neben Sharvil Antwort, fügen Sie etwas Verzögerung, bevor System-Task ruft '$ finish', Sie sind beendet-up in der Simulation erst nach '# 1', # $ finish; nahe am Endmodul der Testbench. –