Following code may be useful for students or enthusiasts who are trying to design a voting machine. It has been successfully simulated as well as implemented on Spartan 3 xc3s400 FPGA. If you are having any doubts regarding following code then post a comment. I will try my best to answer the questions.
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Engineer: Chaitannya Supe // Create Date: 09:31:19 03/08/2015 // Design Name: Electronic Voting Machine // Module Name: evm // Target Devices: Xilinx Spartan 3 XCS400-PQ208 // Tool versions: Xilinx ISE 12.2, 14.7 // Description: This is simple Voting machine code in which total 3 partys were considered. // A voter can vote to any of the parties only one at a time. If a voter votes two parties // at a time then that vote will be invalid. This code has been successfully simulated as well as // implemented on Spartan 3 xc3s400-4pq208 device. // // Additional Comments: To register a vote, operate a voter_switch and then press push button to register // a vote. This operation was chosen to simplify a coding and get better understanding // of a voting machine on FPGA. ////////////////////////////////////////////////////////////////////////////////// module evm(clk,voter_switch,PB,voting_en,opled,invalid,dout); input voting_en,PB,clk;//voting process will start when vote_en is on input [2:0]voter_switch; output [6:0]dout;//Max no. of votes = 127 output reg [2:0]opled;//opled[0]=party1 led, opled[1]=party2 led, opled[2]=party3 led output reg invalid;//invalid vote indicator led //counters to count each party votes reg [6:0]cnt_reg1=0;//party1 reg [6:0]cnt_nxt1=0;//party1 reg [6:0]cnt_reg2=0;//party2 reg [6:0]cnt_nxt2=0;//party2 reg [6:0]cnt_reg3=0;//party3 reg [6:0]cnt_nxt3=0;//party3 reg PB_reg1; reg PB_reg2; reg [15:0] PB_cnt; reg PB_state; //debounce circuit to detect only one rising edge of push button PB(Refer http://www.fpga4fun.com/Debouncer2.html for more information on debounce circuit) always @(posedge clk) PB_reg1 <= PB; always @(posedge clk) PB_reg2 <= PB_reg1; wire PB_idle = (PB_state==PB_reg2); wire PB_cnt_max = &PB_cnt; // true when all bits of PB_cnt are 1's always @(posedge clk) if(PB_idle) PB_cnt <= 0; // idle state i.e. PB_cnt will not increment else begin PB_cnt <= PB_cnt + 16'd1; if(PB_cnt_max) PB_state <= ~PB_state; // if the counter is maximum, PB changes end assign PB_down = ~PB_idle & PB_cnt_max & ~PB_state; //counter for party1 votes always@(posedge PB_down) if(voter_switch == 3'b001 && voting_en == 1'b1) begin cnt_reg1 <= cnt_nxt1; end always@(*) begin cnt_nxt1 = cnt_reg1 + 1; end //Counter for party2 votes always@(posedge PB_down) if(voter_switch == 3'b010 && voting_en == 1'b1) begin cnt_reg2 <= cnt_nxt2; end always@(*) begin cnt_nxt2 = cnt_reg2 + 1; end //Counter for party3 votes always@(posedge PB_down) if(voter_switch == 3'b100 && voting_en == 1'b1) begin cnt_reg3 <= cnt_nxt3; end always@(*) begin cnt_nxt3 = cnt_reg3 + 1; end //Final count i.e. total number of votes assign dout = cnt_reg1 + cnt_reg2 + cnt_reg3; //relation of "voter_switch" with "opled" & "invalid" always@(*) if(voting_en) case(voter_switch) 3'b100 : begin opled = 3'b100; invalid = 1'b0; end 3'b010 : begin opled = 3'b010; invalid = 1'b0; end 3'b001 : begin opled = 3'b001; invalid = 1'b0; end 3'b011 : begin opled = 3'b000; invalid = 1'b1; end 3'b110 : begin opled = 3'b000; invalid = 1'b1; end 3'b101 : begin opled = 3'b000; invalid = 1'b1; end 3'b111 : begin opled = 3'b000; invalid = 1'b1; end 3'b000 : begin opled = 3'b000; invalid = 1'b0; end default : begin opled = 3'b000; invalid = 1'b0; end endcase endmodule