62 / 63 · 개념
레지스터 인터페이스와 상태 변경 시점
주소·바이트 쓰기·응답 정지를 명세하고, 요청 한 번이 정확히 한 번의 상태 변경으로 이어지게 만듭니다.
내용은 무료로 볼 수 있습니다. 수강 신청하면 학습 기록을 저장할 수 있어요.
‘레지스터에 쓴다’는 동작을 정의합니다
선수 지식: 주소 디코더디코더 이진 코드에 대응하는 출력 선을 활성화하는 회로입니다. enable이 있으면 비활성일 때 모든 출력을 0으로 만들 수 있습니다. 자세히 보기, ready/valid핸드셰이크 송신 측의 valid와 수신 측의 ready가 같은 에지에서 모두 1일 때 데이터를 전달하는 규칙입니다. 기다리는 동안 데이터를 유지하는 규칙도 포함합니다. 자세히 보기, 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인 쓰기는 성공 응답을 만들되 값을 바꾸지 않습니다.
MSBMSB 가장 높은 자릿값을 갖는 비트입니다. 벡터의 선언 방향에 따라 인덱스 번호가 달라지므로 항상 가장 큰 번호라고 가정하면 안 됩니다. 자세히 보기부터 byte3,2,1,0 순서입니다. strobe=0101은 byte2와 byte0을 선택하므로 BB와 DD만 새로 기록합니다. strobe는 비트 한 개가 아닌 바이트 단위의 write enable입니다.
- 기존 CONFIG: 11 | 22 | 33 | 44
- 쓰기 데이터: AA | BB | CC | DD
- strobe 0101: 유지 | 교체 | 유지 | 교체
- 새 CONFIG: 11 | BB | 33 | DD
상태는 어느 시점의 값인가요?
STATUS 읽기 응답에는 요청 수락 시점의 status_value를 저장합니다. 이후 응답이 정지하는 동안 실제 status가 변해도 rsp_rdata는 유지됩니다. rsp_valid=1, rsp_ready=0인 상태에서 조합 status를 응답에 그대로 연결하면 응답 내용이 바뀌는 프로토콜 위반이 됩니다.
연속된 에지에 req_valid와 req_ready가 모두 1이면 서로 다른 두 요청입니다. 송신 측은 수락 후 valid를 내리거나 다음 요청으로 갱신해야 합니다. 같은 요청을 계속 유지하면서 한 번만 처리되기를 기대해서는 안 됩니다.
세 가지를 나누어 검증합니다
- 주소·접근 권한: 유효한 주소, 정렬되지 않은 주소, STATUS 쓰기, 정의하지 않은 주소에서 오류 응답과 상태 변경 여부를 확인합니다.
- 데이터 선택: 네 strobe 비트를 전수 검사하고, 비활성 byte가 보존되는지 확인합니다.
- 흐름 제어: 응답을 여러 사이클 막아도 응답과 상태가 유지되고, 응답 전달과 다음 요청 수락이 겹쳐도 요청과 응답의 개수가 맞는지 확인합니다.
직접 생각해 보기
req_wstrb[0]=1, req_wdata[0]=1인 COMMAND 쓰기가 수락된 뒤 rsp_ready=0이 3사이클 유지됩니다. start_pulse가 3사이클 동안 반복되어야 합니까? STATUS 쓰기는 config_value를 바꿔도 됩니까?
해설 보기
start_pulse는 요청 수락 직후 한 사이클만 1이고 이후 0입니다. 응답 정지는 명령 재실행 조건이 아닙니다. STATUS 쓰기는 오류 응답을 만들고 config_value를 포함한 다른 상태를 바꾸지 않습니다. 응답 완료 전 재시도 정책도 송수신 측이 합의해야 합니다.