Skip to content

Instantly share code, notes, and snippets.

@mb2532
Created December 21, 2020 07:24
Show Gist options
  • Save mb2532/be2970cc6b99c1ca621c570b7e639bfb to your computer and use it in GitHub Desktop.
Save mb2532/be2970cc6b99c1ca621c570b7e639bfb to your computer and use it in GitHub Desktop.
//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