Last active
April 8, 2017 17:40
-
-
Save KeitetsuWorks/ac50fd695bbde7ac2bdf5e2dffbada19 to your computer and use it in GitHub Desktop.
FPGA / Verilog-HDL入門 - スロットマシンの設計
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
`define max 2 | |
`define length 22 | |
module slot_machine(clk, sw, btn0, btn1, btn2, led7_0, led7_1, led7_2, led10); | |
input clk, sw, btn0, btn1, btn2; | |
output [6:0] led7_0, led7_1, led7_2; | |
output [9:0] led10; | |
reg [1:0] state; | |
reg en_0, en_1, en_2; | |
reg [1:0] cnt; | |
wire clk_local; | |
wire rst; | |
wire en_led10; | |
wire [2:0] cout_0, cout_1, cout_2; | |
parameter init = 2'b00; | |
parameter slot_start0 = 2'b01; | |
parameter slot_start1 = 2'b11; | |
parameter slot_wait = 2'b10; | |
clk_generator uclk_generator(.clk(clk), .rst(rst), .clk_local(clk_local)); | |
counter ucounter_0(.clk(clk_local), .rst(rst), .en(en_0), .cout(cout_0)); | |
counter ucounter_1(.clk(clk_local), .rst(rst), .en(en_1), .cout(cout_1)); | |
counter ucounter_2(.clk(clk_local), .rst(rst), .en(en_2), .cout(cout_2)); | |
decoder udecoder_0(.din(cout_0), .led7(led7_0)); | |
decoder udecoder_1(.din(cout_1), .led7(led7_1)); | |
decoder udecoder_2(.din(cout_2), .led7(led7_2)); | |
led10 uled10(.clk(clk_local), .rst(rst), .en(en_led10), .led10(led10)); | |
assign rst = sw; | |
assign en_led10 = ((state == slot_wait) & ~en_0 & ~en_1 & ~en_2 & (cout_0 == cout_1) & (cout_0 == cout_2)) ? 1'b1 : 1'b0; | |
always @(negedge clk_local or posedge rst) begin | |
if(rst == 1'b1) begin | |
en_0 <= 1'b0; | |
en_1 <= 1'b0; | |
en_2 <= 1'b0; | |
cnt <= 2'd0; | |
state <= init; | |
end | |
else begin | |
case(state) | |
init: begin | |
if(rst == 1'b0) begin | |
en_0 <= 1'b1; | |
en_1 <= 1'b0; | |
en_2 <= 1'b0; | |
cnt <= 2'd0; | |
state <= slot_start0; | |
end | |
else begin | |
en_0 <= 1'b0; | |
en_1 <= 1'b0; | |
en_2 <= 1'b0; | |
state <= state; | |
end | |
end | |
slot_start0: begin | |
if(cnt == `max - 1) begin | |
en_0 <= 1'b1; | |
en_1 <= 1'b1; | |
en_2 <= 1'b0; | |
cnt <= 2'd0; | |
state <= slot_start1; | |
end | |
else begin | |
cnt <= cnt + 2'd1; | |
state <= state; | |
end | |
end | |
slot_start1: begin | |
if(cnt == `max - 1) begin | |
en_0 <= 1'b1; | |
en_1 <= 1'b1; | |
en_2 <= 1'b1; | |
cnt <= 2'd0; | |
state <= slot_wait; | |
end | |
else begin | |
cnt <= cnt + 2'd1; | |
state <= state; | |
end | |
end | |
slot_wait: begin | |
if(btn0 == 1'b0) begin | |
en_0 <= 1'b0; | |
end | |
if(btn1 == 1'b0) begin | |
en_1 <= 1'b0; | |
end | |
if(btn2 == 1'b0) begin | |
en_2 <= 1'b0; | |
end | |
state <= state; | |
end | |
endcase | |
end | |
end | |
endmodule | |
module decoder(din, led7); | |
input [2:0] din; | |
output [6:0] led7; | |
assign led7 = decoder_func(din); | |
function [6:0] decoder_func; | |
input [2:0] din; | |
case(din) | |
3'd0: decoder_func = 7'b1000000; | |
3'd1: decoder_func = 7'b1111001; | |
3'd2: decoder_func = 7'b0100100; | |
3'd3: decoder_func = 7'b0110000; | |
3'd4: decoder_func = 7'b0011001; | |
3'd5: decoder_func = 7'b0010010; | |
3'd6: decoder_func = 7'b0000011; | |
3'd7: decoder_func = 7'b1111000; | |
default: decoder_func = 7'b0111111; | |
endcase | |
endfunction | |
endmodule | |
module led10(clk, rst, en, led10); | |
input clk, rst, en; | |
output [9:0] led10; | |
reg [9:0] led10; | |
reg led10_state; | |
parameter led10_init = 1'b0; | |
parameter led10_func0 = 1'b1; | |
always @(negedge clk or posedge rst) begin | |
if(rst == 1'b1) begin | |
led10 <= 10'b0000000000; | |
led10_state <= led10_init; | |
end | |
else if(en == 1'b1) begin | |
case(led10_state) | |
led10_init: begin | |
led10 <= 10'b0101010101; | |
led10_state <= led10_func0; | |
end | |
led10_func0: begin | |
led10 <= led10 ^ 10'b1111111111; | |
led10_state <= led10_state; | |
end | |
endcase | |
end | |
end | |
endmodule | |
module counter(clk, rst, en, cout); | |
input clk; | |
input rst; | |
input en; | |
output [2:0] cout; | |
reg [2:0] cout; | |
always @(posedge clk or posedge rst) begin | |
if(rst == 1'b1) begin | |
cout <= 3'd0; | |
end | |
else if(en == 1'b1) begin | |
if(cout == 3'd7) begin | |
cout <= 3'd0; | |
end | |
else begin | |
cout <= cout + 3'd1; | |
end | |
end | |
end | |
endmodule | |
module clk_generator(clk, rst, clk_local); | |
input clk; | |
input rst; | |
output clk_local; | |
reg [`length - 1:0] cnt; | |
assign clk_local = cnt[`length - 1]; | |
always @(posedge clk or posedge rst) begin | |
if(rst == 1'b1) begin | |
cnt <= `length'd0; | |
end | |
else begin | |
cnt <= cnt + `length'd1; | |
end | |
end | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment