2013-12-17 5 views
4

프로젝트를 마무리하고 있으며 프로세서 내부의 기능 유닛간에 양방향 핸드 쉐이킹이 필요합니다. 나는 그것이 무엇인지는 알지만 어떤 '표준'이나 좋은 간단한 예가 있는가?Verilog 양방향 핸드 셰이 킹 예

두 유닛간에 데이터 라인이 있고 X가 Y로 보낼 때 별도의 '보낸'신호가 주어집니다. Y가 '수신'신호를 받으면 다른 와이어의 X로 신호가 전송됩니다. X가 수신 된 신호를 읽으면 데이터 라인에서 데이터 전송을 중지하고 전송 된 와이어를 0 또는 Z로 설정합니다. Y는 수신 된 신호를 0 또는 Z로 설정합니다.

이것은 모두 동기식입니다 (동일한 시계에서).

이 문제를 해결하는 올바른 방법입니까? 나는 그것이 대규모로 매우 난잡해질 수 있다는 것을 알았지 만, 나는 단순한 누산기 기반의 프로세서에 대해서만 연구하고있다.

답변

5

단일 클럭 도메인에 대한 가장 일반적인 간단한 핸드 셰이크는 유효/준비 핸드 셰이크가됩니다.

'X'가 'Y'로 전송되면 X는 datavalid의 출력을 가지며 Y는 ready의 출력을가집니다.

X가 전송할 데이터를 가지고있을 때, X는 유효성을 주장하고 준비를합니다. posedge 시계가 유효하고 ready 상태가 높으면 X는 전송할 데이터를 고려하고 Y는 수신 할 데이터를 고려합니다.

이 구성표의 장점은 다운 타임없이 클록 사이클 당 하나의 데이터를 보낼 수 있다는 것입니다. valid/ready가 high 인 다음 valid가 여전히 높은 경우, 이것은 두 번째 패킷으로 간주됩니다.

Y는 Y가 준비 상태를 표시하기 전에 유효성을 확인하기 위해 대기하고 Y는 데이터를 수신 할 수있을 때마다 Y 상태를 준비 할 수있는 요구 사항이 없습니다.

당신이 설명하는 방식은 내가하는 '필수/ACK 4 단계 핸드 쉐이크'를 부를 것이다 그것은 네 개의 클럭 사이클을 소요 한 데이터

1. req=1 ack=0 
2. req=1 ack=1 
3. req=0 ack=1 
4. req=0 ack=0 

인터페이스 이런 종류의 때 더 나은 것을 보낼 것입니다 클럭 경계를 넘어서 비동기 요청을하는 것은 패킷을 두 번 해석 할 가능성을 없애기 때문입니다. 그러나 완전히 동기식 인터페이스에 대해서는이 기능이 필요하지 않습니다.

-1

저는 중재인을 디자인하려고합니다. 다양한 중재 제도가 있습니다. 가장 간단한 방법은 라운드 로빈 방식입니다. 누군가가 리소스 (예 : CPU 또는 메모리 등)에 대한 액세스를 원할 경우 해당 모듈은 요청 행을 표시합니다. 중재자가 허가 라인을 선언 할 때까지 대기하고, 중재자가 제어하는 ​​인터페이스에 대한 전용 액세스를 가지고 있음을 알면 처리를 계속할 수 있습니다.

+0

잘 작동하는지 잘 모르겠습니다. T-state를 기반으로 컨트롤러가 신호를 보내서 데이터 버스에서 단위를 읽거나 데이터 버스에 쓴다. 기능 단위 자체는 데이터의 출처 또는 이동 여부를 알지 못한다. 내가 너의 대답을 오해하지 않는다면. – zKarp

+0

당신이 뭘 찾고 있는지 잘 모르겠습니다. 좀 더 명확하게 질문을 편집 할 수 있습니까? Z가 Z라는 또 다른 구성 요소이거나 높은 임피던스라고 할 때? – Russell

0

저는 종종 FSM이 서로 트리거링/일시 정지시키는 Tim 제안과 유사한 스키마를 사용합니다. go (req) 신호는 하위 모듈 또는 보조 모듈에서 처리를 트리거 할 수 있으며 완료되면이를 확인합니다.

reg go; 
reg complete; 

//abstracted FSM1 
always @(posedge clk) begin 
    case(fsm1_state) 
    START_SUB : begin 
     go    <= 1'b1; 
     fsm1_next_state <= WAIT_SUB; 
    end 
    WAIT_SUB: begin 
     if (complete == 1'b1) begin 
     go    <= 1'b0; 
     fsm1_next_state <= COMPLETED_SUB; 
     end 
     else begin 
     go    <= 1'b1;   //Might not be required to hold high in Synch design 
     fsm1_next_state <= WAIT_SUB;  // Holds state 
     end 
    end 
    default: begin 
     go    <= 1'b0; 
     fsm1_next_state <= fsm1_state; 
    end 
    endcase 
end 

//fsm2 
always @(posedge clk) begin 
    case(fsm2_state) 
    WAITING : begin 
     complete  <= 1'b0; 
     if (go ==1'b1) begin 
     fsm2_next_state <= DOSOMETHING; 
     end 
     else begin 
     fsm2_next_state <= WAITING; 
     end 
    end 
    DOSOMETHING : begin 
     complete  <= 1'b1; 
     fsm2_next_state <= WAITING; 
     // if an async system wait until go is deasserted 
     // rather than pulse complete for 1 cycle 
    end 
    endcase 
end 

상태 시스템은 항상 초기화되거나 재설정되어야하며 의도하지 않은 잠금 상태를 제거하려면 기본 사례를 사용해야합니다.