2013-03-30 2 views
3

를 할당 말 다음 코드 섹션 (같은 블록) : A는 항상 2를 할당 할 수의 Verilog 순서는

A <= 1 
A <= 2 

윌 변수? 또는 경쟁 조건이 있고 1 또는 2가 할당됩니까?

논 블로킹 할당에 대한 나의 이해는 미래의 시간에 변수 A를 할당하는 것이 하드웨어에 달려 있기 때문에 임의의 결과 일 수 있습니다. 그러나 이것은 직관적이지 않습니다. 시뮬레이션 결과 2는 항상 할당되지만, 이것이 인지 확실히 알고 싶습니다. 하드웨어 합성의 경우는입니다.

+1

유효하지 않은 구문입니다. 좀 더 완전한 코드 예제를 보여줘야합니다. – toolic

답변

4

시뮬레이션에서 A가 2가되고 마지막으로 정의 된 값이 적용됩니다. 그들이 동일한 블록에 없다면 시뮬레이션에서 마지막으로 정의 된 시뮬레이터 스케줄러에 따라 경쟁 조건이있을 수 있습니다.

이 기술은 꽤 많이 사용되었고 합성 후 예기치 않은 결과는 전혀 보지 못했지만 다른 사람들은 이것이 Verilog 사양에 의해 보장되거나 보장되지 않는다고 언급 했으므로 이것의

사용이 드문 드문의 출력을 정의하는 FSM 수 있습니다 :

always @(posedge clk) begin 
    out_one <= 1'b0; 
    out_two <= 1'b0; 
    out_thr <= 1'b0; 
    case (state) 
    2'd1 : out_one <= 1'b1; 
    2'd2 : out_two <= 1'b1; 
    2'd3 : out_thr <= 1'b1; 
    endcase 
end 
+0

과 모순됩니다. 본질적으로이 질문을하는 것이기 때문에, 특정 상태에서만 변경되는 기본 출력이 있었기 때문입니다. – nehz

0

IEEE Std (예 : 1800-2009)의 "결정론"섹션에 따르면 이러한 명령문이 begin-end 블록에 있으면 시뮬레이션에서 항상 A에 값 2가 할당됩니다.

그러나 Std는 코드 합성 방법을 보증하지 않습니다. 결과 게이트는 아마도 합성 도구에 의존합니다. 그러나 좋은 RTL linting 도구는 이러한 잘못된 코딩을 식별합니다. Cadence의 Hal lint 도구가 경고를 표시합니다.

+0

RTL linting tool에 대한 제안 사항이 있습니까? quartus II는 불평/경고하지 않습니다. ( – nehz

+0

대답을 업데이트했습니다. – toolic

-3

RTL의 관점. "A"는 1과 2로 지정됩니다. 첫 번째와 두 번째가 될 수 있지만 그 반대의 경우도 있습니다. 그러나 시작 값 블록의 끝에 할당 할 값을 알 수 없으므로 1 또는 2가 될 수 있습니다 할당 된 두 번째 값).

+0

귀하의 진술은 IEEE Std. – toolic

2

하지 시뮬레이션이 아닌 합성 코드에서 A의 최종 값에 대한 결정적 아무것도 없다.

그러나 정확히 말하면 디자인에 A에 트리거가있는 경우 시뮬레이션 합성 불일치가 발생할 수 있습니다. 그래서 a 항상 끝, 시뮬레이션 동안

module tb; 
    reg clk = 0; 
    always #5 clk = ~clk; 

    wire a, b; 
    test uut (clk, a, b); 

    initial begin 
    $monitor("clk=%b a=%b b=%b", clk, a, b); 
    repeat (100) @(posedge clk); 
    $finish; 
    end 
endmodule 

업데이트 a <= 0a <= 1 모두 NBA 이벤트 영역으로 밀어 넣으면에서 주문 실행됩니다

module test(input clk, output reg a, b); 
    always @(posedge clk) begin 
    a <= 0; 
    a <= 1; 
    end 

    initial b = 0; 
    always @(posedge a) begin 
    b <= !b; 
    end 
endmodule 

그리고 테스트 벤치 : 다음 예를 살펴 보겠습니다 되고있다. 그러나 a <= 0도 실행되므로 매 클록주기마다 너비가 0 인 네거티브 펄스가 a에 있습니다. 이 펄스는 두 번째 항상 블록을 트리거합니다.

clk=0 a=x b=0 
clk=1 a=1 b=1 
clk=0 a=1 b=1 
clk=1 a=1 b=0 
clk=0 a=1 b=0 
clk=1 a=1 b=1 
clk=0 a=1 b=1 
clk=1 a=1 b=0 
clk=0 a=1 b=0 
clk=1 a=1 b=1 
clk=0 a=1 b=1 
clk=1 a=1 b=0 
clk=0 a=1 b=0 
... 

그러나, 합성이 간단히 a에게 일정한 값 1 b 상수 제로 값을 지정한다 :이 (루스의 Verilog와 ModelSim을 테스트) 시뮬레이션 출력된다. (Yosys와 Xilinx Vivado로 테스트되었습니다.) 그래서 포스트 합성 시뮬레이션 출력은 다음과 같습니다

clk=0 a=1 b=0 
clk=1 a=1 b=0 
clk=0 a=1 b=0 
clk=1 a=1 b=0 
clk=0 a=1 b=0 
clk=1 a=1 b=0 
clk=0 a=1 b=0 
clk=1 a=1 b=0 
clk=0 a=1 b=0 
clk=1 a=1 b=0 
clk=0 a=1 b=0 
clk=1 a=1 b=0 
clk=0 a=1 b=0 
clk=1 a=1 b=0 

(이론적으로 첫 번째 줄은 여전히 ​​a=x 말할 수 있지만, 모든 괜찮은 합성 툴은 테스트에서 모두 도구로, 멀리 a -flip 플롭을 최적화 할 것 않았다.)

그 외에도 그 코드에는 문제가 없으며 그의 답변에서 @Morgan이 정확하게 지적했듯이 이것은 인코딩하기 전에 출력 신호의 "기본값"을 정의하는 매우 일반적인 코딩 기술입니다. 조건부 지정을 사용하는 특별한 경우 (if 및/또는 case 사용).