2013-03-10 1 views
2

하드웨어 및 Verilog 코딩에서 래치가 눈살을 찌푸리게한다는 것을 알고 있습니다. 하지만 때로는 걸레를 피할 수없는 경우가 종종 있습니다. 예를 들어, 다음 두 경우에 해당합니다.래치를 피할 수 없으면 어떻게해야합니까?

always @ (*) 
begin 
    random_next = random; //default state stays the same 
    count_next_r = count_r; 

     random_next = {random[28:0], feedback}; //**shift left the xor'd every posedge clock 


    if (count_r == 30) //if all 30 bits are shifted into register 
    begin 
     count_next_r = 0; 
     random_done = random; //assign the random number to output after 13 shifts 
    end 
    else 

     count_next_r = count_r + 1; 

여기서 random_done은 래치입니다. 나는 이것을 쓰는 다른 방법을 볼 수 없다. 나는 random_donerandom의 30 교대 만 데이터를 갖기를 원합니다. 이 방법으로 구현하면 래치가 경고되며 제대로 작동하지 않습니다.

마찬가지로 아래 코드 :

always @ (*) 
begin 
    state_next = state_reg; //default state stays the same 
    count_next = count_reg; 
    sel_next = sel; 
    case(state_reg) 
     idle: 
      begin 
       //DISPLAY HI HERE 
       sel_next = 2'b00; 
       if(start) 
       begin 
        count_next = random_done; //get the random number from LFSR module 
        state_next = starting; 
       end 
      end 
     starting: 
      begin 
       if(count_next == 750000000) // **750M equals a delay of 15 seconds. 8191 for simulation 
       begin       //and starting from 'rand' ensures a random delay 
        outled = 1'b1; //turn on the led 
        state_next = time_it; //go to next state 
       end 

       else 
       begin 
        count_next = count_reg + 1; 
        outled = 1'b0; 
       end 
      end  
     time_it: 
      begin 
        sel_next = 2'b01; //start the timer 
        state_next = done;     
      end 

     done: 
      begin 
       if(stop) 
        begin 
         sel_next = 2'b10; //stop the timer 
         outled = 1'b0; 
        end 

      end 

     endcase 

상기 코드에서 문제가있는 부분이있다 :

done: 
    begin 
     if(stop) 
      begin 
       sel_next = 2'b10; //stop the timer 
       outled = 1'b0; 
      end 
여기 outled

래치 같이 I이 경고하고 실행 중에 검출 . 나는 멈춤 비트가 눌려 졌을 때 LED가 낮아지기를 원한다.

어떻게 이러한 래치를 피할 수 있습니까?

답변

2

random_done을 등록하지 않으시는 이유는 무엇입니까?

카운터를 생성하고 30에서 카운트 다운 한 다음 0 인 경우 레지스터 random_done에 새 임의 값을 할당하십시오.

reg [4:0] counter; 

[email protected](posedge clk) begin 
    if(rst) begin 
    counter <= 5'd30; 
    end 
    else begin 
    if(counter == 0) begin 
     counter <= 5'd30; 
    else begin 
     counter <= counter - 1; 
    end 
end 

wire count_done; 

assign count_done = (counter == 0); 

reg [size-1:0] random_done 

[email protected](posedge clk) begin 
    ... 
    if(count_done) random_done <= random; 
    ... 
end 

나에게이 코드는 약간 뒤죽박죽이되어 보이지만 하드웨어를 설명하는 것처럼 보이지 않습니다. Verilog ia는 HDL 하드웨어 설명 언어입니다. 의 설명에 중점을 두었을 때.

각 레지스터에 대한 논리를 항상 자체 블록으로 분할하십시오.

하지만 먼저 시도하려는 RTL 설계도를 그립니다. 설계하고자하는 RTL 설계도를 그릴 수 없다면 디자인은 좋은 하드웨어가 아닐 것입니다.

+0

해답을 가져 주셔서 감사합니다. "각 레지스터에 대한 논리가 항상 차단"이라는 의미에 대해 조금 자세히 설명해 주시겠습니까? 디자인이 너무 바쁘고 지저분 해지지 않을까? – ipunished

+1

부시? 무슨 말이에요? HW 입장에서 보면 중요하지 않습니다. 그것은 똑같을 것이다. 내 말은 만약 당신이 카운터를 가지고 있다면 당신은 자신의 블록을 가지고있는 상태 레지스터를 가지고 있다면 그것을 항상 하나의 블록에 두는 것입니다. 읽기 또는 쓰기 할 상태 레지스터가있는 경우에는 항상 블록이 있습니다. 예제에서 본 코드를보십시오. 카운터를위한 블록 하나와 random_done의 블록입니다. – AxelOmega

2

outled 로직을 제거 할 수 있어야합니다. 이 같은.

always @(posedge clk or negedge nreset) begin 
    if (!nreset) begin 
     outled <= 0; 
    end else if (state_reg == starting) begin 
     if (count_next == 750000000) begin 
      outled <= 1'b1; //turn on the led 
     end else begin 
      outled <= 1'b0; 
     end 
    end else if ((state_reg == done) && stop) begin 
      outled <= 1'b0; 
    end 
end 
1

모든 코드를 동기화하면 (posedge clk에 민감 함) 래치가 발생하지 않습니다. 그리고 타이밍 제약을 쓰는 것이 더 쉬운 시간을 갖게 될 것입니다 (가장 좋은 경우에는 클럭주기에 대해서만 하나의 제약이 필요합니다!)

관련 문제