Created
December 21, 2020 07:21
-
-
Save mb2532/7198e572eebd30b39e2a67bb4c113ce6 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
module DE1_SoC_Computer ( | |
//////////////////////////////////// | |
// FPGA Pins | |
//////////////////////////////////// | |
// Clock pins | |
CLOCK_50, | |
CLOCK2_50, | |
CLOCK3_50, | |
CLOCK4_50, | |
// ADC | |
ADC_CS_N, | |
ADC_DIN, | |
ADC_DOUT, | |
ADC_SCLK, | |
// Audio | |
AUD_ADCDAT, | |
AUD_ADCLRCK, | |
AUD_BCLK, | |
AUD_DACDAT, | |
AUD_DACLRCK, | |
AUD_XCK, | |
// SDRAM | |
DRAM_ADDR, | |
DRAM_BA, | |
DRAM_CAS_N, | |
DRAM_CKE, | |
DRAM_CLK, | |
DRAM_CS_N, | |
DRAM_DQ, | |
DRAM_LDQM, | |
DRAM_RAS_N, | |
DRAM_UDQM, | |
DRAM_WE_N, | |
// I2C Bus for Configuration of the Audio and Video-In Chips | |
FPGA_I2C_SCLK, | |
FPGA_I2C_SDAT, | |
// 40-Pin Headers | |
GPIO_0, | |
GPIO_1, | |
// Seven Segment Displays | |
HEX0, | |
HEX1, | |
HEX2, | |
HEX3, | |
HEX4, | |
HEX5, | |
// IR | |
IRDA_RXD, | |
IRDA_TXD, | |
// Pushbuttons | |
KEY, | |
// LEDs | |
LEDR, | |
// PS2 Ports | |
PS2_CLK, | |
PS2_DAT, | |
PS2_CLK2, | |
PS2_DAT2, | |
// Slider Switches | |
SW, | |
// Video-In | |
TD_CLK27, | |
TD_DATA, | |
TD_HS, | |
TD_RESET_N, | |
TD_VS, | |
// VGA | |
VGA_B, | |
VGA_BLANK_N, | |
VGA_CLK, | |
VGA_G, | |
VGA_HS, | |
VGA_R, | |
VGA_SYNC_N, | |
VGA_VS, | |
//////////////////////////////////// | |
// HPS Pins | |
//////////////////////////////////// | |
// DDR3 SDRAM | |
HPS_DDR3_ADDR, | |
HPS_DDR3_BA, | |
HPS_DDR3_CAS_N, | |
HPS_DDR3_CKE, | |
HPS_DDR3_CK_N, | |
HPS_DDR3_CK_P, | |
HPS_DDR3_CS_N, | |
HPS_DDR3_DM, | |
HPS_DDR3_DQ, | |
HPS_DDR3_DQS_N, | |
HPS_DDR3_DQS_P, | |
HPS_DDR3_ODT, | |
HPS_DDR3_RAS_N, | |
HPS_DDR3_RESET_N, | |
HPS_DDR3_RZQ, | |
HPS_DDR3_WE_N, | |
// Ethernet | |
HPS_ENET_GTX_CLK, | |
HPS_ENET_INT_N, | |
HPS_ENET_MDC, | |
HPS_ENET_MDIO, | |
HPS_ENET_RX_CLK, | |
HPS_ENET_RX_DATA, | |
HPS_ENET_RX_DV, | |
HPS_ENET_TX_DATA, | |
HPS_ENET_TX_EN, | |
// Flash | |
HPS_FLASH_DATA, | |
HPS_FLASH_DCLK, | |
HPS_FLASH_NCSO, | |
// Accelerometer | |
HPS_GSENSOR_INT, | |
// General Purpose I/O | |
HPS_GPIO, | |
// I2C | |
HPS_I2C_CONTROL, | |
HPS_I2C1_SCLK, | |
HPS_I2C1_SDAT, | |
HPS_I2C2_SCLK, | |
HPS_I2C2_SDAT, | |
// Pushbutton | |
HPS_KEY, | |
// LED | |
HPS_LED, | |
// SD Card | |
HPS_SD_CLK, | |
HPS_SD_CMD, | |
HPS_SD_DATA, | |
// SPI | |
HPS_SPIM_CLK, | |
HPS_SPIM_MISO, | |
HPS_SPIM_MOSI, | |
HPS_SPIM_SS, | |
// UART | |
HPS_UART_RX, | |
HPS_UART_TX, | |
// USB | |
HPS_CONV_USB_N, | |
HPS_USB_CLKOUT, | |
HPS_USB_DATA, | |
HPS_USB_DIR, | |
HPS_USB_NXT, | |
HPS_USB_STP | |
); | |
//======================================================= | |
// PARAMETER declarations | |
//======================================================= | |
//======================================================= | |
// PORT declarations | |
//======================================================= | |
//////////////////////////////////// | |
// FPGA Pins | |
//////////////////////////////////// | |
// Clock pins | |
input CLOCK_50; | |
input CLOCK2_50; | |
input CLOCK3_50; | |
input CLOCK4_50; | |
// ADC | |
inout ADC_CS_N; | |
output ADC_DIN; | |
input ADC_DOUT; | |
output ADC_SCLK; | |
// Audio | |
input AUD_ADCDAT; | |
inout AUD_ADCLRCK; | |
inout AUD_BCLK; | |
output AUD_DACDAT; | |
inout AUD_DACLRCK; | |
output AUD_XCK; | |
// SDRAM | |
output [12: 0] DRAM_ADDR; | |
output [ 1: 0] DRAM_BA; | |
output DRAM_CAS_N; | |
output DRAM_CKE; | |
output DRAM_CLK; | |
output DRAM_CS_N; | |
inout [15: 0] DRAM_DQ; | |
output DRAM_LDQM; | |
output DRAM_RAS_N; | |
output DRAM_UDQM; | |
output DRAM_WE_N; | |
// I2C Bus for Configuration of the Audio and Video-In Chips | |
output FPGA_I2C_SCLK; | |
inout FPGA_I2C_SDAT; | |
// 40-pin headers | |
inout [35: 0] GPIO_0; | |
inout [35: 0] GPIO_1; | |
// Seven Segment Displays | |
output [ 6: 0] HEX0; | |
output [ 6: 0] HEX1; | |
output [ 6: 0] HEX2; | |
output [ 6: 0] HEX3; | |
output [ 6: 0] HEX4; | |
output [ 6: 0] HEX5; | |
// IR | |
input IRDA_RXD; | |
output IRDA_TXD; | |
// Pushbuttons | |
input [ 3: 0] KEY; | |
// LEDs | |
output [ 9: 0] LEDR; | |
// PS2 Ports | |
inout PS2_CLK; | |
inout PS2_DAT; | |
inout PS2_CLK2; | |
inout PS2_DAT2; | |
// Slider Switches | |
input [ 9: 0] SW; | |
// Video-In | |
input TD_CLK27; | |
input [ 7: 0] TD_DATA; | |
input TD_HS; | |
output TD_RESET_N; | |
input TD_VS; | |
// VGA | |
output [ 7: 0] VGA_B; | |
output VGA_BLANK_N; | |
output VGA_CLK; | |
output [ 7: 0] VGA_G; | |
output VGA_HS; | |
output [ 7: 0] VGA_R; | |
output VGA_SYNC_N; | |
output VGA_VS; | |
//////////////////////////////////// | |
// HPS Pins | |
//////////////////////////////////// | |
// DDR3 SDRAM | |
output [14: 0] HPS_DDR3_ADDR; | |
output [ 2: 0] HPS_DDR3_BA; | |
output HPS_DDR3_CAS_N; | |
output HPS_DDR3_CKE; | |
output HPS_DDR3_CK_N; | |
output HPS_DDR3_CK_P; | |
output HPS_DDR3_CS_N; | |
output [ 3: 0] HPS_DDR3_DM; | |
inout [31: 0] HPS_DDR3_DQ; | |
inout [ 3: 0] HPS_DDR3_DQS_N; | |
inout [ 3: 0] HPS_DDR3_DQS_P; | |
output HPS_DDR3_ODT; | |
output HPS_DDR3_RAS_N; | |
output HPS_DDR3_RESET_N; | |
input HPS_DDR3_RZQ; | |
output HPS_DDR3_WE_N; | |
// Ethernet | |
output HPS_ENET_GTX_CLK; | |
inout HPS_ENET_INT_N; | |
output HPS_ENET_MDC; | |
inout HPS_ENET_MDIO; | |
input HPS_ENET_RX_CLK; | |
input [ 3: 0] HPS_ENET_RX_DATA; | |
input HPS_ENET_RX_DV; | |
output [ 3: 0] HPS_ENET_TX_DATA; | |
output HPS_ENET_TX_EN; | |
// Flash | |
inout [ 3: 0] HPS_FLASH_DATA; | |
output HPS_FLASH_DCLK; | |
output HPS_FLASH_NCSO; | |
// Accelerometer | |
inout HPS_GSENSOR_INT; | |
// General Purpose I/O | |
inout [ 1: 0] HPS_GPIO; | |
// I2C | |
inout HPS_I2C_CONTROL; | |
inout HPS_I2C1_SCLK; | |
inout HPS_I2C1_SDAT; | |
inout HPS_I2C2_SCLK; | |
inout HPS_I2C2_SDAT; | |
// Pushbutton | |
inout HPS_KEY; | |
// LED | |
inout HPS_LED; | |
// SD Card | |
output HPS_SD_CLK; | |
inout HPS_SD_CMD; | |
inout [ 3: 0] HPS_SD_DATA; | |
// SPI | |
output HPS_SPIM_CLK; | |
input HPS_SPIM_MISO; | |
output HPS_SPIM_MOSI; | |
inout HPS_SPIM_SS; | |
// UART | |
input HPS_UART_RX; | |
output HPS_UART_TX; | |
// USB | |
inout HPS_CONV_USB_N; | |
input HPS_USB_CLKOUT; | |
inout [ 7: 0] HPS_USB_DATA; | |
input HPS_USB_DIR; | |
input HPS_USB_NXT; | |
output HPS_USB_STP; | |
//======================================================= | |
// REG/WIRE declarations | |
//======================================================= | |
wire [15: 0] hex3_hex0; | |
//wire [15: 0] hex5_hex4; | |
//assign HEX0 = ~hex3_hex0[ 6: 0]; // hex3_hex0[ 6: 0]; | |
//assign HEX1 = ~hex3_hex0[14: 8]; | |
//assign HEX2 = ~hex3_hex0[22:16]; | |
//assign HEX3 = ~hex3_hex0[30:24]; | |
assign HEX4 = 7'b1111111; | |
assign HEX5 = 7'b1111111; | |
HexDigit Digit0(HEX0, hex3_hex0[3:0]); | |
HexDigit Digit1(HEX1, hex3_hex0[7:4]); | |
HexDigit Digit2(HEX2, hex3_hex0[11:8]); | |
HexDigit Digit3(HEX3, hex3_hex0[15:12]); | |
//======================================================= | |
// SRAM/VGA state machine | |
//======================================================= | |
// --Check for sram address=0 nonzero, which means that | |
// HPS wrote some new data. | |
// | |
// --Read sram address 1 and 2 to get x1, y1 | |
// left-most x, upper-most y | |
// --Read sram address 3 and 4 to get x2, y2 | |
// right-most x, lower-most y | |
// --Read sram address 5 to get color | |
// --write a rectangle to VGA | |
// | |
// --clear sram address=0 to signal HPS | |
//======================================================= | |
// Controls for Qsys sram slave exported in system module | |
//======================================================= | |
wire [31:0] sram_readdata ; | |
reg [31:0] data_buffer, sram_writedata ; | |
reg [7:0] sram_address; | |
reg sram_write ; | |
wire sram_clken = 1'b1; | |
wire sram_chipselect = 1'b1; | |
// rectangle corners | |
reg signed [26:0] x1, y1; | |
reg [31:0] timer ; // may need to throttle write-rate | |
//======================================================= | |
// Controls for VGA memory | |
//======================================================= | |
wire [31:0] vga_out_base_address = 32'h0000_0000 ; // vga base addr | |
reg [7:0] vga_sram_writedata ; | |
reg [31:0] vga_sram_address; | |
reg vga_sram_write ; | |
wire vga_sram_clken = 1'b1; | |
wire vga_sram_chipselect = 1'b1; | |
//======================================================= | |
// pixel address is | |
reg [9:0] vga_x_cood, vga_y_cood ; | |
//reg [7:0] pixel_color ; | |
wire hps_reset; | |
assign LEDR[0] = hps_reset; | |
reg sim_reset; | |
wire max_iterations; | |
reg [5:0] state; | |
wire hps_move_finished; | |
reg ai_move_finished; | |
wire [83:0] gameState; | |
wire [3:0] aiMove; | |
wire [3:0] aiMove_defensive; | |
//need to change if board size changes | |
reg [13:0] row1; | |
reg [13:0] row2; | |
reg [13:0] row3; | |
reg [13:0] row4; | |
reg [13:0] row5; | |
reg [13:0] row6; | |
reg [5:0] move_counter; | |
//AI to be used for majority of game | |
connectFourAI smarterAI( | |
.clk (CLOCK_50), | |
.reset (hps_reset), | |
.gameState (gameState), | |
.aiMove (aiMove) | |
); | |
//AI to be used for first few moves | |
connectFourAI_defensive defensiveAI( | |
.clk (CLOCK_50), | |
.reset (hps_reset), | |
.gameState (gameState), | |
.aiMove (aiMove_defensive) | |
); | |
assign gameState = {row6, row5, row4, row3, row2, row1}; | |
//Top level FSM | |
always @(posedge CLOCK_50) begin | |
if(hps_reset)begin | |
state <= 6'd0; | |
ai_move_finished <= 1'b0; | |
move_counter <= 5'd0; | |
end | |
//read SRAM address 0, used to signal new game state from HPS | |
if (state == 6'd0) begin | |
sram_address <= 6'd0 ; | |
sram_write <= 1'b0 ; | |
state <= 6'd1 ; | |
end | |
// wait 1 for read | |
if (state == 6'd1) begin | |
state <= 6'd2 ; | |
end | |
// do data-read read | |
if (state == 6'd2) begin | |
data_buffer <= sram_readdata ; | |
sram_write <= 1'b0 ; | |
state <= 6'd3 ; | |
end | |
// If there's a new move continue to read game state, if not return to state 0 | |
if (state == 6'd3) begin | |
// if (addr 0)==0 try again | |
if (data_buffer==0) state <= 6'd0 ; | |
// if nonzero, do the add | |
else state <= 6'd4 ; | |
end | |
//read row 1 | |
if (state == 6'd4) begin | |
sram_address <= 8'd1 ; | |
sram_write <= 1'b0 ; | |
state <= 6'd5 ; | |
end | |
if (state == 6'd5) begin | |
state <= 6'd6 ; | |
end | |
if (state == 6'd6) begin | |
row1 <= sram_readdata[13:0]; | |
sram_write <= 1'b0 ; | |
state <= 6'd7 ; | |
end | |
//read row 2 | |
if (state == 6'd7) begin | |
sram_address <= 8'd2 ; | |
sram_write <= 1'b0 ; | |
state <= 6'd8 ; | |
end | |
if (state == 6'd8) begin | |
state <= 6'd9 ; | |
end | |
if (state == 6'd9) begin | |
row2 <= sram_readdata[13:0]; | |
sram_write <= 1'b0 ; | |
state <= 6'd10 ; | |
end | |
//read row 3 | |
if (state == 6'd10) begin | |
sram_address <= 8'd3 ; | |
sram_write <= 1'b0 ; | |
state <= 6'd11 ; | |
end | |
if (state == 6'd11) begin | |
state <= 6'd12 ; | |
end | |
if (state == 6'd12) begin | |
row3 <= sram_readdata[13:0]; | |
sram_write <= 1'b0 ; | |
state <= 6'd13 ; | |
end | |
//read row 4 | |
if (state == 6'd13) begin | |
sram_address <= 8'd4 ; | |
sram_write <= 1'b0 ; | |
state <= 6'd14 ; | |
end | |
if (state == 6'd14) begin | |
state <= 6'd15 ; | |
end | |
if (state == 6'd15) begin | |
row4 <= sram_readdata[13:0]; | |
sram_write <= 1'b0 ; | |
state <= 6'd16 ; | |
end | |
//read row 5 | |
if (state == 6'd16) begin | |
sram_address <= 8'd5 ; | |
sram_write <= 1'b0 ; | |
state <= 6'd17 ; | |
end | |
if (state == 6'd17) begin | |
state <= 6'd18 ; | |
end | |
if (state == 6'd18) begin | |
row5 <= sram_readdata[13:0]; | |
sram_write <= 1'b0 ; | |
state <= 6'd19 ; | |
end | |
//read row 6 | |
if (state == 6'd19) begin | |
sram_address <= 8'd6 ; | |
sram_write <= 1'b0 ; | |
state <= 6'd20 ; | |
end | |
if (state == 6'd20) begin | |
state <= 6'd21 ; | |
end | |
if (state == 6'd21) begin | |
row6 <= sram_readdata[13:0]; | |
sram_write <= 1'b0 ; | |
state <= 6'd22 ; | |
end | |
//get new AI move from AI compute module, write move to SRAM 7 | |
if (state == 6'd22) begin | |
sram_address <= 8'd7 ; | |
if(move_counter<5'd4)begin | |
sram_writedata <= aiMove_defensive; | |
end | |
else sram_writedata <= aiMove; | |
sram_write <= 1'b1 ; | |
state <= 6'd23; | |
end | |
//done state | |
if (state == 6'd23) begin | |
// signal the HPS we are done | |
sram_address <= 8'd0 ; | |
sram_writedata <= 32'b0; | |
sram_write <= 1'b1 ; | |
move_counter <= move_counter + 5'd1; | |
state <= 6'd0 ; | |
end | |
end | |
//======================================================= | |
// Structural coding | |
//======================================================= | |
// From Qsys | |
Computer_System The_System ( | |
//////////////////////////////////// | |
// FPGA Side | |
//////////////////////////////////// | |
.hps_reset_port_export (hps_reset), | |
.max_iterations_port_export (max_iterations), | |
// Global signals | |
.system_pll_ref_clk_clk (CLOCK_50), | |
.system_pll_ref_reset_reset (1'b0), | |
// SRAM shared block with HPS | |
.onchip_sram_s1_address (sram_address), | |
.onchip_sram_s1_clken (sram_clken), | |
.onchip_sram_s1_chipselect (sram_chipselect), | |
.onchip_sram_s1_write (sram_write), | |
.onchip_sram_s1_readdata (sram_readdata), | |
.onchip_sram_s1_writedata (sram_writedata), | |
.onchip_sram_s1_byteenable (4'b1111), | |
// sram to video | |
.onchip_vga_buffer_s1_address (vga_sram_address), | |
.onchip_vga_buffer_s1_clken (vga_sram_clken), | |
.onchip_vga_buffer_s1_chipselect (vga_sram_chipselect), | |
.onchip_vga_buffer_s1_write (vga_sram_write), | |
.onchip_vga_buffer_s1_readdata (), // never read from vga here | |
.onchip_vga_buffer_s1_writedata (vga_sram_writedata), | |
// AV Config | |
.av_config_SCLK (FPGA_I2C_SCLK), | |
.av_config_SDAT (FPGA_I2C_SDAT), | |
// 50 MHz clock bridge | |
.clock_bridge_0_in_clk_clk (CLOCK_50), //(CLOCK_50), | |
// VGA Subsystem | |
.vga_pll_ref_clk_clk (CLOCK2_50), | |
.vga_pll_ref_reset_reset (1'b0), | |
.vga_CLK (VGA_CLK), | |
.vga_BLANK (VGA_BLANK_N), | |
.vga_SYNC (VGA_SYNC_N), | |
.vga_HS (VGA_HS), | |
.vga_VS (VGA_VS), | |
.vga_R (VGA_R), | |
.vga_G (VGA_G), | |
.vga_B (VGA_B), | |
// SDRAM | |
.sdram_clk_clk (DRAM_CLK), | |
.sdram_addr (DRAM_ADDR), | |
.sdram_ba (DRAM_BA), | |
.sdram_cas_n (DRAM_CAS_N), | |
.sdram_cke (DRAM_CKE), | |
.sdram_cs_n (DRAM_CS_N), | |
.sdram_dq (DRAM_DQ), | |
.sdram_dqm ({DRAM_UDQM,DRAM_LDQM}), | |
.sdram_ras_n (DRAM_RAS_N), | |
.sdram_we_n (DRAM_WE_N), | |
//////////////////////////////////// | |
// HPS Side | |
//////////////////////////////////// | |
// DDR3 SDRAM | |
.memory_mem_a (HPS_DDR3_ADDR), | |
.memory_mem_ba (HPS_DDR3_BA), | |
.memory_mem_ck (HPS_DDR3_CK_P), | |
.memory_mem_ck_n (HPS_DDR3_CK_N), | |
.memory_mem_cke (HPS_DDR3_CKE), | |
.memory_mem_cs_n (HPS_DDR3_CS_N), | |
.memory_mem_ras_n (HPS_DDR3_RAS_N), | |
.memory_mem_cas_n (HPS_DDR3_CAS_N), | |
.memory_mem_we_n (HPS_DDR3_WE_N), | |
.memory_mem_reset_n (HPS_DDR3_RESET_N), | |
.memory_mem_dq (HPS_DDR3_DQ), | |
.memory_mem_dqs (HPS_DDR3_DQS_P), | |
.memory_mem_dqs_n (HPS_DDR3_DQS_N), | |
.memory_mem_odt (HPS_DDR3_ODT), | |
.memory_mem_dm (HPS_DDR3_DM), | |
.memory_oct_rzqin (HPS_DDR3_RZQ), | |
// Ethernet | |
.hps_io_hps_io_gpio_inst_GPIO35 (HPS_ENET_INT_N), | |
.hps_io_hps_io_emac1_inst_TX_CLK (HPS_ENET_GTX_CLK), | |
.hps_io_hps_io_emac1_inst_TXD0 (HPS_ENET_TX_DATA[0]), | |
.hps_io_hps_io_emac1_inst_TXD1 (HPS_ENET_TX_DATA[1]), | |
.hps_io_hps_io_emac1_inst_TXD2 (HPS_ENET_TX_DATA[2]), | |
.hps_io_hps_io_emac1_inst_TXD3 (HPS_ENET_TX_DATA[3]), | |
.hps_io_hps_io_emac1_inst_RXD0 (HPS_ENET_RX_DATA[0]), | |
.hps_io_hps_io_emac1_inst_MDIO (HPS_ENET_MDIO), | |
.hps_io_hps_io_emac1_inst_MDC (HPS_ENET_MDC), | |
.hps_io_hps_io_emac1_inst_RX_CTL (HPS_ENET_RX_DV), | |
.hps_io_hps_io_emac1_inst_TX_CTL (HPS_ENET_TX_EN), | |
.hps_io_hps_io_emac1_inst_RX_CLK (HPS_ENET_RX_CLK), | |
.hps_io_hps_io_emac1_inst_RXD1 (HPS_ENET_RX_DATA[1]), | |
.hps_io_hps_io_emac1_inst_RXD2 (HPS_ENET_RX_DATA[2]), | |
.hps_io_hps_io_emac1_inst_RXD3 (HPS_ENET_RX_DATA[3]), | |
// Flash | |
.hps_io_hps_io_qspi_inst_IO0 (HPS_FLASH_DATA[0]), | |
.hps_io_hps_io_qspi_inst_IO1 (HPS_FLASH_DATA[1]), | |
.hps_io_hps_io_qspi_inst_IO2 (HPS_FLASH_DATA[2]), | |
.hps_io_hps_io_qspi_inst_IO3 (HPS_FLASH_DATA[3]), | |
.hps_io_hps_io_qspi_inst_SS0 (HPS_FLASH_NCSO), | |
.hps_io_hps_io_qspi_inst_CLK (HPS_FLASH_DCLK), | |
// Accelerometer | |
.hps_io_hps_io_gpio_inst_GPIO61 (HPS_GSENSOR_INT), | |
//.adc_sclk (ADC_SCLK), | |
//.adc_cs_n (ADC_CS_N), | |
//.adc_dout (ADC_DOUT), | |
//.adc_din (ADC_DIN), | |
// General Purpose I/O | |
.hps_io_hps_io_gpio_inst_GPIO40 (HPS_GPIO[0]), | |
.hps_io_hps_io_gpio_inst_GPIO41 (HPS_GPIO[1]), | |
// I2C | |
.hps_io_hps_io_gpio_inst_GPIO48 (HPS_I2C_CONTROL), | |
.hps_io_hps_io_i2c0_inst_SDA (HPS_I2C1_SDAT), | |
.hps_io_hps_io_i2c0_inst_SCL (HPS_I2C1_SCLK), | |
.hps_io_hps_io_i2c1_inst_SDA (HPS_I2C2_SDAT), | |
.hps_io_hps_io_i2c1_inst_SCL (HPS_I2C2_SCLK), | |
// Pushbutton | |
.hps_io_hps_io_gpio_inst_GPIO54 (HPS_KEY), | |
// LED | |
.hps_io_hps_io_gpio_inst_GPIO53 (HPS_LED), | |
// SD Card | |
.hps_io_hps_io_sdio_inst_CMD (HPS_SD_CMD), | |
.hps_io_hps_io_sdio_inst_D0 (HPS_SD_DATA[0]), | |
.hps_io_hps_io_sdio_inst_D1 (HPS_SD_DATA[1]), | |
.hps_io_hps_io_sdio_inst_CLK (HPS_SD_CLK), | |
.hps_io_hps_io_sdio_inst_D2 (HPS_SD_DATA[2]), | |
.hps_io_hps_io_sdio_inst_D3 (HPS_SD_DATA[3]), | |
// SPI | |
.hps_io_hps_io_spim1_inst_CLK (HPS_SPIM_CLK), | |
.hps_io_hps_io_spim1_inst_MOSI (HPS_SPIM_MOSI), | |
.hps_io_hps_io_spim1_inst_MISO (HPS_SPIM_MISO), | |
.hps_io_hps_io_spim1_inst_SS0 (HPS_SPIM_SS), | |
// UART | |
.hps_io_hps_io_uart0_inst_RX (HPS_UART_RX), | |
.hps_io_hps_io_uart0_inst_TX (HPS_UART_TX), | |
// USB | |
.hps_io_hps_io_gpio_inst_GPIO09 (HPS_CONV_USB_N), | |
.hps_io_hps_io_usb1_inst_D0 (HPS_USB_DATA[0]), | |
.hps_io_hps_io_usb1_inst_D1 (HPS_USB_DATA[1]), | |
.hps_io_hps_io_usb1_inst_D2 (HPS_USB_DATA[2]), | |
.hps_io_hps_io_usb1_inst_D3 (HPS_USB_DATA[3]), | |
.hps_io_hps_io_usb1_inst_D4 (HPS_USB_DATA[4]), | |
.hps_io_hps_io_usb1_inst_D5 (HPS_USB_DATA[5]), | |
.hps_io_hps_io_usb1_inst_D6 (HPS_USB_DATA[6]), | |
.hps_io_hps_io_usb1_inst_D7 (HPS_USB_DATA[7]), | |
.hps_io_hps_io_usb1_inst_CLK (HPS_USB_CLKOUT), | |
.hps_io_hps_io_usb1_inst_STP (HPS_USB_STP), | |
.hps_io_hps_io_usb1_inst_DIR (HPS_USB_DIR), | |
.hps_io_hps_io_usb1_inst_NXT (HPS_USB_NXT) | |
); | |
endmodule // end top level | |
//============================================================ | |
// M10K module for testing | |
//============================================================ | |
// See example 12-16 in | |
// http://people.ece.cornell.edu/land/courses/ece5760/DE1_SOC/HDL_style_qts_qii51007.pdf | |
//============================================================ | |
module M10K_256_32( | |
output reg [31:0] q, | |
input [31:0] d, | |
input [7:0] write_address, read_address, | |
input we, clk | |
); | |
// force M10K ram style | |
// 256 words of 32 bits | |
reg [31:0] mem [255:0] /* synthesis ramstyle = "no_rw_check, M10K" */; | |
always @ (posedge clk) begin | |
if (we) begin | |
mem[write_address] <= d; | |
end | |
q <= mem[read_address]; // q doesn't get d in this clock cycle | |
end | |
endmodule | |
//============================================================ | |
// MLAB module for testing | |
//============================================================ | |
// See example 12-16 in | |
// http://people.ece.cornell.edu/land/courses/ece5760/DE1_SOC/HDL_style_qts_qii51007.pdf | |
//============================================================ | |
module MLAB_20_32( | |
output reg signed [31:0] q, | |
input [31:0] data, | |
input [7:0] readaddr, writeaddr, | |
input wren, clock | |
); | |
// force MLAB ram style | |
// 20 words of 32 bits | |
reg signed [31:0] mem [19:0] /* synthesis ramstyle = "no_rw_check, MLAB" */; | |
always @ (posedge clock) | |
begin | |
if (wren) begin | |
mem[writeaddr] <= data; | |
end | |
q <= mem[readaddr]; | |
end | |
endmodule | |
/************************************************************************** | |
* Following floating point modules written by Bruce Land | |
* March 2017 | |
*************************************************************************/ | |
/************************************************************************** | |
* Floating Point to 16-bit integer * | |
* Combinational | |
* Numbers with mag > than +/-32768 get clipped to 32768 or -32768 | |
*************************************************************************/ | |
module Int2Fp( | |
input signed [15:0] iInteger, | |
output[26:0] oA | |
); | |
// output fields | |
wire A_s; | |
wire [7:0] A_e; | |
wire [17:0] A_f; | |
wire [15:0] abs_input ; | |
// get output sign bit | |
assign A_s = (iInteger < 0); | |
// remove sign from input | |
assign abs_input = (iInteger < 0)? -iInteger : iInteger ; | |
// find the most significant (nonzero) bit | |
wire [7:0] shft_amt; | |
assign shft_amt = abs_input[15] ? 8'd3 : | |
abs_input[14] ? 8'd4 : abs_input[13] ? 8'd5 : | |
abs_input[12] ? 8'd6 : abs_input[11] ? 8'd7 : | |
abs_input[10] ? 8'd8 : abs_input[9] ? 8'd9 : | |
abs_input[8] ? 8'd10 : abs_input[7] ? 8'd11 : | |
abs_input[6] ? 8'd12 : abs_input[5] ? 8'd13 : | |
abs_input[4] ? 8'd14 : abs_input[3] ? 8'd15 : | |
abs_input[2] ? 8'd16 : abs_input[1] ? 8'd17 : | |
abs_input[0] ? 8'd18 : 8'd19; | |
// exponent 127 + (18-shift_amt) | |
// 127 is 2^0 | |
// 18 is amount '1' is shifted | |
assign A_e = 127 + 18 - shft_amt ; | |
// where the intermediate value is formed | |
wire [33:0] shift_buffer ; | |
// remember that the high-order '1' is not stored, | |
// but is shifted to bit 18 | |
assign shift_buffer = {16'b0, abs_input} << shft_amt ; | |
assign A_f = shift_buffer[17:0]; | |
assign oA = (iInteger==0)? 27'b0 : {A_s, A_e, A_f}; | |
endmodule //Int2Fp | |
/************************************************************************** | |
* Floating Point to 16-bit integer * | |
* Combinational | |
* Numbers with mag > than +/-32768 get clipped to 32768 or -32768 | |
*************************************************************************/ | |
module Fp2Int( | |
input [26:0] iA, | |
output reg [15:0] oInteger | |
); | |
// Extract fields of A and B. | |
wire A_s; | |
wire [7:0] A_e; | |
wire [17:0] A_f; | |
assign A_s = iA[26]; | |
assign A_e = iA[25:18]; | |
assign A_f = iA[17:0]; | |
wire [15:0] max_int = 16'h7fff ; //32768 | |
wire [33:0] shift_buffer ; | |
// form (1.A_f) and shift it to postiion | |
assign shift_buffer = {15'b0, 1'b1, A_f}<<(A_e-127) ; | |
// If exponent less than 127, oInteger=0 | |
// If exponent greater than 127+14 oInteger=max value | |
// Between these two values: | |
// set up input mantissa with 1.mantissa | |
// and the "1." in the lowest bit of an extended word. | |
// shift-left by A_e-127 | |
// If the sign bit is set, negate oInteger | |
always @(*) begin | |
if (A_e < 127) oInteger = 16'b0; | |
else if (A_e > 141) begin | |
if (A_s) oInteger = -max_int; | |
else oInteger = max_int; | |
end | |
else begin | |
if (A_s) oInteger = -shift_buffer[33:18]; | |
else oInteger = shift_buffer[33:18]; | |
end | |
end | |
endmodule //Fp2Int | |
/************************************************************************** | |
* Floating Point shift * | |
* Combinational | |
* Negative shift input is right shift | |
*************************************************************************/ | |
module FpShift( | |
input [26:0] iA, | |
input [7:0] iShift, | |
output [26:0] oShifted | |
); | |
// Extract fields of A and B. | |
wire A_s; | |
wire [7:0] A_e; | |
wire [17:0] A_f; | |
assign A_s = iA[26]; | |
assign A_e = iA[25:18]; | |
assign A_f = iA[17:0]; | |
// Flip bit 26 | |
// zero the output if underflow/overflow | |
// assign oShifted = (A_e+iShift<8'd254 && A_e+iShift>8'd2)? | |
// {A_s, A_e+iShift, A_f} | |
assign oShifted = {A_s, A_e+iShift, A_f} ; | |
endmodule //FpShift | |
/************************************************************************** | |
* Floating Point sign negation * | |
* Combinational * | |
*************************************************************************/ | |
module FpNegate( | |
input [26:0] iA, | |
output [26:0] oNegative | |
); | |
// Extract fields of A and B. | |
wire A_s; | |
wire [7:0] A_e; | |
wire [17:0] A_f; | |
assign A_s = iA[26]; | |
assign A_e = iA[25:18]; | |
assign A_f = iA[17:0]; | |
// Flip bit 26 | |
assign oNegative = {~A_s, A_e, A_f}; | |
endmodule //FpNegate | |
/************************************************************************** | |
* Floating Point absolute * | |
* Combinational * | |
*************************************************************************/ | |
module FpAbs( | |
input [26:0] iA, | |
output [26:0] oAbs | |
); | |
// Extract fields of A and B. | |
wire A_s; | |
wire [7:0] A_e; | |
wire [17:0] A_f; | |
assign A_s = iA[26]; | |
assign A_e = iA[25:18]; | |
assign A_f = iA[17:0]; | |
// zero bit 26 | |
assign oAbs = {1'b0, A_e, A_f}; | |
endmodule //Fp absolute | |
/************************************************************************** | |
* Floating Point compare * | |
* Combinational | |
* output=1 if A>=B | |
*************************************************************************/ | |
module FpCompare( | |
input [26:0] iA, | |
input [26:0] iB, | |
output reg oA_larger | |
); | |
// Extract fields of A and B. | |
wire A_s; | |
wire [7:0] A_e; | |
wire [17:0] A_f; | |
wire B_s; | |
wire [7:0] B_e; | |
wire [17:0] B_f; | |
assign A_s = iA[26]; | |
assign A_e = iA[25:18]; | |
assign A_f = iA[17:0]; | |
assign B_s = iB[26]; | |
assign B_e = iB[25:18]; | |
assign B_f = iB[17:0]; | |
// Determine which of A, B is larger | |
wire A_mag_larger ; | |
assign A_mag_larger =(A_e > B_e) ? 1'b1 : | |
((A_e == B_e) && (A_f >= B_f)) ? 1'b1 : | |
1'b0; | |
// now do the sign checks | |
always @(*) begin | |
if (A_s==0 && B_s==1) begin // A positive, B negative | |
oA_larger = 1'b1 ; | |
end | |
else if (A_s==1 && B_s==0) begin // A negative, B positive | |
oA_larger = 1'b0 ; | |
end | |
else if (A_s==0 && B_s==0) begin // A positive, B positive | |
oA_larger = A_mag_larger ; | |
end | |
else if (A_s==1 && B_s==1) begin // A negative, B negative | |
oA_larger = ~A_mag_larger ; | |
end | |
else oA_larger = 0; // make sure no inferred latch | |
end | |
endmodule //FpCompare | |
/************************************************************************** | |
* Following floating point written by Mark Eiding mje56 * | |
* ECE 5760 * | |
* Modified IEEE single precision FP * | |
* bit 26: Sign (0: pos, 1: neg) * | |
* bits[25:18]: Exponent (unsigned) * | |
* bits[17:0]: Fraction (unsigned) * | |
* (-1)^SIGN * 2^(EXP-127) * (1+.FRAC) * | |
* (http://en.wikipedia.org/wiki/Single-precision_floating-point_format) * | |
* Adapted from Skyler Schneider ss868 * | |
*************************************************************************/ | |
/************************************************************************** | |
* Floating Point Fast Inverse Square Root * | |
* 5-stage pipeline * | |
* http://en.wikipedia.org/wiki/Fast_inverse_square_root * | |
* Magic number 27'd49920718 * | |
* 1.5 = 27'd33423360 * | |
*************************************************************************/ | |
module FpInvSqrt ( | |
input iCLK, | |
input [26:0] iA, | |
output [26:0] oInvSqrt | |
); | |
// Extract fields of A and B. | |
wire A_s; | |
wire [7:0] A_e; | |
wire [17:0] A_f; | |
assign A_s = iA[26]; | |
assign A_e = iA[25:18]; | |
assign A_f = iA[17:0]; | |
//Stage 1 | |
wire [26:0] y_1, y_1_out, half_iA_1; | |
assign y_1 = 27'd49920718 - (iA>>1); | |
assign half_iA_1 = {A_s, A_e-8'd1,A_f}; | |
FpMul s1_mult ( .iA(y_1), .iB(y_1), .oProd(y_1_out) ); | |
//Stage 2 | |
reg [26:0] y_2, mult_2_in, half_iA_2; | |
wire [26:0] y_2_out; | |
FpMul s2_mult ( .iA(half_iA_2), .iB(mult_2_in), .oProd(y_2_out) ); | |
//Stage 3 | |
reg [26:0] y_3, add_3_in; | |
wire [26:0] y_3_out; | |
FpAdd s3_add ( .iCLK(iCLK), .iA({~add_3_in[26],add_3_in[25:0]}), .iB(27'd33423360), .oSum(y_3_out) ); | |
//Stage 4 | |
reg [26:0] y_4; | |
//Stage 5 | |
reg [26:0] y_5, mult_5_in; | |
FpMul s5_mult ( .iA(y_5), .iB(mult_5_in), .oProd(oInvSqrt) ); | |
always @(posedge iCLK) begin | |
//Stage 1 to 2 | |
y_2 <= y_1; | |
mult_2_in <= y_1_out; | |
half_iA_2 <= half_iA_1; | |
//Stage 2 to 3 | |
y_3 <= y_2; | |
add_3_in <= y_2_out; | |
//Stage 3 to 4 | |
y_4 <= y_3; | |
//Stage 4 to 5 | |
y_5 <= y_4; | |
mult_5_in <= y_3_out; | |
end | |
endmodule | |
/************************************************************************** | |
* Floating Point Multiplier * | |
* Combinational * | |
*************************************************************************/ | |
module FpMul ( | |
input [26:0] iA, // First input | |
input [26:0] iB, // Second input | |
output [26:0] oProd // Product | |
); | |
// Extract fields of A and B. | |
wire A_s; | |
wire [7:0] A_e; | |
wire [17:0] A_f; | |
wire B_s; | |
wire [7:0] B_e; | |
wire [17:0] B_f; | |
assign A_s = iA[26]; | |
assign A_e = iA[25:18]; | |
assign A_f = {1'b1, iA[17:1]}; | |
assign B_s = iB[26]; | |
assign B_e = iB[25:18]; | |
assign B_f = {1'b1, iB[17:1]}; | |
// XOR sign bits to determine product sign. | |
wire oProd_s; | |
assign oProd_s = A_s ^ B_s; | |
// Multiply the fractions of A and B | |
wire [35:0] pre_prod_frac; | |
assign pre_prod_frac = A_f * B_f; | |
// Add exponents of A and B | |
wire [8:0] pre_prod_exp; | |
assign pre_prod_exp = A_e + B_e; | |
// If top bit of product frac is 0, shift left one | |
wire [7:0] oProd_e; | |
wire [17:0] oProd_f; | |
assign oProd_e = pre_prod_frac[35] ? (pre_prod_exp-9'd126) : (pre_prod_exp - 9'd127); | |
assign oProd_f = pre_prod_frac[35] ? pre_prod_frac[34:17] : pre_prod_frac[33:16]; | |
// Detect underflow | |
wire underflow; | |
assign underflow = pre_prod_exp < 9'h80; | |
// Detect zero conditions (either product frac doesn't start with 1, or underflow) | |
assign oProd = underflow ? 27'b0 : | |
(B_e == 8'd0) ? 27'b0 : | |
(A_e == 8'd0) ? 27'b0 : | |
{oProd_s, oProd_e, oProd_f}; | |
endmodule | |
/************************************************************************** | |
* Floating Point Adder * | |
* 2-stage pipeline * | |
*************************************************************************/ | |
module FpAdd ( | |
input iCLK, | |
input [26:0] iA, | |
input [26:0] iB, | |
output reg [26:0] oSum | |
); | |
// Extract fields of A and B. | |
wire A_s; | |
wire [7:0] A_e; | |
wire [17:0] A_f; | |
wire B_s; | |
wire [7:0] B_e; | |
wire [17:0] B_f; | |
assign A_s = iA[26]; | |
assign A_e = iA[25:18]; | |
assign A_f = {1'b1, iA[17:1]}; | |
assign B_s = iB[26]; | |
assign B_e = iB[25:18]; | |
assign B_f = {1'b1, iB[17:1]}; | |
wire A_larger; | |
// Shift fractions of A and B so that they align. | |
wire [7:0] exp_diff_A; | |
wire [7:0] exp_diff_B; | |
wire [7:0] larger_exp; | |
wire [36:0] A_f_shifted; | |
wire [36:0] B_f_shifted; | |
assign exp_diff_A = B_e - A_e; // if B bigger | |
assign exp_diff_B = A_e - B_e; // if A bigger | |
assign larger_exp = (B_e > A_e) ? B_e : A_e; | |
assign A_f_shifted = A_larger ? {1'b0, A_f, 18'b0} : | |
(exp_diff_A > 9'd35) ? 37'b0 : | |
({1'b0, A_f, 18'b0} >> exp_diff_A); | |
assign B_f_shifted = ~A_larger ? {1'b0, B_f, 18'b0} : | |
(exp_diff_B > 9'd35) ? 37'b0 : | |
({1'b0, B_f, 18'b0} >> exp_diff_B); | |
// Determine which of A, B is larger | |
assign A_larger = (A_e > B_e) ? 1'b1 : | |
((A_e == B_e) && (A_f > B_f)) ? 1'b1 : | |
1'b0; | |
// Calculate sum or difference of shifted fractions. | |
wire [36:0] pre_sum; | |
assign pre_sum = ((A_s^B_s) & A_larger) ? A_f_shifted - B_f_shifted : | |
((A_s^B_s) & ~A_larger) ? B_f_shifted - A_f_shifted : | |
A_f_shifted + B_f_shifted; | |
// buffer midway results | |
reg [36:0] buf_pre_sum; | |
reg [7:0] buf_larger_exp; | |
reg buf_A_e_zero; | |
reg buf_B_e_zero; | |
reg [26:0] buf_A; | |
reg [26:0] buf_B; | |
reg buf_oSum_s; | |
always @(posedge iCLK) begin | |
buf_pre_sum <= pre_sum; | |
buf_larger_exp <= larger_exp; | |
buf_A_e_zero <= (A_e == 8'b0); | |
buf_B_e_zero <= (B_e == 8'b0); | |
buf_A <= iA; | |
buf_B <= iB; | |
buf_oSum_s <= A_larger ? A_s : B_s; | |
end | |
// Convert to positive fraction and a sign bit. | |
wire [36:0] pre_frac; | |
assign pre_frac = buf_pre_sum; | |
// Determine output fraction and exponent change with position of first 1. | |
wire [17:0] oSum_f; | |
wire [7:0] shft_amt; | |
assign shft_amt = pre_frac[36] ? 8'd0 : pre_frac[35] ? 8'd1 : | |
pre_frac[34] ? 8'd2 : pre_frac[33] ? 8'd3 : | |
pre_frac[32] ? 8'd4 : pre_frac[31] ? 8'd5 : | |
pre_frac[30] ? 8'd6 : pre_frac[29] ? 8'd7 : | |
pre_frac[28] ? 8'd8 : pre_frac[27] ? 8'd9 : | |
pre_frac[26] ? 8'd10 : pre_frac[25] ? 8'd11 : | |
pre_frac[24] ? 8'd12 : pre_frac[23] ? 8'd13 : | |
pre_frac[22] ? 8'd14 : pre_frac[21] ? 8'd15 : | |
pre_frac[20] ? 8'd16 : pre_frac[19] ? 8'd17 : | |
pre_frac[18] ? 8'd18 : pre_frac[17] ? 8'd19 : | |
pre_frac[16] ? 8'd20 : pre_frac[15] ? 8'd21 : | |
pre_frac[14] ? 8'd22 : pre_frac[13] ? 8'd23 : | |
pre_frac[12] ? 8'd24 : pre_frac[11] ? 8'd25 : | |
pre_frac[10] ? 8'd26 : pre_frac[9] ? 8'd27 : | |
pre_frac[8] ? 8'd28 : pre_frac[7] ? 8'd29 : | |
pre_frac[6] ? 8'd30 : pre_frac[5] ? 8'd31 : | |
pre_frac[4] ? 8'd32 : pre_frac[3] ? 8'd33 : | |
pre_frac[2] ? 8'd34 : pre_frac[1] ? 8'd35 : | |
pre_frac[0] ? 8'd36 : 8'd37; | |
wire [53:0] pre_frac_shft, uflow_shift; | |
// the shift +1 is because high order bit is not stored, but implied | |
assign pre_frac_shft = {pre_frac, 17'b0} << (shft_amt+1); //? shft_amt+1 | |
assign uflow_shift = {pre_frac, 17'b0} << (shft_amt); //? shft_amt for overflow | |
assign oSum_f = pre_frac_shft[53:36]; | |
wire [7:0] oSum_e; | |
assign oSum_e = buf_larger_exp - shft_amt + 8'b1; | |
// Detect underflow | |
wire underflow; | |
// this incorrectly sets uflow for 10-10.1 | |
//assign underflow = ~oSum_e[7] && buf_larger_exp[7] && (shft_amt != 8'b0); | |
// if top bit of matissa is not set, then denorm | |
assign underflow = ~uflow_shift[53]; | |
always @(posedge iCLK) begin | |
oSum <= (buf_A_e_zero && buf_B_e_zero) ? 27'b0 : | |
buf_A_e_zero ? buf_B : | |
buf_B_e_zero ? buf_A : | |
underflow ? 27'b0 : | |
(pre_frac == 0) ? 27'b0 : | |
{buf_oSum_s, oSum_e, oSum_f}; | |
end //output update | |
endmodule | |
/// end ///////////////////////////////////////////////////////////////////// |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment