사거리인 주요도로와 간선도로의 교차로에서 교통을 위한 제어기를 설계해보기로 한다.
순차회로에 대하여 알고 싶다면 다음 글을 참고하길 바란다!👇
교통 신호 제어기
다음과 같은 명제를 고려해야 한다.
- 주요도로(Main Highway)는 차가 끊임없이 다니기 때문에 주요도로의 신호등은 가장 높은 우선순위를 가진다. 그러므로 주요도로의 신호는 기본적으로 녹색이다.
- 간선도로(Counrty Road)에서는 때때로 차가 교차로를 지나간다. 이때 간선도로의 신호등은 녹색으로 바뀐다.
- 간선도로에 차가 없으면, 간선도로의 신호등은 노란색으로 바뀌고 다시 빨간색으로 바뀌어야 한다. 주요도로의 신호등은 다시 녹색으로 바뀐다.
- 간선도로에 차가 있는지 감지하는 센서가 있다. 센서는 제어기의 입력으로 신호 X를 보낸다. 간선도로에 차가 있으면 X=1, 없으면 X=0이다.
위의 명제를 가지고 FSM을 만든다.
- 입력(X)
- 간선도로에 차가 있는가?
→ 있으면 X = 1, 없으면 X = 0
- 출력
- 3가지 상태(녹색, 노란색, 빨간색)의 신호에 대한 2비트 출력
- hwy, cntry 각각의 출력 신호에 대한 레지스터
- 초기화
- 주요도로는 초록불, 간선도로는 빨간불인 상태
- 상태
- 기본 상태: 주요도로가 초록불, 간선도로가 빨간불 (S0)
- 간선도로에 차가 있을 때: 주요도로가 노란불로 바뀌고 다시 빨간불으로 바뀐다. (S1)
주요도로가 빨간불일 때 간선도로는 초록불로 바뀐다. (S2) - 간선도로에 차가 없을 때: 간선도로가 노란불로 바뀌고 다시 빨간불으로 바뀐다. (S3)
간선도로가 빨간불일 때 주요도로는 초록불로 바뀐다. (S4)
FSM을 만들면 다음과 같은 형태를 띠게 된다.
S0 → S1과 다르게 S1 → S2로 진행될 때는 조건이 없으므로 그냥(?) 진행하면 된다.
교통 신호 제어기를 Verilog 코드로 설계하기 위해 녹색, 노란색, 빨간색을 2비트 신호로 표현해야 한다.
각각의 신호를 다음과 같이 지정했다.
Red = 2'b00
Green = 2'b01
Yellow = 2'b10
※ 상태에 따른 신호등의 색깔을 이진수로 표현한 표
MAIN_SIG | CNTRY_SIG | |
S0 | 01 (G) | 00 (R) |
S1 | 10 (Y) | 00 (R) |
S2 | 00 (R) | 00 (R) |
S3 | 00 (R) | 01 (G) |
S4 | 00 (R) | 10 (Y) |
* RTL
`define TURE 1'b1
`define FALSE 1'b0
module sig_control(hwy, cntry, X, clock, clear);
input X; // cntry에 차가 있을 경우 1, cntry에 차가 없을 경우 0
input clock;
input clear;
output [1:0] hwy;
output [1:0] cntry;
reg [1:0] hwy;
reg [1:0] cntry;
parameter RED = 2'b00;
parameter GREEN = 2'b01;
parameter YELLOW = 2'b10;
parameter S0 = 3'b000;
parameter S1 = 3'b001;
parameter S2 = 3'b010;
parameter S3 = 3'b011;
parameter S4 = 3'b100;
reg [2:0] state;
// main fsm
always @(posedge clock) begin
if (clear == 1'b1)
state <= S0;
else
case (state)
S0 : state <= (X) ? S1 : S0;
S1 : state <= S2;
S2 : state <= S3;
S3 : state <= (X) ? S3 : S4;
S4 : state <= S0;
default : state <= S0;
endcase
end
// hwy output
always @(*) begin
case (state)
S0 : hwy = GREEN; // 2'b01;
S1 : hwy = YELLOW; // 2'b10;
S2 : hwy = RED; // 2'b00;
S3 : hwy = RED; // 2'b00;
S4 : hwy = RED; // 2'b00;
default : hwy = GREEN; // 2'b01;
endcase
end
// cntry output
always @(*) begin
case (state)
S0 : cntry = RED; // 2'b00;
S1 : cntry = RED; // 2'b00;
S2 : cntry = RED; // 2'b00;
S3 : cntry = GREEN; // 2'b01;
S4 : cntry = YELLOW; // 2'b10;
default : cntry = RED; // 2'b00;
endcase
end
endmodule
※ testbench에서만 forever, repeat를 쓰는 것을 권하기 때문에 RTL에서는 forever, repeat를 쓰지 않는다.
* TestBench
`timescale 1ns/1ps
`define TRUE 1'b1
`define FALSE 1'b0
// 차가 간선도로에 도착했을 때 교통 신호가 올바르게 작동하는 지 검사
module tb_sig_control;
wire [1:0] MAIN_SIG, CNTRY_SIG;
reg CAR_ON_CNTRY_RD; // 참이면 간선도로에 차가 있음
reg CLOCK, CLEAR;
// 신호 제어기 파생
sig_control SC(MAIN_SIG, CNTRY_SIG, CAR_ON_CNTRY_RD, CLOCK, CLEAR);
// 모니터 구성
initial
$monitor($time, " Main Sig = %b Country Sig = %b Car_on_cntry = %d",
MAIN_SIG, CNTRY_SIG, CAR_ON_CNTRY_RD);
// 클럭의 구성
initial
begin
CLOCK = `FALSE;
forever #5 CLOCK = ~CLOCK;
end
// 클럭의 구성2
/* initial begin
CLOCK = `FALSE;
end
always #5 CLOCK = ~CLOCK; */
// clear 신호의 제어
initial
begin
CLEAR = `TRUE;
repeat(5) @(negedge CLOCK); // #(50);
CLEAR = `FALSE;
end
// 스티뮬러스 적용
initial
begin
CAR_ON_CNTRY_RD = `FALSE; // 1'b0
repeat(20) @(negedge CLOCK); // #(200);
CAR_ON_CNTRY_RD = `TRUE;
repeat(10) @(negedge CLOCK); // #(100);
CAR_ON_CNTRY_RD = `FALSE;
repeat(20) @(negedge CLOCK); // #(200);
CAR_ON_CNTRY_RD = `TRUE;
repeat(10) @(negedge CLOCK); // #(100);
CAR_ON_CNTRY_RD = `FALSE;
repeat(10) @(negedge CLOCK); // #(100);
$stop;
end
endmodule
repeat(20) @(negedge CLOCK);
CLOCK의 하향 엣지(negedge)를 20번 반복하라! 라는 의미이다.
forever #5 CLOCK = ~CLOCK; 는
CLOCK 신호가 5ns마다 0과 1을 반복한다는 코드로, CLOCK의 주기가 10ns라는 것을 알 수 있다.
즉, 하향 엣지를 한 번 반복하면 10ns가 경과한다.
그러므로 하향 엣지를 20번 반복하면 200ns가 경과한다.
출력 결과
0ns : X
5ns : CLR -> S0
200ns : X=1
205ns : S1
215ns : S2
225ns : S3
300ns : X=0
305ns : S4
315ns : S0
500ns : X=1
... 반복
- 참고 -
Verilog HDL 디지털 설계와 합성의 길잡이 (한국어판)
https://disasmain.tistory.com/84
'Verilog HDL' 카테고리의 다른 글
[ModelSim] 프로그램 내의 필요한 창이 없어졌을 때 해결법 (0) | 2021.09.29 |
---|---|
순차회로와 FSM (0) | 2021.08.23 |
[조합회로] 4비트 전가산기 설계하기 (0) | 2021.07.28 |
[조합회로] 4:1 멀티플렉서 설계하기 (0) | 2021.07.28 |
[ModelSim] Verilog 조합회로 설계 방법 (0) | 2021.07.28 |