Created
December 21, 2020 07:24
-
-
Save mb2532/be2970cc6b99c1ca621c570b7e639bfb 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
//Defensive AI module to be used during first four moves | |
module connectFourAI_defensive( | |
input [83:0] gameState, | |
output [3:0] aiMove, | |
output [4:0] maxConnectOut, | |
input clk, reset | |
); | |
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 [3:0] tempMove [5:0]; | |
wire [4:0] maxConnect [6:0]; | |
assign maxConnectOut = maxConnect[0]; | |
//instantiate seven maxConnect Finders for each possible move | |
maxConnectFinder_defensive col0( | |
.clk (clk), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd0), | |
.maxConnect (maxConnect[0]) | |
); | |
maxConnectFinder_defensive col1( | |
.clk (clk), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd1), | |
.maxConnect (maxConnect[1]) | |
); | |
maxConnectFinder_defensive col2( | |
.clk (clk), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd2), | |
.maxConnect (maxConnect[2]) | |
); | |
maxConnectFinder_defensive col3( | |
.clk (clk), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd3), | |
.maxConnect (maxConnect[3]) | |
); | |
maxConnectFinder_defensive col4( | |
.clk (clk), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd4), | |
.maxConnect (maxConnect[4]) | |
); | |
maxConnectFinder_defensive col5( | |
.clk (clk), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd5), | |
.maxConnect (maxConnect[5]) | |
); | |
maxConnectFinder_defensive col6( | |
.clk (clk), | |
.row0 (row0), | |
.row1 (row1), | |
.row2 (row2), | |
.row3 (row3), | |
.row4 (row4), | |
.row5 (row5), | |
.moveColumn (4'd6), | |
.maxConnect (maxConnect[6]) | |
); | |
wire [4:0] foundMax; | |
findMaximum_defensive findmax( | |
.in0 (maxConnect[0]), | |
.in1 (maxConnect[1]), | |
.in2 (maxConnect[2]), | |
.in3 (maxConnect[3]), | |
.in4 (maxConnect[4]), | |
.in5 (maxConnect[5]), | |
.in6 (maxConnect[6]), | |
.out (foundMax) | |
); | |
//assign move to the column that generates highest heuristic value | |
assign aiMove = (foundMax==maxConnect[3]?3:(foundMax==maxConnect[2]?2:(foundMax==maxConnect[4]?4:(foundMax==maxConnect[1]?1:(foundMax==maxConnect[5]?5:(foundMax==maxConnect[0]?0:6)))))); | |
endmodule | |
//module to generate a heuristic value given a column to place in and a current game state | |
module maxConnectFinder_defensive( | |
input [13:0] row0, row1, row2, row3, row4, row5, | |
input [3:0] moveColumn, | |
//input [3:0] moveRow, | |
input clk, | |
output [4:0] maxConnect | |
); | |
reg test1; | |
reg test2; | |
reg test3; | |
wire test4; | |
wire test5; | |
wire test6; | |
wire [3:0] test7; | |
wire [3:0] test8; | |
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 move row the row number of the next open slot in move column | |
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; | |
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; | |
wire crossCheckSelf; | |
//check for split diagonals in AI tokens | |
assign crossCheckSelf = ((upLeftSelfWire+botRightSelfWire)>=4'd4 || (upRightSelfWire+botLeftSelfWire)>=4'd4 || (leftSelfWire+rightSelfWire)>=4'd4)?1:0; | |
//check for an AI win in the next move | |
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:0; | |
//check for split diagonals in human player tokens | |
assign crossCheck = ((upLeftWire+botRightWire)>=4'd4 || (upRightWire+botLeftWire)>=4'd4 || (leftWire+rightWire)>=4'd4)?5'd10:5'd0; | |
//maximum heuristic value | |
assign maxConnect = (moveRow < 4'd6) ? (selfWinWire == 1'b1 ? 5'd30 :botWire + botLeftWire + botRightWire + leftWire + rightWire + upLeftWire + upRightWire + crossCheck) : 5'd0; | |
always @(*) begin | |
///////////////////////////////////////////CHECK OPPONENT MOVES///////////////////////////////////////////////////// | |
//bottom check | |
if(moveRow == 0) bot = 4'd0; | |
else if((moveRow != 0) && (rowArray[moveRow-1][(moveColumn<<1)+1] == 1'b1)) begin //check 1 under | |
test1 = 1; | |
if (moveRow - 1 != 0 && rowArray[moveRow-2][(moveColumn<<1)+1] == 1'b1) begin //check 2 under | |
test2 = 1; | |
if (moveRow - 2 != 0 && rowArray[moveRow-3][(moveColumn<<1)+1] == 1'b1) begin //check 3 under | |
test3 = 1; | |
bot = 4'd10; | |
end | |
else bot = 4'd5; | |
end | |
else bot = 4'd1; | |
end | |
else bot = 4'd0; | |
//bottom left check | |
if(moveRow == 0) botLeft = 0; | |
else if(moveRow != 0 && moveColumn != 0 && rowArray[moveRow-1][((moveColumn-1)<<1)+1] == 1'b1) begin //check 1 under | |
if (moveRow - 1 != 0 && moveColumn - 1 != 0 && rowArray[moveRow-2][((moveColumn-2)<<1)+1] == 1'b1) begin //check 2 under | |
if (moveRow - 2 != 0 && moveColumn - 2 != 0 && rowArray[moveRow-3][((moveColumn-3)<<1)+1] == 1'b1) begin //check 3 under | |
botLeft = 4'd10; | |
end | |
else botLeft = 4'd5; | |
end | |
else botLeft = 4'd1; | |
end | |
else botLeft = 4'd0; | |
//bottom right check | |
if(moveRow == 0) botRight = 0; | |
else if(moveRow != 0 && moveColumn != 6 && rowArray[moveRow-1][((moveColumn+1)<<1)+1] == 1'b1) begin //check 1 under | |
if (moveRow - 1 != 0 && moveColumn + 1 != 6 && rowArray[moveRow-2][((moveColumn+2)<<1)+1] == 1'b1) begin //check 2 under | |
if (moveRow - 2 != 0 && moveColumn + 2 != 6 && rowArray[moveRow-3][((moveColumn+3)<<1)+1] == 1'b1) begin //check 3 under | |
botRight = 4'd10; | |
end | |
else botRight = 4'd5; | |
end | |
else botRight = 4'd1; | |
end | |
else botRight = 4'd0; | |
//left check | |
if(moveColumn == 0) left = 0; | |
else if(moveColumn != 0 && rowArray[moveRow][((moveColumn-1)<<1)+1] == 1'b1) begin //check 1 under | |
if (moveColumn - 1 != 0 && rowArray[moveRow][((moveColumn-2)<<1)+1] == 1'b1) begin //check 2 under | |
if (moveColumn - 2 != 0 && rowArray[moveRow][((moveColumn-3)<<1)+1] == 1'b1) begin //check 3 under | |
left = 4'd10; | |
end | |
else left = 4'd5; | |
end | |
else left = 4'd1; | |
end | |
else left = 4'd0; | |
//right check | |
if(moveColumn == 6) right = 0; | |
else if(moveColumn != 6 && rowArray[moveRow][((moveColumn+1)<<1)+1] == 1'b1) begin //check 1 under | |
if (moveColumn + 1 != 6 && rowArray[moveRow][((moveColumn+2)<<1)+1] == 1'b1) begin //check 2 under | |
if (moveColumn + 2 != 6 && rowArray[moveRow][((moveColumn+3)<<1)+1] == 1'b1) begin //check 3 under | |
right = 4'd10; | |
end | |
else right = 4'd5; | |
end | |
else right = 4'd1; | |
end | |
else right = 4'd0; | |
//upper left check | |
if(moveColumn == 0) upLeft = 0; | |
else if(moveColumn != 0 && moveRow != 5 && rowArray[moveRow+1][((moveColumn-1)<<1)+1] == 1'b1) begin //check 1 under | |
if (moveColumn - 1 != 0 && moveRow + 1 != 5 && rowArray[moveRow+2][((moveColumn-2)<<1)+1] == 1'b1) begin //check 2 under | |
if (moveColumn - 2 != 0 && moveRow + 2 != 5 && rowArray[moveRow+3][((moveColumn-3)<<1)+1] == 1'b1) begin //check 3 under | |
upLeft = 4'd10; | |
end | |
else upLeft = 4'd5; | |
end | |
else upLeft = 4'd1; | |
end | |
else upLeft = 4'd0; | |
//upper right check | |
if(moveColumn == 6) upRight = 0; | |
else if(moveColumn != 6 && moveRow != 5 && rowArray[moveRow+1][((moveColumn+1)<<1)+1] == 1'b1) begin //check 1 under | |
if (moveColumn + 1 != 6 && moveRow + 1 != 5 && rowArray[moveRow+2][((moveColumn+2)<<1)+1] == 1'b1) begin //check 2 under | |
if (moveColumn + 2 != 6 && moveRow + 2 != 5 && rowArray[moveRow+3][((moveColumn+3)<<1)+1] == 1'b1) begin //check 3 under | |
upRight = 4'd10; | |
end | |
else upRight = 4'd5; | |
end | |
else upRight = 4'd1; | |
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 | |
//find max given seven inputs | |
module findMaximum_defensive( | |
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 | |
/* | |
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 | |
*/ | |
module vc_Mux2 #(parameter bits = 18)(in0, in1, sel, out); | |
input [bits-1:0] in0, in1; | |
input sel; | |
output [bits-1:0] out; | |
assign out = sel ? in1 : in0; | |
endmodule | |
////////////////////////////////////////////////// | |
//// signed mult of 1.17 format 2'comp//////////// | |
////////////////////////////////////////////////// | |
module signed_mult (out, a, b); | |
output signed [17:0] out; | |
input signed [17:0] a; | |
input signed [17:0] b; | |
// intermediate full bit length | |
wire signed [35:0] mult_out; | |
assign mult_out = a * b; | |
// select bits for 1.17 fixed point | |
assign out = {mult_out[35], mult_out[33:17]}; | |
endmodule | |
////////////////////////////////////////////////// | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment