작성자 없음
작성자 정보가 삭제된 글입니다.
23.12.02 03:56 작성
·
565
0
안녕하세요? 대학교 과제로 Up and Down game을 만들어보려고 코드를 짜봤는데 모델심에서 시뮬레이션을 돌리면 에러가 떠서 이렇게 도움을 받고자..질문드립니다 동작만 가능하게 만들면 되어서 마음껏 수정하셔도 괜찮아요 (뭔가 제가 짠 게 비효율적인 것 같아서요..)
아래는 제가 짠 코드들 이구요, 전체적인 동작은 다음과 같습니다. 1. State0에서 module LSFR을 불러와서 난수 rnd를 저장하고 State1로 넘어간다. 2. State1에서는 사용자에게 fpga보드의 스위치를 통해 4비트의 이진수 sw을 입력받고 bcd에 저장한다. 그러고나서 module bcd_seven을 불러와서 fpga보드의 숫자판에 seven을 출력하고 State2로 넘어간다. 3. State3는 rnd와 bcd 값을 비교하는 부분이다. 만약 rnd > bcd인 경우, led 에서 Red 불빛을 키고 다시 State1로 간다. 그렇지 않고 만약 rnd < bcd인 경우, led에서 Blue 불빛을 키고 State1로 간다. 그렇지 않고 rnd = bcd인 경우, led에서 Green 불빛을 키고 다시 State0으로 간다.
ㄱ. 사용자로부터 입력받은 4bit 스위치 값을 fpga보드 위에 숫자판에 0~9까지의 숫자로 표시하는 bcd_seven 모듈
`timescale 1ns/1ns
module bcd_seven
input [3:0] bcd;
output [6:0] seven;
reg [6:0] seven;
always @(bcd)
begin
case (bcd)
4'b0000 : seven = 7'b0111111;
4'b0001 : seven = 7'b0000110;
4'b0010 : seven = 7'b1011011;
4'b0011 : seven = 7'b1001111;
4'b0100 : seven = 7'b1100110;
4'b0101 : seven = 7'b1101101;
4'b0110 : seven = 7'b1111101;
4'b0111 : seven = 7'b0000111;
4'b1000 : seven = 7'b1111111;
4'b1001 : seven = 7'b1101111;
default : seven = 7'b0000000;
endcase
end
endmodule
ㄴ. 0~9까지의 숫자 중 하나를 랜덤으로 뽑아 rnd에 저장하는 LSFR 모듈
`timescale 1ns/1ns
module LFSR (input clk, input rst, output [3:0] rnd);
reg [3:0] random, random_next, random_done;
reg [2:0] count, count_next;
wire feedback = random[3] ^ random[2];
always @(posedge clk or posedge rst) begin
if (rst) begin
random <= 4'hF;
count <= 0;
end
else if (count == 3) begin
count <= 0;
// if (random < 10) // Limit the range to 0 to 9
random_done <= random % 10;
end
else begin
random <= random_next;
count <= count_next;
end
end
always @(*) begin
random_next = random;
count_next = count;
random_next = {random[2:0], feedback};
count_next = count + 1;
end
assign rnd = random_done;
endmodule
ㄷ. rnd와 bcd 값을 비교해서 led 불빛을 표시하는 Upanddown 모듈
`timescale 1ns/1ns
module Upanddown (
input clk,
input rst,
input [3:0] sw,
output reg red_led,
output reg blue_led,
output reg green_led
);
reg [3:0] rnd;
reg [3:0] bcd;
reg [1:0] state, next_state;
// Instantiate LSFR and bcd_seven modules
LSFR lsfr_inst (
.clk(clk),
.rst(rst),
.rnd(rnd)
);
bcd_seven bcd_seven_inst (
.bcd(sw),
.seven()
);
always @(posedge clk or posedge rst) begin
if (rst) begin
state <= 2'b00; // Initial state: State0
end else begin
state <= next_state;
end
end
always @(posedge clk) begin
case (state)
2'b00: begin
// State0: Generate rnd using LSFR
lsfr_inst; // Call LSFR module
rnd <= lsfr_inst.rnd; // Store the generated rnd
next_state = 2'b01; // Move to State1
end
2'b01: begin
// State1: Get user input from switch and display on 7-segment display
bcd_seven_inst.bcd <= sw;
bcd_seven_inst.seven(); // Call bcd_seven module
bcd <= bcd_seven_inst.bcd;
next_state = 2'b10; // Move to State2
end
2'b10: begin
// State2: Compare rnd and user input, update LEDs, and go to the next state
if (rnd > bcd) begin
red_led = 1;
blue_led = 0;
green_led = 0;
next_state = 2'b01; // Move to State1
end else if (rnd < bcd) begin
red_led = 0;
blue_led = 1;
green_led = 0;
next_state = 2'b01; // Move to State1
end else begin
red_led = 0;
blue_led = 0;
green_led = 1;
next_state = 2'b00; // Move to State0
end
end
default: begin
next_state = 2'b00; // Default: Move to State0
end
endcase
end
endmodule
ㄹ. rnd>bcd, rnd<bcd, rnd=bcd 등 전체적인 동작을 확인할 수 있는 테스트벤치
`timescale 1ns/1ns
module Upanddown_Tb;
reg clk;
reg rst;
reg [3:0] sw;
wire red_led, blue_led, green_led;
// Instantiate Upanddown module
Upanddown upanddown_inst (
.clk(clk),
.rst(rst),
.sw(sw),
.red_led(red_led),
.blue_led(blue_led),
.green_led(green_led)
);
// Clock generation
initial begin
clk = 0;
forever #5 clk = ~clk;
end
// Initial values
initial begin
rst = 1;
sw = 4'b0000;
// Apply reset
#10 rst = 0;
// Scenario 1: rnd > bcd
#20 sw = 4'b0010; // User input: 0010
#30 $display("Scenario 1: rnd > bcd, Expect Red LED: %0d, Blue LED: %0d, Green LED: %0d", red_led, blue_led, green_led);
// Scenario 2: rnd < bcd
#40 sw = 4'b1001; // User input: 1001
#50 $display("Scenario 2: rnd < bcd, Expect Red LED: %0d, Blue LED: %0d, Green LED: %0d", red_led, blue_led, green_led);
// Scenario 3: rnd = bcd
#60 sw = 4'b1101; // User input: 1101
#70 $display("Scenario 3: rnd = bcd, Expect Red LED: %0d, Blue LED: %0d, Green LED: %0d", red_led, blue_led, green_led);
#100 $finish; // End simulation after some time
end
endmodule
답변 1
0
안녕하세요, 인프런 AI 인턴입니다. gdwkld0324님, Verilog 코드 질문에 답변드리겠습니다.
모델심 시뮬레이션이 에러를 발생시킨 원인은 구체적인 에러 메시지를 보지 않고 정확히 파악하기 어렵지만, 제공해주신 코드를 기반으로 몇 가지 잠재적 문제점에 대해 말씀드릴 수 있습니다:
Module 인스턴스 호출 방식이 올바르지 않습니다.
Verilog에서 module을 호출할 때는 함수처럼 호출할 수 없습니다. inst_name.module_name(); 같은 형식은 올바른 Verilog 문법이 아닙니다.
대신 아래와 같이 module을 정의하고 ports를 연결하여 인스턴스를 생성합니다:
lsfr lsfr_inst(
.clk(clk),
.rst(rst),
.rnd(rnd)
);
State 머신 설계에 문제가 보입니다.
현재 상태를 바탕으로 다음 상태 및 LED를 설정하는 모든 로직이 posedge clk만 확인하고 있습니다. always @(posedge clk)
블록을 사용하여 이러한 처리를 하도록 수정해야 합니다. 상태 변경을 위해 민감한 신호들을 항상 블록의 트리거에 포함시켜야 합니다.
비동기적 리셋의 사용 (posedge 블록에 rst 신호가 포함되어 있는 경우)
rst 신호를 비동기 리셋으로 사용하려면 다음과 같이 모든 always 블록에 포함시켜야 합니다:
always @(posedge clk or posedge rst) begin
if (rst) begin
// reset logic
end else begin
// normal logic
end
end
위의 조건으로 초기 상태 설정 및 기기 상태의 리셋을 포함시킬 수 있습니다.
Upanddown 모듈 내의 LSFR 모듈과 bcd_seven 모듈 인스턴스가 중첩된 always 블록에서 등장하지 않아야 합니다. 여기서 모듈 인스턴스는 상위 블록 안에 한 번만 선언되어야 합니다.
시뮬레이션 명령인 $display 문은 모듈의 내부 로직이 아니라 testbench에서 결과를 출력하기 위한 용도로 사용됩니다. 저 결과 메시지들은 Upanddown 모듈 자체에 있어서는 안 되고 Upanddown_Tb 내에서만 사용되어야 합니다.
이 외에도 세부 로직에 문제가 있을 수 있으니 구체적 에러 메시지에 따라 추가적인 디버깅이 필요합니다.
위 사항들을 검토하여 코드 수정을 진행해보세요. 왕초보 대학교 과제를 잘 마무리하시길 바랍니다. Verilog 코딩에서 더 궁금한 점이 있으시다면 다시 질문해주시기 바랍니다.