| module fpga #( |
| parameter MX = 7, |
| parameter MY = 8, |
| parameter NUM_CONFIG_REGIONS = 2, |
| // There are 38 IO pins in Caravel, so we distribute them around the chip. |
| parameter IO_NORTH = 10, // Actually 9 |
| parameter IO_SOUTH = 8, // Actually 0 |
| parameter IO_EAST = 10, // Actually 15 |
| parameter IO_WEST = 10, // Actually 14 |
| |
| // SRAM |
| |
| // MAC |
| parameter MAC_CONF_WIDTH = 4, |
| parameter MAC_MIN_WIDTH = 8, |
| parameter MAC_MULT_WIDTH = 2*MAC_MIN_WIDTH, |
| parameter MAC_ACC_WIDTH = 2*MAC_MULT_WIDTH, |
| parameter MAC_INT_WIDTH = 5*MAC_MIN_WIDTH, |
| parameter DCB_NS_W = 192, |
| parameter IX_IN_OUT_W = DCB_NS_W+2, |
| parameter DCB_DATAIN = 8, |
| parameter DCB_DATAOUT = 8, |
| |
| // CLBs |
| parameter S_XX_BASE = 4, |
| parameter NUM_LUTS = 4, |
| |
| parameter WS = 4, |
| parameter WD = 8, |
| parameter WG = 0, |
| parameter CLBIN = 10, |
| parameter CLBIN_EACH_SIDE = 10, |
| parameter CLBOUT = 5, |
| parameter CLBOUT_EACH_SIDE = 5, |
| parameter CLBOS = 4, |
| parameter CLBOD = 4, |
| parameter CLBX = 1 |
| )( |
| inout [IO_NORTH-1:0] gpio_north, |
| inout [IO_SOUTH-1:0] gpio_south, |
| inout [IO_WEST-1:0] gpio_west, |
| inout [IO_EAST-1:0] gpio_east, |
| |
| // Global signals |
| input wb_clk_i, |
| input wb_rst_i, |
| |
| // Wishbone signals |
| input wbs_stb_i, |
| input wbs_cyc_i, |
| input wbs_we_i, |
| // Write mask |
| input [3:0] wbs_sel_i, |
| input [31:0] wbs_data_i, |
| input [31:0] wbs_addr_i, |
| output wbs_ack_o, |
| output [31:0] wbs_data_o |
| |
| ); |
| |
| wire clk; |
| wire rst; |
| wire en; |
| |
| /* We take the wishbone clock to be our fabric clock, I guess. |
| * rst is the first GPIO pin. |
| * en is the second GPIO pin. |
| */ |
| |
| assign clk = wb_clk_i; |
| assign rst = gpio_north[9]; |
| assign en = gpio_north[8]; |
| |
| /* This FPGA lays out tiles in the following fixed configuration (not to |
| * scale). |
| * |
| * +-----------++-----------++-----------+ |
| * 5 | clb_tile || clb_tile || clb_tile | |
| * +-----------++-----------++-----------+ |
| * +-----------++-----------++-----------+ |
| * 4 | clb_tile || clb_tile || clb_tile | |
| * +-----------++-----------++-----------+ |
| * ^ +-----------++-----------++-----------+ |
| * | 3 | clb_tile || clb_tile || clb_tile | |
| * MY +-----------++-----------++-----------+ |
| * | +-----------++-----------++-----------+ |
| * v 2 | clb_tile || clb_tile || clb_tile | |
| * +-----------++-----------++-----------+ |
| * +-----------++-----------++-----------+ |
| * 1 | clb_tile || clb_tile || clb_tile | |
| * +-----------++-----------++-----------+ |
| * +-----------++-----------++-----------+ |
| * 0 | clb_tile || clb_tile || clb_tile | |
| * +-----------++-----------++-----------+ |
| * 0 1 2 |
| * <--- MX ---> |
| * |
| */ |
| |
| // Interconnect wires go between switch boxes and connection boxes. |
| wire [WS-1:0] ix_single_ns[MY :0][MX-1:0]; |
| wire [WS-1:0] ix_single_ew[MY-1:0][MX :0]; |
| wire [WD-1:0] ix_double_ns[MY :0][MX-1:0]; |
| wire [WD-1:0] ix_double_ew[MY-1:0][MX :0]; |
| |
| // Direct connection wires go between connection boxes and CLBs. |
| wire [CLBOUT_EACH_SIDE-1:0] dc_ns[MY:0][MX-1:0]; |
| wire [CLBIN_EACH_SIDE-1:0] dc_sn[MY:0][MX-1:0]; |
| wire [CLBOUT_EACH_SIDE-1:0] dc_ew[MY-1:0][MX:0]; |
| wire [CLBIN_EACH_SIDE-1:0] dc_we[MY-1:0][MX:0]; |
| |
| // Configuration enable signals, one per column. |
| wire [MX-1:0] col_cen; |
| wire [MX-1:0] col_set[MY:0]; |
| wire [MX-1:0] col_shift[MY:0]; |
| |
| wire [MX-1:0] carry[MY:0]; |
| |
| genvar x; |
| genvar y; |
| generate |
| for (x = 0; x < MX; x = x + 1) begin:X |
| for (y = 0; y < MY; y = y + 1) begin:Y |
| clb_tile #( |
| .S_XX_BASE(S_XX_BASE), |
| .NUM_LUTS(NUM_LUTS), |
| .WS(WS), |
| .WD(WD), |
| .WG(WG), |
| .CLBIN(CLBIN), |
| .CLBIN_EACH_SIDE(CLBIN_EACH_SIDE), |
| .CLBOUT(CLBOUT), |
| .CLBOUT_EACH_SIDE(CLBOUT_EACH_SIDE), |
| .CLBOS(CLBOS), |
| .CLBOD(CLBOD), |
| .CLBX(CLBX) |
| ) clb ( |
| .clk(clk), |
| .rst(rst), |
| .cen(col_cen[x]), |
| |
| .north_single(ix_single_ns[y+1][ x]), |
| .east_single( ix_single_ew[ y][x+1]), |
| .south_single(ix_single_ns[ y][ x]), |
| .west_single( ix_single_ew[ y][ x]), |
| |
| .north_double(ix_double_ns[y+1][ x]), |
| .east_double( ix_double_ew[ y][x+1]), |
| .south_double(ix_double_ns[ y][ x]), |
| .west_double( ix_double_ew[ y][ x]), |
| |
| // The names are made up and the points don't matter! |
| .cb_north_in( dc_ns[y+1][ x]), |
| .clb_south_out(dc_ns[ y][ x]), |
| |
| .clb_south_in( dc_sn[ y][ x]), |
| .cb_north_out( dc_sn[y+1][ x]), |
| |
| .clb_west_in( dc_we[ y][ x]), |
| .cb_east_out( dc_we[ y][x+1]), |
| |
| .cb_east_in( dc_ew[ y][x+1]), |
| .clb_west_out( dc_ew[ y][ x]), |
| |
| .carry_in( carry[y ][ x]), |
| .carry_out( carry[y+1][ x]), |
| |
| .shift_in_hard(col_shift[ y][ x]), |
| .set_in_hard( col_set [ y][ x]), |
| |
| .shift_out_hard( col_shift[y+1][ x]), |
| .set_out_hard( col_set [y+1][ x]) |
| ); |
| end |
| end |
| endgenerate |
| |
| //mac_tile #( |
| // .MAC_CONF_WIDTH(MAC_CONF_WIDTH), |
| // .MAC_MIN_WIDTH(MAC_MIN_WIDTH), |
| // .MAC_MULT_WIDTH(MAC_MULT_WIDTH), |
| // .MAC_ACC_WIDTH(MAC_ACC_WIDTH), |
| // .MAC_INT_WIDTH(MAC_INT_WIDTH), |
| // .DCB_NS_W(DCB_NS_W), |
| // .IX_IN_OUT_W(IX_IN_OUT_W), |
| // .DCB_DATAIN(DCB_DATAIN), |
| // .DCB_DATAOUT(DCB_DATAOUT) |
| //) mac ( |
| // .north(), |
| // .south(), |
| // .east(), |
| // .west() |
| //); |
| |
| wire [3:0] wb_set_out[NUM_CONFIG_REGIONS-1:0]; |
| wire [3:0] wb_shift_out[NUM_CONFIG_REGIONS-1:0]; |
| wire wb_cen_out[NUM_CONFIG_REGIONS-1:0]; |
| wire [31:0] wbs_data_o_internal[NUM_CONFIG_REGIONS-1:0]; |
| wire wbs_ack_o_internal[NUM_CONFIG_REGIONS-1:0]; |
| |
| assign wbs_data_o = wbs_data_o_internal[0] | wbs_data_o_internal[1]; |
| assign wbs_ack_o = wbs_ack_o_internal[0] | wbs_ack_o_internal[1]; |
| |
| wishbone_configuratorinator_00 wishbonatron_00 ( |
| .wb_clk_i(wb_clk_i), |
| .wb_rst_i(wb_rst_i), |
| .wbs_cyc_i(wbs_cyc_i), |
| .wbs_stb_i(wbs_stb_i), |
| .wbs_we_i(wbs_we_i), |
| .wbs_sel_i(wbs_sel_i), |
| .wbs_data_i(wbs_data_i), |
| .wbs_addr_i(wbs_addr_i), |
| .wbs_ack_o(wbs_ack_o_internal[0]), |
| .wbs_data_o(wbs_data_o_internal[0]), |
| |
| .cen(wb_cen_out[0]), |
| .set_out(wb_set_out[0]), |
| .shift_out(wb_shift_out[0]) |
| ); |
| |
| wishbone_configuratorinator_10 wishbonatron_10 ( |
| .wb_clk_i(wb_clk_i), |
| .wb_rst_i(wb_rst_i), |
| .wbs_cyc_i(wbs_cyc_i), |
| .wbs_stb_i(wbs_stb_i), |
| .wbs_we_i(wbs_we_i), |
| .wbs_sel_i(wbs_sel_i), |
| .wbs_data_i(wbs_data_i), |
| .wbs_addr_i(wbs_addr_i), |
| .wbs_ack_o(wbs_ack_o_internal[1]), |
| .wbs_data_o(wbs_data_o_internal[1]), |
| |
| .cen(wb_cen_out[1]), |
| .set_out(wb_set_out[1]), |
| .shift_out(wb_shift_out[1]) |
| ); |
| |
| genvar i; |
| generate |
| for (i = 0; i < NUM_CONFIG_REGIONS; i = i + 1) begin:wb |
| assign col_set[0][4*i +: 4] = wb_set_out[i][3:0]; |
| assign col_shift[0][4*i +: 4] = wb_shift_out[i][3:0]; |
| assign col_cen[4*i +: 4] = {wb_cen_out[i], wb_cen_out[i], wb_cen_out[i], wb_cen_out[i]}; |
| end |
| endgenerate |
| |
| generate |
| for (x = 0; x < MX; x = x + 1) begin |
| assign gpio_north[x] = ix_single_ns[MY][x][0]; |
| assign gpio_south[x] = ix_single_ns[0][x][0]; |
| end |
| for (y = 0; y < MY; y = y + 1) begin |
| assign gpio_east[y] = ix_single_ew[y][MX][0]; |
| assign gpio_west[y] = ix_single_ew[y][ 0][0]; |
| end |
| endgenerate |
| |
| endmodule |