51 / 52 · Concetto
Register interfaces and transaction side effects
주소·바이트 쓰기·응답 정지를 명세하고, 요청 한 번이 정확히 한 번의 상태 변경으로 이어지게 만듭니다.
Le lezioni sono gratuite. Iscriviti per salvare i progressi.
La traduzione non è ancora disponibile. Viene mostrata la lezione originale. (한국어)
‘레지스터에 쓴다’는 동작을 정의합니다
선수 지식: 주소 디코더, ready/valid, enable과 상태 갱신 우선순위.
설정 레지스터를 외부 제어기에 연결하면 주소가 맞는지만 확인해서는 충분하지 않습니다. 요청이 수락된 시점, 응답이 대기하는 동안의 유지 조건, 읽기 전용 주소에 쓰는 경우까지 정의해야 합니다. 여기서는 같은 클록의 간단한 단일 요청·응답 인터페이스를 사용합니다.
아래 주소는 바이트 주소이며 32비트 정렬을 사용합니다. 요청 하나마다 성공 또는 오류 응답을 정확히 하나 만듭니다.
| 주소 | 이름 | 동작 |
|---|---|---|
| 0x0 | CONFIG | 읽기/쓰기, byte strobe 적용 |
| 0x4 | STATUS | 읽기 전용, 수락 시점 값을 반환 |
| 0x8 | COMMAND | 읽으면 0, byte 0의 bit 0을 쓰면 start pulse |
| 기타 | 미정의 | 오류 응답, 상태 변경 없음 |
응답 슬롯이 비거나 비워지는 에지에 받습니다
module register_interface (
input logic clk, rst,
input logic req_valid, req_write,
output logic req_ready,
input logic [3:0] req_addr,
input logic [31:0] req_wdata,
input logic [3:0] req_wstrb,
output logic rsp_valid,
input logic rsp_ready,
output logic [31:0] rsp_rdata,
output logic rsp_error,
input logic [31:0] status_value,
output logic [31:0] config_value,
output logic start_pulse
);
assign req_ready = !rsp_valid || rsp_ready;
always_ff @(posedge clk) begin
if (rst) begin
rsp_valid <= 1'b0;
config_value <= 32'd0;
start_pulse <= 1'b0;
end else begin
start_pulse <= 1'b0;
if (req_ready) begin
rsp_valid <= req_valid;
if (req_valid) begin
rsp_rdata <= 32'd0;
rsp_error <= 1'b0;
case (req_addr)
4'h0: begin
if (req_write) begin
for (int i=0; i<4; i++)
if (req_wstrb[i])
config_value[8*i +: 8]
<= req_wdata[8*i +: 8];
end else rsp_rdata <= config_value;
end
4'h4: begin
if (req_write) rsp_error <= 1'b1;
else rsp_rdata <= status_value;
end
4'h8: begin
if (req_write)
start_pulse <= req_wstrb[0] && req_wdata[0];
end
default: rsp_error <= 1'b1;
endcase
end
end
end
end
endmodule응답이 막히면 req_ready=0이므로 config 쓰기와 command pulse도 다시 실행되지 않습니다. 이미 수락한 요청의 부작용은 발생했지만 응답만 대기할 수 있습니다. 응답 지연을 보고 요청을 무조건 재전송하면 명령이 중복 실행될 수 있습니다.
byte strobe의 의미를 계산합니다
CONFIG가 32'h11223344일 때 req_wdata=32'hAABBCCDD, req_wstrb=4'b0101을 쓰면 byte 0과 byte 2만 바뀝니다. 결과는 32'h11BB33DD입니다. 주소의 정렬, 비트 위치, 메모리의 byte 순서를 따로 확인해야 하며 wstrb=0000인 쓰기는 성공 응답을 만들되 값을 바꾸지 않습니다.
상태는 어느 시점의 값인가요?
STATUS 읽기 응답에는 요청 수락 시점의 status_value를 저장합니다. 이후 응답이 정지하는 동안 실제 status가 변해도 rsp_rdata는 유지됩니다. rsp_valid=1, rsp_ready=0인 상태에서 조합 status를 응답에 그대로 연결하면 응답 내용이 바뀌는 프로토콜 위반이 됩니다.
연속된 에지에 req_valid와 req_ready가 모두 1이면 서로 다른 두 요청입니다. 송신 측은 수락 후 valid를 내리거나 다음 요청으로 갱신해야 합니다. 같은 요청을 계속 유지하면서 한 번만 처리되기를 기대해서는 안 됩니다.
검증의 세 축
- 주소·접근 권한: 유효 주소, 비정렬 주소, STATUS 쓰기, 미정의 주소에서 오류와 부작용을 확인합니다.
- 데이터 선택: 네 strobe 비트를 전수 검사하고, 비활성 byte가 보존되는지 확인합니다.
- 흐름 제어: 응답을 여러 사이클 막아도 응답과 상태가 유지되고, 응답 소비와 다음 요청 수락이 겹쳐도 거래 수가 일치하는지 확인합니다.
Prova tu
req_wstrb[0]=1, req_wdata[0]=1인 COMMAND 쓰기가 수락된 뒤 rsp_ready=0이 3사이클 유지됩니다. start_pulse가 3사이클 동안 반복되어야 합니까? STATUS 쓰기는 config_value를 바꿔도 됩니까?
Leggi la spiegazione
start_pulse는 요청 수락 직후 한 사이클만 1이고 이후 0입니다. 응답 정지는 명령 재실행 조건이 아닙니다. STATUS 쓰기는 오류 응답을 만들고 config_value를 포함한 다른 상태를 바꾸지 않습니다. 응답 완료 전 재시도 정책도 송수신 측이 합의해야 합니다.