Last active
December 21, 2020 07:23
-
-
Save mb2532/c5179e14e4bc3c891b32828834821ff4 to your computer and use it in GitHub Desktop.
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
//Top Level AI Compute Module: | |
//gamestate bits: 00 = empty, 01 = AI move, 10 = user move | |
module connectFourAI( | |
input [83:0] gameState, | |
output [3:0] aiMove, | |
output [4:0] maxConnectOut, | |
input clk, reset | |
); | |
wire [3:0] move [7:0]; | |
wire [4:0] foundMax [7:0]; | |
wire [83:0] nextState [6:0]; | |
wire disable_column [6:0]; | |
wire [3:0] trapMove [7:0]; | |
//Instantiate 7 genStateFromColumns to create 7 new gameState values for an AI move in each column | |
genStateFromColumn genMove0( | |
.column (4'd0), | |
.gameState (gameState), | |
.player (2'b01), | |
.nextState (nextState[0]), | |
.disable_column (disable_column[0]) | |
); | |
genStateFromColumn genMove1( | |
.column (4'd1), | |
.gameState (gameState), | |
.player (2'b01), | |
.nextState (nextState[1]), | |
.disable_column (disable_column[1]) | |
); | |
genStateFromColumn genMove2( | |
.column (4'd2), | |
.gameState (gameState), | |
.player (2'b01), | |
.nextState (nextState[2]), | |
.disable_column (disable_column[2]) | |
); | |
genStateFromColumn genMove3( | |
.column (4'd3), | |
.gameState (gameState), | |
.player (2'b01), | |
.nextState (nextState[3]), | |
.disable_column (disable_column[3]) | |
); | |
genStateFromColumn genMove4( | |
.column (4'd4), | |
.gameState (gameState), | |
.player (2'b01), | |
.nextState (nextState[4]), | |
.disable_column (disable_column[4]) | |
); | |
genStateFromColumn genMove5( | |
.column (4'd5), | |
.gameState (gameState), | |
.player (2'b01), | |
.nextState (nextState[5]), | |
.disable_column (disable_column[5]) | |
); | |
genStateFromColumn genMove6( | |
.column (4'd6), | |
.gameState (gameState), | |
.player (2'b01), | |
.nextState (nextState[6]), | |
.disable_column (disable_column[6]) | |
); | |
//instantiate 7 moveDeterminers to compute a heuristic value for each of the new gameStates | |
moveDeterminer findImmediateMove( | |
.gameState (gameState), | |
.clk (clk), | |
.disable_column (1'b0), | |
.player (2'b01), | |
.foundMax (foundMax[7]), | |
.move (move[7]) | |
); | |
moveDeterminer findMove0( | |
.gameState (nextState[0]), | |
.clk (clk), | |
.disable_column (disable_column[0]), | |
.player (2'b10), | |
.foundMax (foundMax[0]), | |
.move (move[0]) | |
); | |
moveDeterminer findMove1( | |
.gameState (nextState[1]), | |
.clk (clk), | |
.disable_column (disable_column[1]), | |
.player (2'b10), | |
.foundMax (foundMax[1]), | |
.move (move[1]) | |
); | |
moveDeterminer findMove2( | |
.gameState (nextState[2]), | |
.clk (clk), | |
.disable_column (disable_column[2]), | |
.player (2'b10), | |
.foundMax (foundMax[2]), | |
.move (move[2]) | |
); | |
moveDeterminer findMove3( | |
.gameState (nextState[3]), | |
.clk (clk), | |
.disable_column (disable_column[3]), | |
.player (2'b10), | |
.foundMax (foundMax[3]), | |
.move (move[3]) | |
); | |
moveDeterminer findMove4( | |
.gameState (nextState[4]), | |
.clk (clk), | |
.disable_column (disable_column[4]), | |
.player (2'b10), | |
.foundMax (foundMax[4]), | |
.move (move[4]) | |
); | |
moveDeterminer findMove5( | |
.gameState (nextState[5]), | |
.clk (clk), | |
.disable_column (disable_column[5]), | |
.player (2'b10), | |
.foundMax (foundMax[5]), | |
.move (move[5]) | |
); | |
moveDeterminer findMove6( | |
.gameState (nextState[6]), | |
.clk (clk), | |
.disable_column (disable_column[6]), | |
.player (2'b10), | |
.foundMax (foundMax[6]), | |
.move (move[6]) | |
); | |
//find the minimum of the moveDeterminer max output values | |
wire [4:0] min; | |
findMinimum minFinder( | |
.in0 (foundMax[0]), | |
.in1 (foundMax[1]), | |
.in2 (foundMax[2]), | |
.in3 (foundMax[3]), | |
.in4 (foundMax[4]), | |
.in5 (foundMax[5]), | |
.in6 (foundMax[6]), | |
.out (min) | |
); | |
//instantiate seven trap determiners to look for 2-move-ahead traps in parallel with move determiners | |
trapDeterminer trap0( | |
.gameState (nextState[0]), | |
.player (2'b01), | |
.clk (clk), | |
.disable_column (disable_column[0]), | |
.move (trapMove[0]) | |
); | |
trapDeterminer trap1( | |
.gameState (nextState[1]), | |
.player (2'b01), | |
.clk (clk), | |
.disable_column (disable_column[1]), | |
.move (trapMove[1]) | |
); | |
trapDeterminer trap2( | |
.gameState (nextState[2]), | |
.player (2'b01), | |
.clk (clk), | |
.disable_column (disable_column[2]), | |
.move (trapMove[2]) | |
); | |
trapDeterminer trap3( | |
.gameState (nextState[3]), | |
.player (2'b01), | |
.clk (clk), | |
.disable_column (disable_column[3]), | |
.move (trapMove[3]) | |
); | |
trapDeterminer trap4( | |
.gameState (nextState[4]), | |
.player (2'b01), | |
.clk (clk), | |
.disable_column (disable_column[4]), | |
.move (trapMove[4]) | |
); | |
trapDeterminer trap5( | |
.gameState (nextState[5]), | |
.player (2'b01), | |
.clk (clk), | |
.disable_column (disable_column[5]), | |
.move (trapMove[5]) | |
); | |
trapDeterminer trap6( | |
.gameState (nextState[6]), | |
.player (2'b01), | |
.clk (clk), | |
.disable_column (disable_column[6]), | |
.move (trapMove[6]) | |
); | |
//AI Out Logic | |
wire [3:0] minMove; | |
wire [3:0] trapMoveFlag; | |
wire allFull; | |
//check if the board is full | |
assign allFull = (foundMax[0] == 5'd31) && (foundMax[1] == 5'd31) && (foundMax[2] == 5'd31) && (foundMax[3] == 5'd31) && (foundMax[4] == 5'd31) && (foundMax[5] == 5'd31) && (foundMax[6] == 5'd31); | |
//check to see if a trap has been detected, if so assign flag value of that move column, if not assign to value of 7; if multiple, prioritize middle columns | |
assign trapMoveFlag = (trapMove[3] != 4'd7 ? 4'd3 : (trapMove[2] != 4'd7 ? 4'd2 : (trapMove[4] != 4'd7 ? 4'd4 : (trapMove[5] != 4'd7 ? 4'd5 : (trapMove[1] != 4'd7 ? 4'd1 : (trapMove[6] != 4'd7 ? 4'd6 : 4'd7)))))); | |
//assign to best move column as determined by moveDeterminers | |
assign minMove = (min==foundMax[3]? 4'd3 :(min==foundMax[2]? 4'd2 :(min==foundMax[4]? 4'd4 :(min==foundMax[1]? 4'd1 :(min==foundMax[5]? 4'd5:(min==foundMax[0]? 4'd0 : 4'd6)))))); | |
//assign AI module output move, if a priority check or only one space left, assign to output of moveDeterminer 7, if not, check for trap moves, if not, assign to minMove | |
assign aiMove = (foundMax[7]>=15 || (allFull == 1'b1)) ? move[7] : ((trapMoveFlag != 4'd7 && foundMax[trapMoveFlag] < 5'd15)? trapMoveFlag : minMove); | |
//assign to value of max heuristic | |
assign maxConnectOut = (foundMax[7]>=5'd15 || (allFull == 1'b1)) ? foundMax[7] : min; | |
endmodule | |
//moveDeterminer module: outputs heuristic maximum value and corresponding move given gameState | |
module moveDeterminer( | |
input [83:0] gameState, | |
input [1:0] player, | |
input clk, disable_column, | |
output [4:0] foundMax, | |
output [3:0] move | |
); | |
wire [13:0] row0; | |
wire [13:0] row1; | |
wire [13:0] row2; | |
wire [13:0] row3; | |
wire [13:0] row4; | |
wire [13:0] row5; | |
assign row0 = gameState[13:0]; | |
assign row1 = gameState[27:14]; | |
assign row2 = gameState[41:28]; | |
assign row3 = gameState[55:42]; | |
assign row4 = gameState[69:56]; | |
assign row5 = gameState[83:70]; | |
wire [4:0] maxConnect [6:0]; | |
//instantiate seven maxConnectFinder modules, one for each possible play | |
maxConnectFinder col0( | |
.clk (clk), | |
.player (player), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd0), | |
.maxConnect (maxConnect[0]) | |
); | |
maxConnectFinder col1( | |
.clk (clk), | |
.player (player), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd1), | |
.maxConnect (maxConnect[1]) | |
); | |
maxConnectFinder col2( | |
.clk (clk), | |
.player (player), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd2), | |
.maxConnect (maxConnect[2]) | |
); | |
maxConnectFinder col3( | |
.clk (clk), | |
.player (player), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd3), | |
.maxConnect (maxConnect[3]) | |
); | |
maxConnectFinder col4( | |
.clk (clk), | |
.player (player), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd4), | |
.maxConnect (maxConnect[4]) | |
); | |
maxConnectFinder col5( | |
.clk (clk), | |
.player (player), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd5), | |
.maxConnect (maxConnect[5]) | |
); | |
maxConnectFinder col6( | |
.clk (clk), | |
.player (player), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd6), | |
.maxConnect (maxConnect[6]) | |
); | |
//take the maximum value of the seven maxConnectFinders | |
wire [4:0] foundMax_temp; | |
findMaximum findmax( | |
.in0 (maxConnect[0]), | |
.in1 (maxConnect[1]), | |
.in2 (maxConnect[2]), | |
.in3 (maxConnect[3]), | |
.in4 (maxConnect[4]), | |
.in5 (maxConnect[5]), | |
.in6 (maxConnect[6]), | |
.out (foundMax_temp) | |
); | |
//if the column is disabled, assign to either max or min value depending on if AI or human, if not assign to maximum heuristic value | |
assign foundMax = (disable_column == 1'b1) ? (player == 2'b10 ? 5'd31 : 5'd0) : foundMax_temp; | |
//assign move to corresponding column | |
assign move = (foundMax==maxConnect[3]? 4'd3 : (foundMax==maxConnect[2]? 4'd2 : (foundMax==maxConnect[4]? 4'd4 : (foundMax==maxConnect[1]? 4'd1 : (foundMax==maxConnect[5]? 4'd5 : (foundMax==maxConnect[0]? 4'd0 : 4'd6)))))); | |
endmodule | |
//trapDeterminer module: look ahead to see if an AI win is possible after a human player block of an immediate AI win | |
module trapDeterminer( | |
input [83:0] gameState, | |
input [1:0] player, | |
input clk, disable_column, | |
output [3:0] move | |
); | |
wire [13:0] row0; | |
wire [13:0] row1; | |
wire [13:0] row2; | |
wire [13:0] row3; | |
wire [13:0] row4; | |
wire [13:0] row5; | |
wire [13:0] row0N; | |
wire [13:0] row1N; | |
wire [13:0] row2N; | |
wire [13:0] row3N; | |
wire [13:0] row4N; | |
wire [13:0] row5N; | |
assign row0 = gameState[13:0]; | |
assign row1 = gameState[27:14]; | |
assign row2 = gameState[41:28]; | |
assign row3 = gameState[55:42]; | |
assign row4 = gameState[69:56]; | |
assign row5 = gameState[83:70]; | |
wire selfWin [6:0]; | |
//instantiate seven winFinders to look for an immediate AI win that the human player will block | |
winFinder win0( | |
.clk (clk), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd0), | |
.selfWin (selfWin[0]) | |
); | |
winFinder win1( | |
.clk (clk), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd1), | |
.selfWin (selfWin[1]) | |
); | |
winFinder win2( | |
.clk (clk), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd2), | |
.selfWin (selfWin[2]) | |
); | |
winFinder win3( | |
.clk (clk), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd3), | |
.selfWin (selfWin[3]) | |
); | |
winFinder win4( | |
.clk (clk), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd4), | |
.selfWin (selfWin[4]) | |
); | |
winFinder win5( | |
.clk (clk), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd5), | |
.selfWin (selfWin[5]) | |
); | |
winFinder win6( | |
.clk (clk), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd6), | |
.selfWin (selfWin[6]) | |
); | |
//assign user move to column of AI win, otherwise assign to 7 | |
wire [3:0] userMove; | |
assign userMove = (disable_column == 1'b1 ? 4'd7 : (selfWin[3]==1'b1 ? 4'd3 : (selfWin[2] == 1'b1 ? 4'd2 : (selfWin[4] == 1'b1 ? 4'd4 : (selfWin[1] == 1'b1 ? 4'd1 : (selfWin[5] == 1'b1 ? 4'd5 : (selfWin[0] == 1'b1 ? 4'd0 : (selfWin[6] == 1'b1 ? 4'd6 : 4'd7)))))))); | |
//generate a new gameState from predicted user move | |
wire [83:0] trapState ; | |
wire tempDisable; | |
genStateFromColumn genTrapMove( | |
.column (userMove), | |
.gameState (gameState), | |
.player (2'b10), | |
.nextState (trapState), | |
.disable_column (tempDisable) | |
); | |
assign row0N = trapState[13:0]; | |
assign row1N = trapState[27:14]; | |
assign row2N = trapState[41:28]; | |
assign row3N = trapState[55:42]; | |
assign row4N = trapState[69:56]; | |
assign row5N = trapState[83:70]; | |
//instantiate seven more winFinders to look for a subsequent AI win | |
wire selfWinN [6:0]; | |
winFinder win0N( | |
.clk (clk), | |
.row0 (row0N), | |
.row1 (row1N), | |
.row2 (row2N), | |
.row3 (row3N), | |
.row4 (row4N), | |
.row5 (row5N), | |
.moveColumn (4'd0), | |
.selfWin (selfWinN[0]) | |
); | |
winFinder win1N( | |
.clk (clk), | |
.row0 (row0N), | |
.row1 (row1N), | |
.row2 (row2N), | |
.row3 (row3N), | |
.row4 (row4N), | |
.row5 (row5N), | |
.moveColumn (4'd1), | |
.selfWin (selfWinN[1]) | |
); | |
winFinder win2N( | |
.clk (clk), | |
.row0 (row0N), | |
.row1 (row1N), | |
.row2 (row2N), | |
.row3 (row3N), | |
.row4 (row4N), | |
.row5 (row5N), | |
.moveColumn (4'd2), | |
.selfWin (selfWinN[2]) | |
); | |
winFinder win3N( | |
.clk (clk), | |
.row0 (row0N), | |
.row1 (row1N), | |
.row2 (row2N), | |
.row3 (row3N), | |
.row4 (row4N), | |
.row5 (row5N), | |
.moveColumn (4'd3), | |
.selfWin (selfWinN[3]) | |
); | |
winFinder win4N( | |
.clk (clk), | |
.row0 (row0N), | |
.row1 (row1N), | |
.row2 (row2N), | |
.row3 (row3N), | |
.row4 (row4N), | |
.row5 (row5N), | |
.moveColumn (4'd4), | |
.selfWin (selfWinN[4]) | |
); | |
winFinder win5N( | |
.clk (clk), | |
.row0 (row0N), | |
.row1 (row1N), | |
.row2 (row2N), | |
.row3 (row3N), | |
.row4 (row4N), | |
.row5 (row5N), | |
.moveColumn (4'd5), | |
.selfWin (selfWinN[5]) | |
); | |
winFinder win6N( | |
.clk (clk), | |
.row0 (row0N), | |
.row1 (row1N), | |
.row2 (row2N), | |
.row3 (row3N), | |
.row4 (row4N), | |
.row5 (row5N), | |
.moveColumn (4'd6), | |
.selfWin (selfWinN[6]) | |
); | |
//output user move if any of the new winFinders outputs a 1, otherwise output a 7 | |
assign move = (tempDisable == 1'b1) ? 4'd7 : (selfWinN[0] == 1'b1 || selfWinN[1] == 1'b1 || selfWinN[2] == 1'b1 || selfWinN[3] == 1'b1 || selfWinN[4] == 1'b1 || selfWinN[5] == 1'b1 || selfWinN[6] == 1'b1) ? userMove : 4'd7; | |
endmodule | |
//winFinder module: used to look for an AI win in gameState | |
module winFinder( | |
input [13:0] row0, row1, row2, row3, row4, row5, | |
input [3:0] moveColumn, | |
//input [3:0] moveRow, | |
input clk, | |
output selfWin | |
); | |
wire [13:0] rowArray [5:0]; | |
assign rowArray[0] = row0; | |
assign rowArray[1] = row1; | |
assign rowArray[2] = row2; | |
assign rowArray[3] = row3; | |
assign rowArray[4] = row4; | |
assign rowArray[5] = row5; | |
//assign moveRow to the row number of the next open slot in moveColumn | |
wire [3:0] moveRow; | |
assign moveRow = (row0[moveColumn<<1] + row0[(moveColumn<<1)+1] + row1[moveColumn<<1] + row1[(moveColumn<<1)+1] + row2[moveColumn<<1] + row2[(moveColumn<<1)+1] + row3[moveColumn<<1] + row3[(moveColumn<<1)+1] + row4[moveColumn<<1] + row4[(moveColumn<<1)+1] + row5[moveColumn<<1] + row5[(moveColumn<<1)+1]); | |
reg [3:0] upLeftSelf; | |
wire [3:0] upLeftSelfWire; | |
reg [3:0] upRightSelf; | |
wire [3:0] upRightSelfWire; | |
reg [3:0] leftSelf; | |
wire [3:0] leftSelfWire; | |
reg [3:0] rightSelf; | |
wire [3:0] rightSelfWire; | |
reg [3:0] botSelf; | |
wire [3:0] botSelfWire; | |
reg [3:0] botRightSelf; | |
wire [3:0] botRightSelfWire; | |
reg [3:0] botLeftSelf; | |
wire [3:0] botLeftSelfWire; | |
assign botSelfWire = botSelf; | |
assign botLeftSelfWire = botLeftSelf; | |
assign botRightSelfWire = botRightSelf; | |
assign leftSelfWire = leftSelf; | |
assign rightSelfWire = rightSelf; | |
assign upLeftSelfWire = upLeftSelf; | |
assign upRightSelfWire = upRightSelf; | |
//check for split diagonals in AI tokens | |
wire crossCheckSelf; | |
assign crossCheckSelf = ((upLeftSelfWire+botRightSelfWire)>=4'd4 || (upRightSelfWire+botLeftSelfWire)>=4'd4 || (leftSelfWire+rightSelfWire)>=4'd4) ? 1'b1 : 1'b0; | |
// assign win flag a 1 if there are any three-in-a-rows next to an empty slot | |
assign selfWin = (botSelfWire==4'd10 || botLeftSelfWire==4'd10 || botRightSelfWire==4'd10 || leftSelfWire==4'd10 || rightSelfWire==4'd10 || upLeftSelfWire == 4'd10 || upRightSelfWire ==4'd10 || crossCheckSelf==1'b1) ? 1'b1 : 1'b0; | |
always @(*) begin | |
//bottom check | |
if(moveRow == 0) botSelf = 4'd0; | |
else if((moveRow != 0) && (rowArray[moveRow-1][(moveColumn<<1)] == 1'b1)) begin //check 1 under | |
if (moveRow - 1 != 0 && rowArray[moveRow-2][(moveColumn<<1)] == 1'b1) begin //check 2 under | |
if (moveRow - 2 != 0 && rowArray[moveRow-3][(moveColumn<<1)] == 1'b1) begin //check 3 under | |
botSelf = 4'd10; | |
end | |
else botSelf = 4'd3; | |
end | |
else botSelf = 4'd1; | |
end | |
else botSelf = 4'd0; | |
//bottom left check | |
if(moveRow == 0) botLeftSelf = 4'd0; | |
else if(moveRow != 0 && moveColumn != 0 && rowArray[moveRow-1][((moveColumn-1)<<1)] == 1'b1) begin //check 1 under | |
if (moveRow - 1 != 0 && moveColumn - 1 != 0 && rowArray[moveRow-2][((moveColumn-2)<<1)] == 1'b1) begin //check 2 under | |
if (moveRow - 2 != 0 && moveColumn - 2 != 0 && rowArray[moveRow-3][((moveColumn-3)<<1)] == 1'b1) begin //check 3 under | |
botLeftSelf = 4'd10; | |
end | |
else botLeftSelf = 4'd3; | |
end | |
else botLeftSelf = 4'd1; | |
end | |
else botLeftSelf = 4'd0; | |
//bottom right check | |
if(moveRow == 0) botRightSelf = 4'd0; | |
else if(moveRow != 0 && moveColumn != 6 && rowArray[moveRow-1][((moveColumn+1)<<1)] == 1'b1) begin //check 1 under | |
if (moveRow - 1 != 0 && moveColumn + 1 != 6 && rowArray[moveRow-2][((moveColumn+2)<<1)] == 1'b1) begin //check 2 under | |
if (moveRow - 2 != 0 && moveColumn + 2 != 6 && rowArray[moveRow-3][((moveColumn+3)<<1)] == 1'b1) begin //check 3 under | |
botRightSelf = 4'd10; | |
end | |
else botRightSelf = 4'd3; | |
end | |
else botRightSelf = 4'd1; | |
end | |
else botRightSelf = 4'd0; | |
//left check | |
if(moveColumn == 0) leftSelf = 0; | |
else if(moveColumn != 0 && rowArray[moveRow][((moveColumn-1)<<1)] == 1'b1) begin //check 1 under | |
if (moveColumn - 1 != 0 && rowArray[moveRow][((moveColumn-2)<<1)] == 1'b1) begin //check 2 under | |
if (moveColumn - 2 != 0 && rowArray[moveRow][((moveColumn-3)<<1)] == 1'b1) begin //check 3 under | |
leftSelf = 4'd10; | |
end | |
else leftSelf = 4'd3; | |
end | |
else leftSelf = 4'd1; | |
end | |
else leftSelf = 4'd0; | |
//right check | |
if(moveColumn == 6) rightSelf = 0; | |
else if(moveColumn != 6 && rowArray[moveRow][((moveColumn+1)<<1)] == 1'b1) begin //check 1 under | |
if (moveColumn + 1 != 6 && rowArray[moveRow][((moveColumn+2)<<1)] == 1'b1) begin //check 2 under | |
if (moveColumn + 2 != 6 && rowArray[moveRow][((moveColumn+3)<<1)] == 1'b1) begin //check 3 under | |
rightSelf = 4'd10; | |
end | |
else rightSelf = 4'd3; | |
end | |
else rightSelf = 4'd1; | |
end | |
else rightSelf = 4'd0; | |
//upper left check | |
if(moveColumn == 0) upLeftSelf = 0; | |
else if(moveColumn != 0 && moveRow != 5 && rowArray[moveRow+1][((moveColumn-1)<<1)] == 1'b1) begin //check 1 under | |
if (moveColumn - 1 != 0 && moveRow + 1 != 5 && rowArray[moveRow+2][((moveColumn-2)<<1)] == 1'b1) begin //check 2 under | |
if (moveColumn - 2 != 0 && moveRow + 2 != 5 && rowArray[moveRow+3][((moveColumn-3)<<1)] == 1'b1) begin //check 3 under | |
upLeftSelf = 4'd10; | |
end | |
else upLeftSelf = 4'd3; | |
end | |
else upLeftSelf = 4'd1; | |
end | |
else upLeftSelf = 4'd0; | |
//upper right check | |
if(moveColumn == 6) upRightSelf = 0; | |
else if(moveColumn != 6 && moveRow != 5 && rowArray[moveRow+1][((moveColumn+1)<<1)] == 1'b1) begin //check 1 under | |
if (moveColumn + 1 != 6 && moveRow + 1 != 5 && rowArray[moveRow+2][((moveColumn+2)<<1)] == 1'b1) begin //check 2 under | |
if (moveColumn + 2 != 6 && moveRow + 2 != 5 && rowArray[moveRow+3][((moveColumn+3)<<1)] == 1'b1) begin //check 3 under | |
upRightSelf = 4'd10; | |
end | |
else upRightSelf = 4'd3; | |
end | |
else upRightSelf = 4'd1; | |
end | |
else upRightSelf = 4'd0; | |
end //end always | |
endmodule | |
//maxConnectFinder module: output heuristic value for a given game state and move column | |
module maxConnectFinder( | |
input [13:0] row0, row1, row2, row3, row4, row5, | |
input [3:0] moveColumn, | |
input [1:0] player, | |
//input [3:0] moveRow, | |
input clk, | |
output [4:0] maxConnect | |
); | |
wire [13:0] rowArray [5:0]; | |
assign rowArray[0] = row0; | |
assign rowArray[1] = row1; | |
assign rowArray[2] = row2; | |
assign rowArray[3] = row3; | |
assign rowArray[4] = row4; | |
assign rowArray[5] = row5; | |
//assign moveRow to the row number of the next open slot in moveColumn | |
wire [3:0] moveRow; | |
assign moveRow = (row0[moveColumn<<1'b1] + row0[(moveColumn<<1)+1'b1] + row1[moveColumn<<1'b1] + row1[(moveColumn<<1'b1)+1'b1] + row2[moveColumn<<1'b1] + row2[(moveColumn<<1'b1)+1'b1] + row3[moveColumn<<1'b1] + row3[(moveColumn<<1'b1)+1'b1] + row4[moveColumn<<1'b1] + row4[(moveColumn<<1'b1)+1'b1] + row5[moveColumn<<1'b1] + row5[(moveColumn<<1'b1)+1'b1]); | |
reg [3:0] upLeftSelf; | |
wire [3:0] upLeftSelfWire; | |
reg [3:0] upRightSelf; | |
wire [3:0] upRightSelfWire; | |
reg [3:0] leftSelf; | |
wire [3:0] leftSelfWire; | |
reg [3:0] rightSelf; | |
wire [3:0] rightSelfWire; | |
reg [3:0] botSelf; | |
wire [3:0] botSelfWire; | |
reg [3:0] botRightSelf; | |
wire [3:0] botRightSelfWire; | |
reg [3:0] botLeftSelf; | |
wire [3:0] botLeftSelfWire; | |
reg [3:0] upLeft; | |
wire [3:0] upLeftWire; | |
reg [3:0] upRight; | |
wire [3:0] upRightWire; | |
reg [3:0] left; | |
wire [3:0] leftWire; | |
reg [3:0] right; | |
wire [3:0] rightWire; | |
reg [3:0] bot; | |
wire [3:0] botWire; | |
reg [3:0] botRight; | |
wire [3:0] botRightWire; | |
reg [3:0] botLeft; | |
wire [3:0] botLeftWire; | |
wire selfWinWire; | |
assign botSelfWire = botSelf; | |
assign botLeftSelfWire = botLeftSelf; | |
assign botRightSelfWire = botRightSelf; | |
assign leftSelfWire = leftSelf; | |
assign rightSelfWire = rightSelf; | |
assign upLeftSelfWire = upLeftSelf; | |
assign upRightSelfWire = upRightSelf; | |
assign botWire = bot; | |
assign botLeftWire = botLeft; | |
assign botRightWire = botRight; | |
assign leftWire = left; | |
assign rightWire = right; | |
assign upLeftWire = upLeft; | |
assign upRightWire = upRight; | |
wire [4:0] crossCheck /* synthesis keep */; | |
wire crossCheckSelf; | |
//check for split diagonals in AI tokens | |
assign crossCheckSelf = ((upLeftSelfWire+botRightSelfWire)>=4'd4 || (upRightSelfWire+botLeftSelfWire)>=4'd4 || (leftSelfWire+rightSelfWire)>=4'd4) ? 1'b1 : 1'b0; | |
//assign self win a 1 if there are any three-in-a-row AI token strings next to an empty slot | |
assign selfWinWire = (botSelfWire==4'd10 || botLeftSelfWire==4'd10 || botRightSelfWire==4'd10 || leftSelfWire==4'd10 || rightSelfWire==4'd10 || upLeftSelfWire == 4'd10 || upRightSelfWire ==4'd10 || crossCheckSelf==1'b1) ? 1'b1 : 1'b0; | |
//check for split diagonals in human player tokens | |
assign crossCheck = ((upLeftWire+botRightWire) >= 4'd6 || (upRightWire+botLeftWire) >= 4'd6 || (leftWire+rightWire) >= 4'd6) ? 5'd10 : (((upLeftWire+botRightWire) == 4'd2 || (upRightWire+botLeftWire) == 4'd2 || (leftWire+rightWire) == 4'd2) ? 5'd3 : 5'd0); //NOTE: will add 10 if already 3 in a row, most likely benign | |
wire [4:0] tempSum; | |
//sum up weighted values for each direction | |
assign tempSum = botWire + botLeftWire + botRightWire + leftWire + rightWire + upLeftWire + upRightWire + crossCheck; | |
//assign max heuristic value | |
assign maxConnect = (moveRow < 4'd6) ? ((selfWinWire == 1'b1 && tempSum < 4'd15) ? (player == 2'b01 ? 5'd30 : 5'd14) :tempSum) : (player == 2'b01 ? 5'd0 : 5'd31); | |
always @(*) begin | |
///////////////////////////////////////////CHECK OPPONENT MOVES///////////////////////////////////////////////////// | |
//bottom check | |
if(moveRow == 4'd0) bot = 4'd0; | |
else if((moveRow != 4'd0) && (rowArray[moveRow - 4'd1][(moveColumn<<1) + 4'd1] == 1'b1)) begin //check 1 under | |
if (((moveRow - 4'd1) != 4'd0) && (rowArray[moveRow - 4'd2][(moveColumn<<1) + 4'd1] == 1'b1)) begin //check 2 under | |
if (((moveRow - 4'd2) != 4'd0) && (rowArray[moveRow - 4'd3][(moveColumn<<1) + 4'd1] == 1'b1)) begin //check 3 under | |
bot = 4'd15; | |
end | |
else bot = 4'd5; | |
end | |
else bot = 4'd1; | |
end | |
else bot = 4'd0; | |
//bottom left check | |
if(moveRow == 4'd0) botLeft = 4'd0; | |
else if((moveRow != 4'd0) && (moveColumn != 4'd0) && (rowArray[moveRow - 4'd1][((moveColumn - 4'd1)<<1) + 4'd1] == 1'b1)) begin //check 1 under | |
if (((moveRow - 4'd1) != 4'd0) && ((moveColumn - 4'd1) != 4'd0) && (rowArray[moveRow - 4'd2][((moveColumn - 4'd2)<<1)+ 4'd1] == 1'b1)) begin //check 2 under | |
if (((moveRow - 4'd2) != 4'd0) && ((moveColumn - 4'd2) != 4'd0) && (rowArray[moveRow - 4'd3][((moveColumn - 4'd3)<<1) + 4'd1] == 1'b1)) begin //check 3 under | |
botLeft = 4'd10; | |
end | |
else botLeft = 4'd5; | |
end | |
else begin | |
if ((moveColumn > 4'd2) && (moveRow > 4'd2) && (rowArray[moveRow - 4'd2][((moveColumn - 4'd2)<<1) + 4'd1] == 1'b0) && (rowArray[moveRow - 4'd2][((moveColumn - 4'd2)<<1)] == 1'b0) && (rowArray[moveRow - 4'd3][((moveColumn - 4'd3)<<1) + 4'd1] == 1'b1)) botLeft = 4'd5; | |
else botLeft = 4'd1; | |
end | |
end | |
else botLeft = 4'd0; | |
//bottom right check | |
if(moveRow == 4'd0) botRight = 4'd0; | |
else if((moveRow != 4'd0) && (moveColumn != 4'd6) && (rowArray[moveRow - 4'd1][((moveColumn + 4'd1)<<1) + 4'd1] == 1'b1)) begin //check 1 under | |
if (((moveRow - 4'd1) != 4'd0) && ((moveColumn + 4'd1) != 4'd6) && (rowArray[moveRow - 4'd2][((moveColumn + 4'd2)<<1) + 4'd1] == 1'b1)) begin //check 2 under | |
if (((moveRow - 4'd2) != 4'd0) && ((moveColumn + 4'd2) != 4'd6) && (rowArray[moveRow - 4'd3][((moveColumn + 4'd3)<<1) + 4'd1] == 1'b1)) begin //check 3 under | |
botRight = 4'd10; | |
end | |
else botRight = 4'd5; | |
end | |
else begin | |
if (((moveColumn + 4'd2) < 4'd6) && (moveRow > 4'd2) && (rowArray[moveRow - 4'd2][((moveColumn + 4'd2)<<1) + 4'd1] == 1'b0) && (rowArray[moveRow - 4'd2][((moveColumn + 4'd2)<<1)] == 1'b0) && (rowArray[moveRow - 4'd3][((moveColumn + 4'd3)<<1) + 4'd1] == 1'b1)) botRight = 4'd5; | |
else botRight = 4'd1; | |
end | |
end | |
else botRight = 4'd0; | |
//left check | |
if(moveColumn == 4'd0) left = 4'd0; | |
else if((moveColumn != 4'd0) && (rowArray[moveRow][((moveColumn - 4'd1)<<1) + 4'd1] == 1'b1)) begin //check 1 under | |
if (((moveColumn - 4'd1) != 4'd0) && (rowArray[moveRow][((moveColumn - 4'd2)<<1) + 4'd1] == 1'b1)) begin //check 2 under | |
if (((moveColumn - 4'd2) != 4'd0) && (rowArray[moveRow][((moveColumn - 4'd3)<<1) + 4'd1] == 1'b1)) begin //check 3 under | |
left = 4'd10; | |
end | |
else left = 4'd5; | |
end | |
else begin | |
if ((moveColumn > 4'd2) && (rowArray[moveRow][((moveColumn - 4'd2)<<1) + 4'd1] == 1'b0) && (rowArray[moveRow][((moveColumn - 4'd2)<<1)] == 1'b0) && (rowArray[moveRow][((moveColumn - 4'd3)<<1) + 4'd1] == 1'b1)) left = 4'd5; | |
else left = 4'd1; | |
end | |
end | |
else left = 4'd0; | |
//right check | |
if(moveColumn == 4'd6) right = 4'd0; | |
else if((moveColumn != 4'd6) && (rowArray[moveRow][((moveColumn+1)<<1)+1] == 1'b1)) begin //check 1 under | |
if (((moveColumn + 4'd1) != 4'd6) && (rowArray[moveRow][((moveColumn + 4'd2)<<1) + 4'd1] == 1'b1)) begin //check 2 under | |
if (((moveColumn + 4'd2) != 4'd6) && (rowArray[moveRow][((moveColumn + 4'd3)<<1) + 4'd1] == 1'b1)) begin //check 3 under | |
right = 4'd10; | |
end | |
else right = 4'd5; | |
end | |
else begin | |
if (((moveColumn + 4'd2) < 4'd6) && (rowArray[moveRow][((moveColumn + 4'd2)<<1) + 4'd1] == 1'b0) && (rowArray[moveRow][((moveColumn + 4'd2)<<1)] == 1'b0) && (rowArray[moveRow][((moveColumn + 4'd3)<<1) + 4'd1] == 1'b1)) right = 4'd5; | |
else right = 4'd1; | |
end | |
end | |
else right = 4'd0; | |
//upper left check | |
if(moveColumn == 0) upLeft = 4'd0; | |
else if((moveColumn != 4'd0) && (moveRow != 4'd5) && (rowArray[moveRow + 4'd1][((moveColumn - 4'd1)<<1) + 4'd1] == 1'b1)) begin //check 1 under | |
if (((moveColumn - 4'd1) != 4'd0) && ((moveRow + 4'd1) != 4'd5) && (rowArray[moveRow + 4'd2][((moveColumn - 4'd2)<<1) + 4'd1] == 1'b1)) begin //check 2 under | |
if (((moveColumn - 4'd2) != 4'd0) && ((moveRow + 4'd2) != 4'd5) && (rowArray[moveRow + 4'd3][((moveColumn - 4'd3)<<1) + 4'd1] == 1'b1)) begin //check 3 under | |
upLeft = 4'd10; | |
end | |
else upLeft = 4'd5; | |
end | |
else begin | |
if ((moveColumn > 4'd2) && ((moveRow + 4'd2) < 4'd5) && (rowArray[moveRow + 4'd2][((moveColumn - 4'd2)<<1) + 4'd1] == 1'b0) && (rowArray[moveRow + 4'd2][((moveColumn - 4'd2)<<1)] == 1'b0) && (rowArray[moveRow + 4'd3][((moveColumn - 4'd3)<<1) + 4'd1] == 1'b1)) upLeft = 4'd5; | |
else upLeft = 4'd1; | |
end | |
end | |
else upLeft = 4'd0; | |
//upper right check | |
if(moveColumn == 6) upRight = 4'd0; | |
else if((moveColumn != 4'd6) && (moveRow != 4'd5) && (rowArray[moveRow+1][((moveColumn+1)<<1)+1] == 1'b1)) begin //check 1 under | |
if (((moveColumn + 4'd1) != 4'd6) && ((moveRow + 4'd1) != 4'd5) && (rowArray[moveRow + 4'd2][((moveColumn + 4'd2)<<1) + 4'd1] == 1'b1)) begin //check 2 under | |
if (((moveColumn + 4'd2) != 4'd6) && ((moveRow + 4'd2) != 4'd5) && (rowArray[moveRow + 4'd3][((moveColumn + 4'd3)<<1) + 4'd1] == 1'b1)) begin //check 3 under | |
upRight = 4'd10; | |
end | |
else upRight = 4'd5; | |
end | |
else begin | |
if (((moveColumn + 4'd2) < 4'd6) && ((moveRow + 4'd2) < 4'd5) && (rowArray[moveRow + 4'd2][((moveColumn + 4'd2)<<1) + 4'd1] == 1'b0) && (rowArray[moveRow + 4'd2][((moveColumn + 4'd2)<<1)] == 1'b0) && (rowArray[moveRow + 4'd3][((moveColumn +4'd3)<<1) + 4'd1] == 1'b1)) upRight = 4'd5; | |
else upRight = 4'd1; | |
end | |
end | |
else upRight = 4'd0; | |
////////////////////////////////////////////////CHECK SELF WIN///////////////////////////////////////////////////////////////// | |
//bottom check | |
if(moveRow == 0) botSelf = 4'd0; | |
else if((moveRow != 0) && (rowArray[moveRow-1][(moveColumn<<1)] == 1'b1)) begin //check 1 under | |
if (moveRow - 1 != 0 && rowArray[moveRow-2][(moveColumn<<1)] == 1'b1) begin //check 2 under | |
if (moveRow - 2 != 0 && rowArray[moveRow-3][(moveColumn<<1)] == 1'b1) begin //check 3 under | |
botSelf = 4'd10; | |
end | |
else botSelf = 4'd3; | |
end | |
else botSelf = 4'd1; | |
end | |
else botSelf = 4'd0; | |
//bottom left check | |
if(moveRow == 0) botLeftSelf = 4'd0; | |
else if(moveRow != 0 && moveColumn != 0 && rowArray[moveRow-1][((moveColumn-1)<<1)] == 1'b1) begin //check 1 under | |
if (moveRow - 1 != 0 && moveColumn - 1 != 0 && rowArray[moveRow-2][((moveColumn-2)<<1)] == 1'b1) begin //check 2 under | |
if (moveRow - 2 != 0 && moveColumn - 2 != 0 && rowArray[moveRow-3][((moveColumn-3)<<1)] == 1'b1) begin //check 3 under | |
botLeftSelf = 4'd10; | |
end | |
else botLeftSelf = 4'd3; | |
end | |
else botLeftSelf = 4'd1; | |
end | |
else botLeftSelf = 4'd0; | |
//bottom right check | |
if(moveRow == 0) botRightSelf = 4'd0; | |
else if(moveRow != 0 && moveColumn != 6 && rowArray[moveRow-1][((moveColumn+1)<<1)] == 1'b1) begin //check 1 under | |
if (moveRow - 1 != 0 && moveColumn + 1 != 6 && rowArray[moveRow-2][((moveColumn+2)<<1)] == 1'b1) begin //check 2 under | |
if (moveRow - 2 != 0 && moveColumn + 2 != 6 && rowArray[moveRow-3][((moveColumn+3)<<1)] == 1'b1) begin //check 3 under | |
botRightSelf = 4'd10; | |
end | |
else botRightSelf = 4'd3; | |
end | |
else botRightSelf = 4'd1; | |
end | |
else botRightSelf = 4'd0; | |
//left check | |
if(moveColumn == 0) leftSelf = 0; | |
else if(moveColumn != 0 && rowArray[moveRow][((moveColumn-1)<<1)] == 1'b1) begin //check 1 under | |
if (moveColumn - 1 != 0 && rowArray[moveRow][((moveColumn-2)<<1)] == 1'b1) begin //check 2 under | |
if (moveColumn - 2 != 0 && rowArray[moveRow][((moveColumn-3)<<1)] == 1'b1) begin //check 3 under | |
leftSelf = 4'd10; | |
end | |
else leftSelf = 4'd3; | |
end | |
else leftSelf = 4'd1; | |
end | |
else leftSelf = 4'd0; | |
//right check | |
if(moveColumn == 6) rightSelf = 0; | |
else if(moveColumn != 6 && rowArray[moveRow][((moveColumn+1)<<1)] == 1'b1) begin //check 1 under | |
if (moveColumn + 1 != 6 && rowArray[moveRow][((moveColumn+2)<<1)] == 1'b1) begin //check 2 under | |
if (moveColumn + 2 != 6 && rowArray[moveRow][((moveColumn+3)<<1)] == 1'b1) begin //check 3 under | |
rightSelf = 4'd10; | |
end | |
else rightSelf = 4'd3; | |
end | |
else rightSelf = 4'd1; | |
end | |
else rightSelf = 4'd0; | |
//upper left check | |
if(moveColumn == 0) upLeftSelf = 0; | |
else if(moveColumn != 0 && moveRow != 5 && rowArray[moveRow+1][((moveColumn-1)<<1)] == 1'b1) begin //check 1 under | |
if (moveColumn - 1 != 0 && moveRow + 1 != 5 && rowArray[moveRow+2][((moveColumn-2)<<1)] == 1'b1) begin //check 2 under | |
if (moveColumn - 2 != 0 && moveRow + 2 != 5 && rowArray[moveRow+3][((moveColumn-3)<<1)] == 1'b1) begin //check 3 under | |
upLeftSelf = 4'd10; | |
end | |
else upLeftSelf = 4'd3; | |
end | |
else upLeftSelf = 4'd1; | |
end | |
else upLeftSelf = 4'd0; | |
//upper right check | |
if(moveColumn == 6) upRightSelf = 0; | |
else if(moveColumn != 6 && moveRow != 5 && rowArray[moveRow+1][((moveColumn+1)<<1)] == 1'b1) begin //check 1 under | |
if (moveColumn + 1 != 6 && moveRow + 1 != 5 && rowArray[moveRow+2][((moveColumn+2)<<1)] == 1'b1) begin //check 2 under | |
if (moveColumn + 2 != 6 && moveRow + 2 != 5 && rowArray[moveRow+3][((moveColumn+3)<<1)] == 1'b1) begin //check 3 under | |
upRightSelf = 4'd10; | |
end | |
else upRightSelf = 4'd3; | |
end | |
else upRightSelf = 4'd1; | |
end | |
else upRightSelf = 4'd0; | |
end //end always | |
endmodule | |
//module to output the max value given 7 inputs | |
module findMaximum( | |
input [4:0] in0, in1, in2, in3, in4, in5, in6, | |
output [4:0] out | |
); | |
wire [4:0] comp1; | |
wire [4:0] comp2; | |
wire [4:0] comp3; | |
wire [4:0] comp4; | |
wire [4:0] comp5; | |
assign comp1 = (in0==5'd31) ? in1 : ((in1==5'd31) ? in0 : ((in0>in1) ? in0 : in1)); | |
assign comp2 = (in2==5'd31) ? in3 : ((in3==5'd31) ? in2 : ((in2>in3) ? in2 : in3)); | |
assign comp3 = (in4==5'd31) ? in5 : ((in5==5'd31) ? in4 : ((in4>in5) ? in4 : in5)); | |
assign comp4 = (comp1==5'd31) ? comp2 : ((comp2==5'd31) ? comp1 : ((comp1>comp2) ? comp1 : comp2)); | |
assign comp5 = (comp4==5'd31) ? comp3 : ((comp3==5'd31) ? comp4 : ((comp4>comp3) ? comp4 : comp3)); | |
assign out = (comp5==5'd31) ? in6 : ((in6==5'd31) ? comp5 : ((comp5>in6) ? comp5 : in6)); | |
endmodule | |
//module to output the min value given 7 inputs | |
module findMinimum( | |
input [4:0] in0, in1, in2, in3, in4, in5, in6, | |
output [4:0] out | |
); | |
wire [4:0] comp1; | |
wire [4:0] comp2; | |
wire [4:0] comp3; | |
wire [4:0] comp4; | |
wire [4:0] comp5; | |
assign comp1 = (in0<in1)?in0:in1; | |
assign comp2 = (in2<in3)?in2:in3; | |
assign comp3 = (in4<in5)?in4:in5; | |
assign comp4 = (comp1<comp2)?comp1:comp2; | |
assign comp5 = (comp4<comp3)?comp4:comp3; | |
assign out = (comp5<in6)?comp5:in6; | |
endmodule | |
//generate an 84-bit game state given the current game state and a new move | |
module genStateFromColumn( | |
input [3:0] column, | |
input [83:0] gameState, | |
input [1:0] player, | |
output [83:0] nextState, | |
output disable_column | |
); | |
wire [13:0] row0; | |
wire [13:0] row1; | |
wire [13:0] row2; | |
wire [13:0] row3; | |
wire [13:0] row4; | |
wire [13:0] row5; | |
wire [13:0] rowArray [5:0]; | |
assign row0 = gameState[13:0]; | |
assign rowArray[0] = row0; | |
assign row1 = gameState[27:14]; | |
assign rowArray[1] = row1; | |
assign row2 = gameState[41:28]; | |
assign rowArray[2] = row2; | |
assign row3 = gameState[55:42]; | |
assign rowArray[3] = row3; | |
assign row4 = gameState[69:56]; | |
assign rowArray[4] = row4; | |
assign row5 = gameState[83:70]; | |
assign rowArray[5] = row5; | |
wire [3:0] moveRow; | |
assign moveRow = (row0[column<<1] + row0[(column<<1)+1] + row1[column<<1] + row1[(column<<1)+1] + row2[column<<1] + row2[(column<<1)+1] + row3[column<<1] + row3[(column<<1)+1] + row4[column<<1] + row4[(column<<1)+1] + row5[column<<1] + row5[(column<<1)+1]); | |
assign disable_column = (moveRow >= 4'd6) ? 1'b1 : 1'b0; | |
wire [3:0] exponent; | |
assign exponent = (column<<1) + player - 4'd1; | |
wire [13:0] newRow; | |
assign newRow = rowArray[moveRow] + (14'd1 << exponent); | |
assign nextState[13:0] = (moveRow==4'd0) ? newRow : row0; | |
assign nextState[27:14] = (moveRow==4'd1) ? newRow : row1; | |
assign nextState[41:28] = (moveRow==4'd2) ? newRow : row2; | |
assign nextState[55:42] = (moveRow==4'd3) ? newRow : row3; | |
assign nextState[69:56] = (moveRow==4'd4) ? newRow : row4; | |
assign nextState[83:70] = (moveRow==4'd5) ? newRow : row5; | |
endmodule | |
/* | |
module RAM_512_18( | |
output reg signed [17:0] q, | |
input signed [17:0] data, | |
input [8:0] wraddress, rdaddress, | |
input wren, rden, clock | |
); | |
reg [8:0] read_address_reg; | |
reg signed [17:0] mem [511:0]; | |
reg rden_reg; | |
always @ (posedge clock) | |
begin | |
if (wren) | |
mem[wraddress] <= data; | |
end | |
always @ (posedge clock) begin | |
if (rden_reg) | |
q <= mem[read_address_reg]; | |
read_address_reg <= rdaddress; | |
rden_reg <= rden; | |
end | |
endmodule | |
*/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment