diff --git a/hw/efinix_fpga/debug_profile.wizard.json b/hw/efinix_fpga/debug_profile.wizard.json index 761e996..421efc5 100644 --- a/hw/efinix_fpga/debug_profile.wizard.json +++ b/hw/efinix_fpga/debug_profile.wizard.json @@ -3,12 +3,12 @@ { "name": "la0", "type": "la", - "uuid": "d0d972d74e3f4c45a9c473ba07318a8e", + "uuid": "2ec8ec3d274747939b82c28997a2ef1d", "trigin_en": false, "trigout_en": false, "auto_inserted": true, "capture_control": false, - "data_depth": 2048, + "data_depth": 128, "input_pipeline": 1, "probes": [ { @@ -40,6 +40,21 @@ "name": "cpu_sync", "width": 1, "probe_type": 1 + }, + { + "name": "cpu_data_out", + "width": 8, + "probe_type": 1 + }, + { + "name": "cpu_data_oe", + "width": 8, + "probe_type": 1 + }, + { + "name": "cpu_phi2", + "width": 1, + "probe_type": 1 } ] } @@ -309,6 +324,91 @@ "name": "la0_probe5", "net": "cpu_sync", "path": [] + }, + { + "name": "la0_probe6[0]", + "net": "cpu_data_out[0]", + "path": [] + }, + { + "name": "la0_probe6[1]", + "net": "cpu_data_out[1]", + "path": [] + }, + { + "name": "la0_probe6[2]", + "net": "cpu_data_out[2]", + "path": [] + }, + { + "name": "la0_probe6[3]", + "net": "cpu_data_out[3]", + "path": [] + }, + { + "name": "la0_probe6[4]", + "net": "cpu_data_out[4]", + "path": [] + }, + { + "name": "la0_probe6[5]", + "net": "cpu_data_out[5]", + "path": [] + }, + { + "name": "la0_probe6[6]", + "net": "cpu_data_out[6]", + "path": [] + }, + { + "name": "la0_probe6[7]", + "net": "cpu_data_out[7]", + "path": [] + }, + { + "name": "la0_probe7[0]", + "net": "cpu_data_oe[0]", + "path": [] + }, + { + "name": "la0_probe7[1]", + "net": "cpu_data_oe[1]", + "path": [] + }, + { + "name": "la0_probe7[2]", + "net": "cpu_data_oe[2]", + "path": [] + }, + { + "name": "la0_probe7[3]", + "net": "cpu_data_oe[3]", + "path": [] + }, + { + "name": "la0_probe7[4]", + "net": "cpu_data_oe[4]", + "path": [] + }, + { + "name": "la0_probe7[5]", + "net": "cpu_data_oe[5]", + "path": [] + }, + { + "name": "la0_probe7[6]", + "net": "cpu_data_oe[6]", + "path": [] + }, + { + "name": "la0_probe7[7]", + "net": "cpu_data_oe[7]", + "path": [] + }, + { + "name": "la0_probe8", + "net": "cpu_phi2", + "path": [] } ] } @@ -322,7 +422,7 @@ ], "session": { "wizard": { - "data_depth": 2048, + "data_depth": 128, "capture_control": false, "selected_nets": [ { @@ -376,6 +476,34 @@ "selected_probe_type": "DATA AND TRIGGER", "child": [], "path": [] + }, + { + "name": "cpu_data_out", + "width": 8, + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [], + "net_idx_left": 7, + "net_idx_right": 0 + }, + { + "name": "cpu_data_oe", + "width": 8, + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [], + "net_idx_left": 7, + "net_idx_right": 0 + }, + { + "name": "cpu_phi2", + "width": 1, + "clk_domain": "clk_2", + "selected_probe_type": "DATA AND TRIGGER", + "child": [], + "path": [] } ], "top_module": "super6502", diff --git a/hw/efinix_fpga/ip/bram/bram_decompose.vh b/hw/efinix_fpga/ip/bram/bram_decompose.vh new file mode 100644 index 0000000..5416b58 --- /dev/null +++ b/hw/efinix_fpga/ip/bram/bram_decompose.vh @@ -0,0 +1,111 @@ +localparam FAMILY = 0; //0:Trion, 1:Titanium +localparam ADDR_WIDTH_A = 8; +localparam DATA_WIDTH_A = 8; +localparam ADDR_WIDTH_B = 8; +localparam DATA_WIDTH_B = 8; +localparam TOTAL_SIZE_A = 256; +localparam TOTAL_SIZE_B = 256; +localparam BYTEEN_WIDTH = 1; +localparam BYTEEN_WIDTH_A = 1; +localparam BYTEEN_WIDTH_B = 1; +localparam GROUP_DATA_WIDTH = 8; +localparam GROUP_DATA_WIDTH_A = 0; +localparam GROUP_DATA_WIDTH_B = 0; +localparam GROUP_COLUMNS = 1; +localparam bram_table_size = 1; +localparam bram_table_loop_mode = 1; +localparam bram_mapping_size = 1; +localparam rMux_mapping_A_size = 0; +localparam rMux_mapping_B_size = 0; +localparam wen_sel_mapping_A_size = 0; +localparam wen_sel_mapping_B_size = 0; +localparam data_mapping_table_A_size = 0; +localparam data_mapping_table_B_size = 0; +localparam address_mapping_table_A_size = 0; +localparam address_mapping_table_B_size = 0; + + +function integer bram_feature_table; +input integer index;//Mode type +input integer val_; //Address_width, data_width, en_width, reserved +case (index) +0: bram_feature_table=(val_==0)?8:(val_==1)?20:(val_==2)?2:(val_==3)?0:(val_==4)?0:0; +1: bram_feature_table=(val_==0)?9:(val_==1)?10:(val_==2)?1:(val_==3)?0:(val_==4)?0:0; +2: bram_feature_table=(val_==0)?10:(val_==1)?5:(val_==2)?1:(val_==3)?0:(val_==4)?0:0; +3: bram_feature_table=(val_==0)?8:(val_==1)?16:(val_==2)?2:(val_==3)?0:(val_==4)?1:0; +4: bram_feature_table=(val_==0)?9:(val_==1)?8:(val_==2)?1:(val_==3)?0:(val_==4)?1:0; +5: bram_feature_table=(val_==0)?10:(val_==1)?4:(val_==2)?1:(val_==3)?0:(val_==4)?1:0; +6: bram_feature_table=(val_==0)?11:(val_==1)?2:(val_==2)?1:(val_==3)?0:(val_==4)?1:0; +7: bram_feature_table=(val_==0)?12:(val_==1)?1:(val_==2)?1:(val_==3)?0:(val_==4)?1:0; + endcase +endfunction + + +function integer bram_decompose_table; +input integer index;//Mode type +input integer val_; //Port A index, Port B Index, Number of Items in Loop, Port A Start, Port B Start, reserved +case (index) + 0: bram_decompose_table=(val_==0)? 0:(val_==1)? 0:(val_==2)? 1:(val_==3)? 0:(val_==4)? 0:0; + endcase +endfunction + + +function integer bram_mapping_table; +input integer index;//Mode type +input integer val_;// Y, X, DataA [MSB], DataA [LSB], DataA Repeat, Read MuxA, Wen0 SelA, Wen1 SelA, Byteen A, DataB [MSB], DataB [LSB], DataB Repeat, Read MuxB, Wen0 SelB, Wen1 SelB, Byteen B, Addr Width A Data Width A Addr Width B Data Width B +case (index) + 0: bram_mapping_table=(val_== 0)? 0:(val_== 1)? 0:(val_== 2)? 7:(val_== 3)? 0:(val_== 4)? 0:(val_== 5)? 0:(val_== 6)? 0:(val_== 7)? 0:(val_== 8)? 0:(val_== 9)? 7:(val_==10)? 0:(val_==11)? 0:(val_==12)? 0:(val_==13)? 0:(val_==14)? 0:(val_==15)? 0:(val_==16)? 8:(val_==17)? 20:(val_==18)? 8:(val_==19)? 20:0; + endcase +endfunction + + +function integer rMux_mapping_table_A; +input integer index;//Mode type +input integer val_;// PortA Addr MSB, PortA Addr LSB, DataA[MSB], DataA[LSB], MuxSelA[MSB], MuxSelA[LSB], Bypass, +rMux_mapping_table_A = 0; +endfunction + + +function integer rMux_mapping_table_B; +input integer index;//Mode type +input integer val_;// PortB Addr MSB, PortB Addr LSB, DataB[MSB], DataB[LSB], MuxSelB[MSB], MuxSelB[LSB], Bypass, +rMux_mapping_table_B = 0; +endfunction + + +function integer wen_sel_mapping_table_A; +input integer index;//Mode type +input integer val_;// PortA Addr MSB, PortA Addr LSB, WenSelA[MSB], WenSelA[LSB], Bypass, +wen_sel_mapping_table_A = 0; +endfunction + + +function integer wen_sel_mapping_table_B; +input integer index;//Mode type +input integer val_;// PortB Addr MSB, PortB Addr LSB, WenSelB[MSB], WenSelB[LSB], Bypass, +wen_sel_mapping_table_B = 0; +endfunction + + +function integer data_mapping_table_A; +input integer index;// +data_mapping_table_A = 0; +endfunction + + +function integer data_mapping_table_B; +input integer index;// +data_mapping_table_B = 0; +endfunction + + +function integer address_mapping_table_A; +input integer index;// +address_mapping_table_A = 0; +endfunction + + +function integer address_mapping_table_B; +input integer index;// +address_mapping_table_B = 0; +endfunction diff --git a/hw/efinix_fpga/ip/bram/bram_ini.vh b/hw/efinix_fpga/ip/bram/bram_ini.vh new file mode 100644 index 0000000..01680d1 --- /dev/null +++ b/hw/efinix_fpga/ip/bram/bram_ini.vh @@ -0,0 +1,49 @@ + +function [255:0] bram_ini_table; +input integer index;//Mode type +input integer val_; //Port A index, Port B Index, Number of Items in Loop, Port A Start, Port B Start, reserved +case (index) + 0: bram_ini_table= +(val_== 0)?256'h0000000000000000000000000000000000000000000000000000010004c000ea: +(val_== 1)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_== 2)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_== 3)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_== 4)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_== 5)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_== 6)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_== 7)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_== 8)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_== 9)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==10)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==11)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==12)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==13)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==14)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==15)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==16)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==17)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==18)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==19)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==20)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==21)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==22)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==23)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==24)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==25)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==26)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==27)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==28)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==29)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==30)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==31)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==32)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==33)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==34)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==35)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==36)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==37)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==38)?256'h0000000000000000000000000000000000000000000000000000000000000000: +(val_==39)?256'h0000000000000000000000000000000000000000000000000000000000000000: +0; + endcase +endfunction diff --git a/hw/efinix_fpga/ip/bram/bram_primitive.v b/hw/efinix_fpga/ip/bram/bram_primitive.v new file mode 100644 index 0000000..ea04bcf --- /dev/null +++ b/hw/efinix_fpga/ip/bram/bram_primitive.v @@ -0,0 +1,281 @@ +//////////////////////////////////////////////////////////////////////////// +// _____ +// / _______ Copyright (C) 2013-2022 Efinix Inc. All rights reserved. +// / / \ +// / / .. / bram_primitive.v +// / / .' / +// __/ /.' / Description: +// __ \ / +// /_/ /\ \_____/ / +// ____/ \_______/ +// +// ******************************* +// Revisions: +// 0.0 Initial rev +// +// ******************************* + +module bram_primitive #( + parameter FAMILY = 0, //0:Trion, 1:Titanium + + //Trion and Titanium parameters + parameter WRITE_WIDTH = 16, // write width + parameter WCLK_POLARITY = 1'b1, //wclk polarity, 0:falling edge, 1:rising edge + parameter WCLKE_POLARITY = 1'b1, //wclke polarity, 0:active low, 1:active high + parameter WE_POLARITY = 1'b1, //we polarity, 0:active low, 1:active high + parameter WRITE_MODE = "READ_FIRST",//write mode, "READ_FIRST" :Old memory content is read. (default) + // "WRITE_FIRST" :Write data is passed to the read port. + // "READ_UNKNOWN": Read and writes are unsynchronized, therefore, the results of the address can conflict. + parameter READ_WIDTH = 16, // read width + parameter RCLK_POLARITY = 1'b1, // rclk polarity, 0:falling edge, 1:rising edge + parameter RE_POLARITY = 1'b1, // re polarity, 0:active low , 1:active high + parameter OUTPUT_REG = 1'b0, // Output register enable, 1:add pipe-line read register + + //Titanium extra paramters + parameter RST_POLARITY = 1'b1, // rst polarity + parameter RESET_RAM = "ASYNC", // reset mode on ram, "NONE": RST signals does not affect the RAM output. + // "ASYNC": RAM output resets asynchronously to RCLK. + // "SYNC": RAM output resets synchronously to RCLK. + parameter RESET_OUTREG = "ASYNC", // reset mode on output register + // "NONE": RST signals does not affect the RAM output register + // "ASYNC": RAM output register resets asynchronously to RCLK. + parameter WADDREN_POLARITY = 1'b1, // waddren polarity + parameter RADDREN_POLARITY = 1'b1, // raddren polarity + + //Titanium Option for byte enable in WEN width = 2 when it is Mode 512x16 or 512x20 + parameter WEN_WIDTH = 1, + + parameter ini_index = 0 + +) +( + //Trion and Titanium ports + WCLK, // Write clock input + WCLKE, // Write clock-enable input + WE, // Write-enable input + WADDR, // Write address input + WDATA, // Write data input + + RCLK, // Read clock input + RE, // Read-enable input + RADDR, // Read address input + RDATA, // Read data output + + //Titanium extra ports + RST, // reset + WADDREN, // write address enable + RADDREN // read address enable + + ); +function integer address_map; +input integer index;//Input data width parameter +input integer type; //Mapped data width, Mapped Address Width for Ram 5K(Trion), Mapped Address Width for Ram 10K(Titanium), WEN width for Ram 5K(Trion), WEN width for Ram 10K(Titanium) +case (index) +0 : address_map= (type==0)? 1 :(type==1)? 12 :(type==2)? 13 :1; +1 : address_map= (type==0)? 1 :(type==1)? 12 :(type==2)? 13 :1; +2 : address_map= (type==0)? 2 :(type==1)? 11 :(type==2)? 12 :1; +3 : address_map= (type==0)? 4 :(type==1)? 10 :(type==2)? 11 :1; +4 : address_map= (type==0)? 4 :(type==1)? 10 :(type==2)? 11 :1; +5 : address_map= (type==0)? 5 :(type==1)? 10 :(type==2)? 11 :1; +6 : address_map= (type==0)? 8 :(type==1)? 9 :(type==2)? 10 :1; +7 : address_map= (type==0)? 8 :(type==1)? 9 :(type==2)? 10 :1; +8 : address_map= (type==0)? 8 :(type==1)? 9 :(type==2)? 10 :1; +9 : address_map= (type==0)? 10 :(type==1)? 9 :(type==2)? 10 :1; +10 : address_map= (type==0)? 10 :(type==1)? 9 :(type==2)? 10 :1; +11 : address_map= (type==0)? 16 :(type==1)? 8 :(type==2)? 9 :1; +12 : address_map= (type==0)? 16 :(type==1)? 8 :(type==2)? 9 :1; +13 : address_map= (type==0)? 16 :(type==1)? 8 :(type==2)? 9 :1; +14 : address_map= (type==0)? 16 :(type==1)? 8 :(type==2)? 9 :1; +15 : address_map= (type==0)? 16 :(type==1)? 8 :(type==2)? 9 :1; +16 : address_map= (type==0)? 16 :(type==1)? 8 :(type==2)? 9 :1; +17 : address_map= (type==0)? 20 :(type==1)? 8 :(type==2)? 9 :1; +18 : address_map= (type==0)? 20 :(type==1)? 8 :(type==2)? 9 :1; +19 : address_map= (type==0)? 20 :(type==1)? 8 :(type==2)? 9 :1; +20 : address_map= (type==0)? 20 :(type==1)? 8 :(type==2)? 9 :1; + endcase +endfunction + +localparam WRITE_DATA_WIDTH = address_map(WRITE_WIDTH,0); +localparam WRITE_ADDRESS_WIDTH = address_map(WRITE_WIDTH,(FAMILY==0)?1:2); + +localparam READ_DATA_WIDTH = address_map(READ_WIDTH,0); +localparam READ_ADDRESS_WIDTH = address_map(READ_WIDTH,(FAMILY==0)?1:2); + + +//Trion and Titanium ports +input WCLK; // Write clock input +input WCLKE; // Write clock-enable input +input [WEN_WIDTH-1:0] WE; // Write-enable input +input [WRITE_ADDRESS_WIDTH-1:0] WADDR; // Write address input +input [WRITE_DATA_WIDTH-1:0] WDATA; // Write data input + +input RCLK; // Read clock input +input RE; // Read-enable input +input [READ_ADDRESS_WIDTH-1:0] RADDR; // Read address input +output[READ_DATA_WIDTH-1:0]RDATA; // Read data output + +//Titanium extra ports +input RST; // reset +input WADDREN; // write address enable +input RADDREN; // read address enable + + +`include "bram_ini.vh" +parameter filePath = "bram_ini.vh"; +integer fd; + + generate + initial begin + fd = $fopen(filePath, "r"); + $fclose(fd); + end + + + if (FAMILY==0) + begin + EFX_RAM_5K # ( + .WRITE_WIDTH (WRITE_WIDTH), + .WCLK_POLARITY (WCLK_POLARITY), + .WCLKE_POLARITY (WCLKE_POLARITY), + .WE_POLARITY (WE_POLARITY), + .WRITE_MODE (WRITE_MODE), + + .READ_WIDTH (READ_WIDTH), + .RCLK_POLARITY (RCLK_POLARITY), + .RE_POLARITY (RE_POLARITY), + .OUTPUT_REG (OUTPUT_REG), + + + .INIT_0 (bram_ini_table(ini_index,16'h0 )), + .INIT_1 (bram_ini_table(ini_index,16'h1 )), + .INIT_2 (bram_ini_table(ini_index,16'h2 )), + .INIT_3 (bram_ini_table(ini_index,16'h3 )), + .INIT_4 (bram_ini_table(ini_index,16'h4 )), + .INIT_5 (bram_ini_table(ini_index,16'h5 )), + .INIT_6 (bram_ini_table(ini_index,16'h6 )), + .INIT_7 (bram_ini_table(ini_index,16'h7 )), + .INIT_8 (bram_ini_table(ini_index,16'h8 )), + .INIT_9 (bram_ini_table(ini_index,16'h9 )), + .INIT_A (bram_ini_table(ini_index,16'hA )), + .INIT_B (bram_ini_table(ini_index,16'hB )), + .INIT_C (bram_ini_table(ini_index,16'hC )), + .INIT_D (bram_ini_table(ini_index,16'hD )), + .INIT_E (bram_ini_table(ini_index,16'hE )), + .INIT_F (bram_ini_table(ini_index,16'hF )), + .INIT_10 (bram_ini_table(ini_index,16'h10)), + .INIT_11 (bram_ini_table(ini_index,16'h11)), + .INIT_12 (bram_ini_table(ini_index,16'h12)), + .INIT_13 (bram_ini_table(ini_index,16'h13)) + ) + ram5k ( + .WCLK(WCLK), // Write clock input + .WE(WE[0]), // Write-enable input + .WCLKE(WCLKE), // Write clock-enable input + .WADDR(WADDR), // Write address input + .WDATA(WDATA), // Write data input + + .RCLK(RCLK), // Read clock input + .RE(RE), // Read-enable input + .RADDR(RADDR), // Read address input + .RDATA(RDATA) // Read data output + ); + end + else + begin + + wire [1:0]w_wen_ram10; + assign w_wen_ram10[0] = WE[0]; + + if (WEN_WIDTH>1) + assign w_wen_ram10[1] = WE[1]; + else if (WRITE_DATA_WIDTH >= 16 ) + assign w_wen_ram10[1] = WE[0]; + else + assign w_wen_ram10[1] = 1'b0; + + EFX_RAM10 # ( + + .WRITE_WIDTH (WRITE_WIDTH), + .WCLK_POLARITY (WCLK_POLARITY), + .WCLKE_POLARITY (WCLKE_POLARITY), + .WE_POLARITY (WE_POLARITY), + .WRITE_MODE (WRITE_MODE), + + .READ_WIDTH (READ_WIDTH), + .RCLK_POLARITY (RCLK_POLARITY), + .RE_POLARITY (RE_POLARITY), + .OUTPUT_REG (OUTPUT_REG), + + //Titanium extra paramters + .RST_POLARITY (RST_POLARITY), // rst polarity + .RESET_RAM (RESET_RAM), // reset mode on ram + .RESET_OUTREG (RESET_OUTREG), // reset mode on output register + .WADDREN_POLARITY (WADDREN_POLARITY), // waddren polarity + .RADDREN_POLARITY (RADDREN_POLARITY), // raddren polarity + + + .INIT_0 (bram_ini_table(ini_index, 16'h0 )), + .INIT_1 (bram_ini_table(ini_index, 16'h1 )), + .INIT_2 (bram_ini_table(ini_index, 16'h2 )), + .INIT_3 (bram_ini_table(ini_index, 16'h3 )), + .INIT_4 (bram_ini_table(ini_index, 16'h4 )), + .INIT_5 (bram_ini_table(ini_index, 16'h5 )), + .INIT_6 (bram_ini_table(ini_index, 16'h6 )), + .INIT_7 (bram_ini_table(ini_index, 16'h7 )), + .INIT_8 (bram_ini_table(ini_index, 16'h8 )), + .INIT_9 (bram_ini_table(ini_index, 16'h9 )), + .INIT_A (bram_ini_table(ini_index, 16'hA )), + .INIT_B (bram_ini_table(ini_index, 16'hB )), + .INIT_C (bram_ini_table(ini_index, 16'hC )), + .INIT_D (bram_ini_table(ini_index, 16'hD )), + .INIT_E (bram_ini_table(ini_index, 16'hE )), + .INIT_F (bram_ini_table(ini_index, 16'hF )), + .INIT_10 (bram_ini_table(ini_index, 16'h10)), + .INIT_11 (bram_ini_table(ini_index, 16'h11)), + .INIT_12 (bram_ini_table(ini_index, 16'h12)), + .INIT_13 (bram_ini_table(ini_index, 16'h13)), + .INIT_14 (bram_ini_table(ini_index, 16'h14)), + .INIT_15 (bram_ini_table(ini_index, 16'h15)), + .INIT_16 (bram_ini_table(ini_index, 16'h16)), + .INIT_17 (bram_ini_table(ini_index, 16'h17)), + .INIT_18 (bram_ini_table(ini_index, 16'h18)), + .INIT_19 (bram_ini_table(ini_index, 16'h19)), + .INIT_1A (bram_ini_table(ini_index, 16'h1A)), + .INIT_1B (bram_ini_table(ini_index, 16'h1B)), + .INIT_1C (bram_ini_table(ini_index, 16'h1C)), + .INIT_1D (bram_ini_table(ini_index, 16'h1D)), + .INIT_1E (bram_ini_table(ini_index, 16'h1E)), + .INIT_1F (bram_ini_table(ini_index, 16'h1F)), + .INIT_20 (bram_ini_table(ini_index, 16'h20)), + .INIT_21 (bram_ini_table(ini_index, 16'h21)), + .INIT_22 (bram_ini_table(ini_index, 16'h22)), + .INIT_23 (bram_ini_table(ini_index, 16'h23)), + .INIT_24 (bram_ini_table(ini_index, 16'h24)), + .INIT_25 (bram_ini_table(ini_index, 16'h25)), + .INIT_26 (bram_ini_table(ini_index, 16'h26)), + .INIT_27 (bram_ini_table(ini_index, 16'h27)) + + ) + ram10k( + + .WCLK(WCLK), // Write clock input + .WE(w_wen_ram10), // Write-enable input + .WCLKE(WCLKE), // Write clock-enable input + .WADDR(WADDR), // Write address input + .WDATA(WDATA), // Write data input + + .RCLK(RCLK), // Read clock input + .RE(RE), // Read-enable input + .RADDR(RADDR), // Read address input + .RDATA(RDATA), // Read data output + + //Titanium extra ports + .RST (RST), // reset + .WADDREN (WADDREN), // write address enable + .RADDREN (RADDREN) // read address enable + + ); + end + endgenerate + +endmodule \ No newline at end of file diff --git a/hw/efinix_fpga/ip/bram/bram_wrapper_mwm.v b/hw/efinix_fpga/ip/bram/bram_wrapper_mwm.v new file mode 100644 index 0000000..d4b0782 --- /dev/null +++ b/hw/efinix_fpga/ip/bram/bram_wrapper_mwm.v @@ -0,0 +1,635 @@ +//////////////////////////////////////////////////////////////////////////// +// _____ +// / _______ Copyright (C) 2013-2022 Efinix Inc. All rights reserved. +// / / \ +// / / .. / tb_top.v +// / / .' / +// __/ /.' / Description: +// __ \ / +// /_/ /\ \_____/ / +// ____/ \_______/ +// +// ******************************* +// Revisions: +// 0.0 Initial rev +// +// ******************************* + +module bram_wrapper_mwm #( + //parameter FAMILY = 0, //0:Trion, 1:Titanium + + //Trion and Titanium parameters + parameter WCLK_POLARITY = 1'b1, //wclk polarity, 0:falling edge, 1:rising edge + parameter WCLKE_POLARITY = 1'b1, //wclke polarity, 0:active low, 1:active high + parameter WE_POLARITY = 1'b1, //we polarity, 0:active low, 1:active high + parameter WRITE_MODE = "READ_FIRST",//write mode, "READ_FIRST" :Old memory content is read. (default) + // "WRITE_FIRST" :Write data is passed to the read port. + // "READ_UNKNOWN": Read and writes are unsynchronized, therefore, the results of the address can conflict. + parameter RCLK_POLARITY = 1'b1, // rclk polarity, 0:falling edge, 1:rising edge + parameter RE_POLARITY = 1'b1, // re polarity, 0:active low , 1:active high + parameter OUTPUT_REG = 1'b0, // Output register enable, 1:add pipe-line read register + + parameter BYTEEN_POLARITY = 1'b1, // byteen polarity 0:active low, 1:active high + + //Titanium extra paramters + parameter RST_POLARITY = 1'b1, // rst polarity + parameter RESET_RAM = "ASYNC", // reset mode on ram, "NONE": RST signals does not affect the RAM output. + // "ASYNC": RAM output resets asynchronously to RCLK. + // "SYNC": RAM output resets synchronously to RCLK. + parameter RESET_OUTREG = "ASYNC", // reset mode on output register + // "NONE": RST signals does not affect the RAM output register + // "ASYNC": RAM output register resets asynchronously to RCLK. + parameter WADDREN_POLARITY = 1'b1, // waddren polarity + parameter RADDREN_POLARITY = 1'b1 // raddren polarity + + + +) +( + //Trion and Titanium ports + wclk, // Write clock input + wclke, // Write clock-enable input + byteen, // Byteen input + we, // Write-enable input + waddr, // Write address input + wdata, // Write data input + + rclk, // Read clock input + re, // Read-enable input + raddr, // Read address input + rdata, // Read data output + + //Titanium extra ports + reset, // reset + waddren, // write address enable + raddren // read address enable + + ); + + +`include "bram_decompose.vh" +//`include "bram_feature.vh" + +input wclk; +input wclke; +input we; +input [BYTEEN_WIDTH-1:0] byteen; +input [ADDR_WIDTH_A-1:0 ] waddr; +input [DATA_WIDTH_A-1:0 ] wdata; + +input rclk; +input re; +input [ADDR_WIDTH_B-1:0 ] raddr; +output [DATA_WIDTH_B-1:0 ]rdata; + +input reset; +input waddren; +input raddren; + +wire [ADDR_WIDTH_A-1:0 ] w_waddr_map; +wire [DATA_WIDTH_A-1:0 ] w_wdata_map; + +wire [ADDR_WIDTH_B-1:0 ] w_raddr_map; +wire [DATA_WIDTH_B-1:0 ] w_rdata_map; + + +function integer get_current_row_index; +input integer row;//Mode type +integer x; + begin + get_current_row_index = 0; + for (x=0; x1) + begin + assign w_we[1] = ((we == WE_POLARITY) & wen_decode[WRSEL_INDEX] & (byteen[BYTEEN_INDEX] == BYTEEN_POLARITY) ) ? WE_POLARITY: !WE_POLARITY; + end + + bram_primitive #( + .FAMILY(FAMILY), //0:Trion, 1:Titanium + + //Trion and Titanium parameters + .WRITE_WIDTH(WDATA_WIDTH_ROW), + .WCLK_POLARITY(WCLK_POLARITY), + .WCLKE_POLARITY(WCLKE_POLARITY), + .WE_POLARITY(WE_POLARITY), + .WRITE_MODE(WRITE_MODE), + + .READ_WIDTH(RDATA_WIDTH_ROW), + .RCLK_POLARITY(RCLK_POLARITY), + .RE_POLARITY(RE_POLARITY), + .OUTPUT_REG(OUTPUT_REG), + + //Titanium extra paramters + .RST_POLARITY(RST_POLARITY), + .RESET_RAM(RESET_RAM), + .RESET_OUTREG(RESET_OUTREG), + .WADDREN_POLARITY(WADDREN_POLARITY), + .RADDREN_POLARITY(RADDREN_POLARITY), + + .WEN_WIDTH(WEN_WIDTH_ROW), + + .ini_index(DATA_MAP_INDEX) + + ) bram ( + //Trion and Titanium ports + .WCLK(wclk), // Write clock input + .WCLKE(wclke), // Write clock-enable input + .WE(w_we), // Write-enable input + .WADDR(w_waddr), // Write address input + .WDATA(w_wdata), // Write data input + + .RCLK(rclk), // Read clock input + .RE(re), // Read-enable input + .RADDR(w_raddr), // Read address input + .RDATA(w_rdata), // Read data output + + //Titanium extra ports + .RST(reset), // reset + .WADDREN(waddren), // write address enable + .RADDREN(raddren) // read address enable + ); + end + end + + end + else if (bram_table_loop_mode == 1 ) + begin:scan_row + for (gen_y=0; gen_y1) + begin + assign w_we[1] = ((we == WE_POLARITY) & wen_decode[WRSEL_INDEX] & (byteen[BYTEEN_INDEX] == BYTEEN_POLARITY)) ? WE_POLARITY: !WE_POLARITY;; + end + + bram_primitive #( + .FAMILY(FAMILY), //0:Trion, 1:Titanium + + //Trion and Titanium parameters + .WRITE_WIDTH(WDATA_WIDTH_ROW), + .WCLK_POLARITY(WCLK_POLARITY), + .WCLKE_POLARITY(WCLKE_POLARITY), + .WE_POLARITY(WE_POLARITY), + .WRITE_MODE(WRITE_MODE), + + .READ_WIDTH(RDATA_WIDTH_ROW), + .RCLK_POLARITY(RCLK_POLARITY), + .RE_POLARITY(RE_POLARITY), + .OUTPUT_REG(OUTPUT_REG), + + //Titanium extra paramters + .RST_POLARITY(RST_POLARITY), + .RESET_RAM(RESET_RAM), + .RESET_OUTREG(RESET_OUTREG), + .WADDREN_POLARITY(WADDREN_POLARITY), + .RADDREN_POLARITY(RADDREN_POLARITY), + + .WEN_WIDTH(WEN_WIDTH_ROW), + + .ini_index(DATA_MAP_INDEX) + + ) bram ( + //Trion and Titanium ports + .WCLK(wclk), // Write clock input + .WCLKE(wclke), // Write clock-enable input + .WE(w_we), // Write-enable input + .WADDR(w_waddr), // Write address input + .WDATA(w_wdata), // Write data input + + .RCLK(rclk), // Read clock input + .RE(re), // Read-enable input + .RADDR(w_raddr), // Read address input + .RDATA(w_rdata), // Read data output + + //Titanium extra ports + .RST(reset), // reset + .WADDREN(waddren), // write address enable + .RADDREN(raddren) // read address enable + ); + end + end + + end + endgenerate + + +endmodule \ No newline at end of file diff --git a/hw/efinix_fpga/ip/bram/efx_mem_decompose_script.py b/hw/efinix_fpga/ip/bram/efx_mem_decompose_script.py new file mode 100644 index 0000000..6c15234 --- /dev/null +++ b/hw/efinix_fpga/ip/bram/efx_mem_decompose_script.py @@ -0,0 +1,2809 @@ +""" + +Copyright (C) 2022 Efinix Inc. All rights reserved. + +No portion of this code may be reused, modified or +distributed in any way without the expressed written +consent of Efinix Inc. + +Modified on 28 September 2022 + +@author: Dragon Lai +""" +import sys +import os +import argparse +import math +import json + +from enum import Enum + + + + +class BRAM_TYPE(Enum): + EFX_RAM_5K = 0 + EFX_DPRAM_5K = 1 + EFX_RAM10 = 2 + EFX_DPRAM10 = 3 + +class COMPATIBLE(Enum): + LARGE = 0 + SMALL = 1 + +class FEATURE(Enum): + ADDRW = 0 + DATAW = 1 + WENW = 2 + BRAM_TYPE = 3 + COMPATIBLE= 4 + +#Address Width, Data Width , Number of wen, BRAM_TYPE, COMPATIBLE +EFX_RAM10_feature_table =[ +[9 ,20,2,BRAM_TYPE.EFX_RAM10.value,COMPATIBLE.LARGE.value], +[9 ,16,2,BRAM_TYPE.EFX_RAM10.value,COMPATIBLE.SMALL.value], +[10,10,1,BRAM_TYPE.EFX_RAM10.value,COMPATIBLE.LARGE.value], +[10,8 ,1,BRAM_TYPE.EFX_RAM10.value,COMPATIBLE.SMALL.value], +[11,5 ,1,BRAM_TYPE.EFX_RAM10.value,COMPATIBLE.LARGE.value], +[11,4 ,1,BRAM_TYPE.EFX_RAM10.value,COMPATIBLE.SMALL.value], +[12,2 ,1,BRAM_TYPE.EFX_RAM10.value,COMPATIBLE.SMALL.value], +[13,1 ,1,BRAM_TYPE.EFX_RAM10.value,COMPATIBLE.SMALL.value] +] + + +#Address Width, Data Width , Number of wen, BRAM_TYPE, COMPATIBLE +EFX_RAM10_MWM_feature_table =[ +[9 ,16,2,BRAM_TYPE.EFX_RAM10.value,COMPATIBLE.SMALL.value], +[10,8 ,1,BRAM_TYPE.EFX_RAM10.value,COMPATIBLE.SMALL.value], +[11,4 ,1,BRAM_TYPE.EFX_RAM10.value,COMPATIBLE.SMALL.value], +[12,2 ,1,BRAM_TYPE.EFX_RAM10.value,COMPATIBLE.SMALL.value], +[13,1 ,1,BRAM_TYPE.EFX_RAM10.value,COMPATIBLE.SMALL.value] +] + + +#Address Width, Data Width , Number of wen, BRAM_TYPE, COMPATIBLE +EFX_DPRAM10_feature_table =[ +[10,10,1,BRAM_TYPE.EFX_DPRAM10.value,COMPATIBLE.LARGE.value], +[11,5 ,1,BRAM_TYPE.EFX_DPRAM10.value,COMPATIBLE.LARGE.value], +[10,8 ,1,BRAM_TYPE.EFX_DPRAM10.value,COMPATIBLE.SMALL.value], +[11,4 ,1,BRAM_TYPE.EFX_DPRAM10.value,COMPATIBLE.SMALL.value], +[12,2 ,1,BRAM_TYPE.EFX_DPRAM10.value,COMPATIBLE.SMALL.value], +[13,1 ,1,BRAM_TYPE.EFX_DPRAM10.value,COMPATIBLE.SMALL.value] +] + +#Table for MixedDataWIdth +#Address Width, Data Width , Number of wen, BRAM_TYPE, COMPATIBLE +EFX_DPRAM10_MWM_feature_table =[ +[10,8 ,1,BRAM_TYPE.EFX_DPRAM10.value,COMPATIBLE.SMALL.value], +[11,4 ,1,BRAM_TYPE.EFX_DPRAM10.value,COMPATIBLE.SMALL.value], +[12,2 ,1,BRAM_TYPE.EFX_DPRAM10.value,COMPATIBLE.SMALL.value], +[13,1 ,1,BRAM_TYPE.EFX_DPRAM10.value,COMPATIBLE.SMALL.value] +] + +#Address Width, Data Width , Number of wen, BRAM_TYPE, COMPATIBLE +EFX_RAM_5K_feature_table =[ +[8 ,20,2,BRAM_TYPE.EFX_RAM_5K.value,COMPATIBLE.LARGE.value], +[9 ,10,1,BRAM_TYPE.EFX_RAM_5K.value,COMPATIBLE.LARGE.value], +[10,5 ,1,BRAM_TYPE.EFX_RAM_5K.value,COMPATIBLE.LARGE.value], +[8 ,16,2,BRAM_TYPE.EFX_RAM_5K.value,COMPATIBLE.SMALL.value], +[9 ,8 ,1,BRAM_TYPE.EFX_RAM_5K.value,COMPATIBLE.SMALL.value], +[10,4 ,1,BRAM_TYPE.EFX_RAM_5K.value,COMPATIBLE.SMALL.value], +[11,2 ,1,BRAM_TYPE.EFX_RAM_5K.value,COMPATIBLE.SMALL.value], +[12,1 ,1,BRAM_TYPE.EFX_RAM_5K.value,COMPATIBLE.SMALL.value] +] + +#Address Width, Data Width , Number of wen, BRAM_TYPE, COMPATIBLE +EFX_RAM_5K_MWM_feature_table =[ +[8 ,16,2,BRAM_TYPE.EFX_RAM_5K.value,COMPATIBLE.SMALL.value], +[9 ,8 ,1,BRAM_TYPE.EFX_RAM_5K.value,COMPATIBLE.SMALL.value], +[10,4 ,1,BRAM_TYPE.EFX_RAM_5K.value,COMPATIBLE.SMALL.value], +[11,2 ,1,BRAM_TYPE.EFX_RAM_5K.value,COMPATIBLE.SMALL.value], +[12,1 ,1,BRAM_TYPE.EFX_RAM_5K.value,COMPATIBLE.SMALL.value] +] + + +#Address Width, Data Width , Number of wen, BRAM_TYPE, COMPATIBLE +EFX_DPRAM_5K_feature_table =[ +[9 ,10,1,BRAM_TYPE.EFX_DPRAM_5K.value,COMPATIBLE.LARGE.value], +[10,5 ,1,BRAM_TYPE.EFX_DPRAM_5K.value,COMPATIBLE.LARGE.value], +[9 ,8 ,1,BRAM_TYPE.EFX_DPRAM_5K.value,COMPATIBLE.SMALL.value], +[10,4 ,1,BRAM_TYPE.EFX_DPRAM_5K.value,COMPATIBLE.SMALL.value], +[11,2 ,1,BRAM_TYPE.EFX_DPRAM_5K.value,COMPATIBLE.SMALL.value], +[12,1 ,1,BRAM_TYPE.EFX_DPRAM_5K.value,COMPATIBLE.SMALL.value] +] + + +#Address Width, Data Width , Number of wen, BRAM_TYPE, COMPATIBLE +EFX_DPRAM_5K_MWM_feature_table =[ +[9 ,8 ,1,BRAM_TYPE.EFX_DPRAM_5K.value,COMPATIBLE.SMALL.value], +[10,4 ,1,BRAM_TYPE.EFX_DPRAM_5K.value,COMPATIBLE.SMALL.value], +[11,2 ,1,BRAM_TYPE.EFX_DPRAM_5K.value,COMPATIBLE.SMALL.value], +[12,1 ,1,BRAM_TYPE.EFX_DPRAM_5K.value,COMPATIBLE.SMALL.value] +] + +#Index of Mode Write (A), Index of Mode Read (B), Number of bram in column/row +bram_decompose_table =[ +[0 ,0, 5, 0, 0], +[0 ,0, 1, 0, 0], +] + +#Index of Y of bram_decompose_table, +#Index of X of bram_decompose_table, +#Port A Data MSB, +#Port A Data LSB, +#Port A Data Repart, +#PORT A rdata MUX, +#PORT A WEN Selecion, +#PORT A BYTEEN, +#Port B Data MSB, +#PORT B Data LSB, +#Port A Data Repart, +#PORT B rdata MUX, +#PORT B BYTEEN, +#PORT B WEN Selecion, +bram_mapping_table = list() + +#Port Address Selection MSB, +#Port Address Selection LSB, +#DATA MSB, +#DATA LSB, +rMux_mapping_table_A = list() + +#Port Address Selection MSB, +#Port Address Selection LSB, +#WEN Range MSB, +#WEN Ragne LSB, +wen_sel_mapping_table_A = list() + +#Port Address Selection MSB, +#Port Address Selection LSB, +#DATA MSB, +#DATA LSB, +rMux_mapping_table_B = list() + +#Port Address Selection MSB, +#Port Address Selection LSB, +#WEN Range MSB, +#WEN Ragne LSB, +wen_sel_mapping_table_B = list() + + + +#Data Bit Index for Mixed Width Mode +data_mapping_table_A = list() + +#Data Bit Index for Mixed Width Mode +data_mapping_table_B = list() + +#Address Bit Index for Mixed Width Mode +address_mapping_table_A = list() + +#Address Bit Index for Mixed Width Mode +address_mapping_table_B = list() + + +bram_decompose_mode = 1 # 1: LOOP ROW FIRST", 0: LOOP COLUMN FIRST" +in_addr_width_a = 10 +in_data_width_a = 10 +in_addr_width_b = 10 +in_data_width_b = 10 + +#byteen mapping +# byteen index, Write Enable (WE) mode for primitive (e.g. for we[0] or we[1], 1 for wen 0, 2 for wen 1 +bram_decompose_byteen_table = list() +byteen_width = 1 +byteen_width_A = 1 +byteen_width_B = 1 + +byteen_enable = 0 +group_data_width = 8 +group_data_width_A = 8 +group_data_width_B = 8 + + +group_columns = 1 +FAMILY = 1 +actual_size = 0 +actual_size_A = 0 +actual_size_B = 0 + +bram_we_mapping_table =[0,1,2,3] + +def create_feature_file(): + f = open("bram_feature.vh", "w") + y = 0 + + line = "" + + line += 'function integer bram_feature_table;\n' + line += 'input integer index;//Mode type \n' + line += 'input integer type; //Address_width, data_width, en_width, reserved \n' + line += 'case (index)\n' + f.write (line) + for row in bram_feature_table: + + line = "" + x = 0 + + line += str(y ) + line += ': bram_feature_table=' + + for feature in row: + line += '(type==' + str(x) + ')?' + str(feature) + ':' + x = x + 1 + + line += '0;\n' + f.write (line) + y = y +1 + + + line = "" + line += " endcase\n" + line += "endfunction \n" + f.write (line) + f.close() + + +def create_memory_init_file(): + f = open("bram_ini.vh", "w") + + line = '\n' + line += 'function [255:0] bram_ini_table;\n' + line += 'input integer index;//Mode type \n' + line += 'input integer val_; //Port A index, Port B Index, Number of Items in Loop, Port A Start, Port B Start, reserved \n' + line += 'case (index)\n' + f.write (line) + y = 0 + for row in bram_mapping_table: + + line = "" + x = 0 + + line += '%4s: bram_ini_table=\n' %(y) + + + stringline ="256'h" + for hexChar in range(0,32): + #stringline += '%02x' % (y) + stringline += '%02x' % (0) + + + for x in range(0, 40): + #line += '(type==' + str(x) + ')?' + str(feature) + ':' + line += '(val_==%2s)?' % (x) + + line += stringline + #line += "256'h0000000000000000000000000000000000000000000000000000000000000000" + + line += ":\n" + x = x + 1 + line += '0;\n' + f.write (line) + + + + y = y +1 + + + line = "" + line += " endcase\n" + line += "endfunction \n" + f.write (line) + + + + + f.close() + + + +def create_decompose_file(): + f = open("bram_decompose.vh", "w") + y = 0 + + line = "" + line += 'localparam FAMILY = ' + str(FAMILY) + '; //0:Trion, 1:Titanium\n' + line += 'localparam ADDR_WIDTH_A = ' + str(in_addr_width_a) + ';\n' + line += 'localparam DATA_WIDTH_A = ' + str(in_data_width_a) + ';\n' + line += 'localparam ADDR_WIDTH_B = ' + str(in_addr_width_b) + ';\n' + line += 'localparam DATA_WIDTH_B = ' + str(in_data_width_b) + ';\n' + line += 'localparam TOTAL_SIZE_A = ' + str(actual_size_A) + ';\n' + line += 'localparam TOTAL_SIZE_B = ' + str(actual_size_B) + ';\n' + line += 'localparam BYTEEN_WIDTH = ' + str(byteen_width) + ';\n' + line += 'localparam BYTEEN_WIDTH_A = ' + str(byteen_width_A) + ';\n' + line += 'localparam BYTEEN_WIDTH_B = ' + str(byteen_width_B) + ';\n' + line += 'localparam GROUP_DATA_WIDTH = ' + str(group_data_width) + ';\n' + line += 'localparam GROUP_DATA_WIDTH_A = ' + str(group_data_width_A) + ';\n' + line += 'localparam GROUP_DATA_WIDTH_B = ' + str(group_data_width_B) + ';\n' + + line += 'localparam GROUP_COLUMNS = ' + str(group_columns) + ';\n' + + line += 'localparam bram_table_size = ' + str(len(bram_decompose_table)) + ';\n' + line += 'localparam bram_table_loop_mode = ' + str(bram_decompose_mode) + ';\n' + + line += 'localparam bram_mapping_size = ' + str(len(bram_mapping_table)) + ';\n' + line += 'localparam rMux_mapping_A_size = ' + str(len(rMux_mapping_table_A)) + ';\n' + line += 'localparam rMux_mapping_B_size = ' + str(len(rMux_mapping_table_B)) + ';\n' + line += 'localparam wen_sel_mapping_A_size = ' + str(len(wen_sel_mapping_table_A)) + ';\n' + line += 'localparam wen_sel_mapping_B_size = ' + str(len(wen_sel_mapping_table_B)) + ';\n' + + + line += 'localparam data_mapping_table_A_size = ' + str(len(data_mapping_table_A)) + ';\n' + line += 'localparam data_mapping_table_B_size = ' + str(len(data_mapping_table_B)) + ';\n' + line += 'localparam address_mapping_table_A_size = ' + str(len(address_mapping_table_A)) + ';\n' + line += 'localparam address_mapping_table_B_size = ' + str(len(address_mapping_table_B)) + ';\n' + f.write (line) + + + y = 0 + + line = '\n\n' + + line += 'function integer bram_feature_table;\n' + line += 'input integer index;//Mode type \n' + line += 'input integer val_; //Address_width, data_width, en_width, reserved \n' + line += 'case (index)\n' + f.write (line) + for row in bram_feature_table: + + line = "" + x = 0 + + line += str(y ) + line += ': bram_feature_table=' + + for feature in row: + line += '(val_==' + str(x) + ')?' + str(feature) + ':' + x = x + 1 + + line += '0;\n' + f.write (line) + y = y +1 + + + line = "" + line += " endcase\n" + line += "endfunction \n" + f.write (line) + + + line = '\n\n' + y = 0 + line += 'function integer bram_decompose_table;\n' + line += 'input integer index;//Mode type \n' + line += 'input integer val_; //Port A index, Port B Index, Number of Items in Loop, Port A Start, Port B Start, reserved \n' + line += 'case (index)\n' + f.write (line) + for row in bram_decompose_table: + + line = "" + x = 0 + + line += '%4s: bram_decompose_table=' %(y) + + for feature in row: + #line += '(type==' + str(x) + ')?' + str(feature) + ':' + line += '(val_==%1s)?%4s:' % (x,feature) + x = x + 1 + line += '0;\n' + f.write (line) + y = y +1 + + + line = "" + line += " endcase\n" + line += "endfunction \n" + f.write (line) + + #line = "" + #line += '\n\n' + #y = 0 + #line += 'function integer bram_decompose_byteen_table;\n' + #line += 'input integer index;//Mode type \n' + #line += 'input integer type; //Port A index, Port B Index, Number of Items in Loop, Port A Start, Port B Start, reserved \n' + #line += 'case (index)\n' + #f.write (line) + # + # + #for row in bram_decompose_byteen_table: + # + # line = "" + # x = 0 + # + # line += str(y ) + # line += ': bram_decompose_byteen_table=' + # + # for feature in row: + # line += '(type==' + str(x) + ')?' + str(feature) + ':' + # x = x + 1 + # line += '0;\n' + # f.write (line) + # y = y +1 + # + #line = "" + #line += " endcase\n" + #line += "endfunction \n" + #f.write (line) + + + line = "" + line += '\n\n' + y = 0 + line += 'function integer bram_mapping_table;\n' + line += 'input integer index;//Mode type \n' + line += 'input integer val_;' + line += '// ' + line += 'Y, ' + line += 'X, ' + line += 'DataA [MSB], ' + line += 'DataA [LSB], ' + line += 'DataA Repeat, ' + line += 'Read MuxA, ' + line += 'Wen0 SelA, ' + line += 'Wen1 SelA, ' + line += 'Byteen A, ' + line += 'DataB [MSB], ' + line += 'DataB [LSB], ' + line += 'DataB Repeat, ' + line += 'Read MuxB, ' + line += 'Wen0 SelB, ' + line += 'Wen1 SelB, ' + line += 'Byteen B, ' + line += 'Addr Width A ' + line += 'Data Width A ' + line += 'Addr Width B ' + line += 'Data Width B ' + + line += '\n' + + line += 'case (index)\n' + f.write (line) + + + for row in bram_mapping_table: + + line = "" + x = 0 + + line += '%4s: bram_mapping_table=' % (y) + + for feature in row: + line += '(val_==%2s)?%4s:' % (x,feature) + # line += '(val_==' + str(x) + ')?' + str(feature) + ':' + + + x = x + 1 + line += '0;\n' + f.write (line) + y = y +1 + + line = "" + line += " endcase\n" + line += "endfunction \n" + f.write (line) + + + line = "" + line += '\n\n' + y = 0 + line += 'function integer rMux_mapping_table_A;\n' + line += 'input integer index;//Mode type \n' + line += 'input integer val_;' + line += '// ' + line += 'PortA Addr MSB, ' + line += 'PortA Addr LSB, ' + line += 'DataA[MSB], ' + line += 'DataA[LSB], ' + line += 'MuxSelA[MSB], ' + line += 'MuxSelA[LSB], ' + line += 'Bypass, ' + line += '\n' + f.write (line) + + if len(rMux_mapping_table_A) != 0: + line = 'case (index)\n' + f.write (line) + + for row in rMux_mapping_table_A: + + line = "" + x = 0 + + line += '%4s: rMux_mapping_table_A=' % (y) + + for feature in row: + line += '(val_==%2s)?%4s:' % (x,feature) + # line += '(val_==' + str(x) + ')?' + str(feature) + ':' + + + x = x + 1 + line += '0;\n' + f.write (line) + y = y +1 + + line = "" + line = " endcase\n" + f.write (line) + else: + line = "rMux_mapping_table_A = 0; \n" + f.write (line) + + line = "endfunction \n" + f.write (line) + + + line = "" + line += '\n\n' + y = 0 + line += 'function integer rMux_mapping_table_B;\n' + line += 'input integer index;//Mode type \n' + line += 'input integer val_;' + line += '// ' + line += 'PortB Addr MSB, ' + line += 'PortB Addr LSB, ' + line += 'DataB[MSB], ' + line += 'DataB[LSB], ' + line += 'MuxSelB[MSB], ' + line += 'MuxSelB[LSB], ' + line += 'Bypass, ' + line += '\n' + f.write (line) + + + if len(rMux_mapping_table_B) != 0: + line = 'case (index)\n' + f.write (line) + + for row in rMux_mapping_table_B: + + line = "" + x = 0 + + line += '%4s: rMux_mapping_table_B=' % (y) + + for feature in row: + line += '(val_==%2s)?%4s:' % (x,feature) + # line += '(val_==' + str(x) + ')?' + str(feature) + ':' + + + x = x + 1 + line += '0;\n' + f.write (line) + y = y +1 + + line = "" + line = " endcase\n" + f.write (line) + else: + line = "rMux_mapping_table_B = 0; \n" + f.write (line) + + line = "endfunction \n" + f.write (line) + + + line = "" + line += '\n\n' + y = 0 + line += 'function integer wen_sel_mapping_table_A;\n' + line += 'input integer index;//Mode type \n' + line += 'input integer val_;' + line += '// ' + line += 'PortA Addr MSB, ' + line += 'PortA Addr LSB, ' + line += 'WenSelA[MSB], ' + line += 'WenSelA[LSB], ' + line += 'Bypass, ' + line += '\n' + f.write (line) + + + if len(wen_sel_mapping_table_A) != 0: + line = 'case (index)\n' + f.write (line) + for row in wen_sel_mapping_table_A: + + line = "" + x = 0 + + line += '%4s: wen_sel_mapping_table_A=' % (y) + + for feature in row: + line += '(val_==%2s)?%4s:' % (x,feature) + # line += '(val_==' + str(x) + ')?' + str(feature) + ':' + + + x = x + 1 + line += '0;\n' + f.write (line) + y = y +1 + + line = "" + line = " endcase\n" + f.write (line) + else: + line = "wen_sel_mapping_table_A = 0; \n" + f.write (line) + + + line = "endfunction \n" + f.write (line) + + line = "" + line += '\n\n' + y = 0 + line += 'function integer wen_sel_mapping_table_B;\n' + line += 'input integer index;//Mode type \n' + line += 'input integer val_;' + line += '// ' + line += 'PortB Addr MSB, ' + line += 'PortB Addr LSB, ' + line += 'WenSelB[MSB], ' + line += 'WenSelB[LSB], ' + line += 'Bypass, ' + line += '\n' + f.write (line) + + if len(wen_sel_mapping_table_B) !=0: + + line = 'case (index)\n' + f.write (line) + for row in wen_sel_mapping_table_B: + + line = "" + x = 0 + + line += '%4s: wen_sel_mapping_table_B=' % (y) + + for feature in row: + line += '(val_==%2s)?%4s:' % (x,feature) + # line += '(val_==' + str(x) + ')?' + str(feature) + ':' + + + x = x + 1 + line += '0;\n' + f.write (line) + y = y +1 + + line = "" + line = " endcase\n" + f.write (line) + else: + line = "wen_sel_mapping_table_B = 0; \n" + f.write (line) + + + line = "endfunction \n" + f.write (line) + + + + line = "" + line += '\n\n' + y = 0 + line += 'function integer data_mapping_table_A;\n' + line += 'input integer index;// \n' + f.write (line) + + if len(data_mapping_table_A) !=0: + + line = 'case (index)\n' + f.write (line) + for row in data_mapping_table_A: + + line = "" + + line += '%4s: data_mapping_table_A= %4s;\n' % (y,row) + + f.write (line) + y = y +1 + + line = "" + line = " endcase\n" + f.write (line) + else: + line = "data_mapping_table_A = 0; \n" + f.write (line) + + + line = "endfunction \n" + f.write (line) + + + line = "" + line += '\n\n' + y = 0 + line += 'function integer data_mapping_table_B;\n' + line += 'input integer index;// \n' + f.write (line) + + if len(data_mapping_table_B) !=0: + + line = 'case (index)\n' + f.write (line) + for row in data_mapping_table_B: + + line = "" + + line += '%4s: data_mapping_table_B= %4s;\n' % (y,row) + + f.write (line) + y = y +1 + + line = "" + line = " endcase\n" + f.write (line) + else: + line = "data_mapping_table_B = 0; \n" + f.write (line) + + + line = "endfunction \n" + f.write (line) + + + + line = "" + line += '\n\n' + y = 0 + line += 'function integer address_mapping_table_A;\n' + line += 'input integer index;// \n' + f.write (line) + + if len(address_mapping_table_A) !=0: + + line = 'case (index)\n' + f.write (line) + for row in address_mapping_table_A: + + line = "" + + line += '%4s: address_mapping_table_A= %4s;\n' % (y,row) + + f.write (line) + y = y +1 + + line = "" + line = " endcase\n" + f.write (line) + else: + line = "address_mapping_table_A = 0; \n" + f.write (line) + + + line = "endfunction \n" + f.write (line) + + + line = "" + line += '\n\n' + y = 0 + line += 'function integer address_mapping_table_B;\n' + line += 'input integer index;// \n' + f.write (line) + + if len(address_mapping_table_B) !=0: + + line = 'case (index)\n' + f.write (line) + for row in address_mapping_table_B: + + line = "" + + line += '%4s: address_mapping_table_B= %4s;\n' % (y,row) + + f.write (line) + y = y +1 + + line = "" + line = " endcase\n" + f.write (line) + else: + line = "address_mapping_table_B = 0; \n" + f.write (line) + + + line = "endfunction \n" + f.write (line) + + + + f.close() + +def create_decompose_column__(address_width, data_width, size, decompose_mode): + + #flag_find = true; + index = 0 + + Find_success = False + + Max_addrw = 0 + Max_dataw = 0 + min_dataw = 0 + rows = 0 + + #result = "Input Address:"+ str(address_width) +" data:" + str(data_width) + #print (result) + + #Find Max Address Width + for feature in bram_feature_table: + if feature[FEATURE.COMPATIBLE.value] == COMPATIBLE.LARGE.value or decompose_mode == 'speed': + if Max_addrw < feature[FEATURE.ADDRW.value]: + Max_addrw = feature[FEATURE.ADDRW.value] + if address_width <= Max_addrw: + break + + # result = "Max Address:"+ str(Max_addrw) + # print (result) + + + #Find Max Data Width + # for feature in bram_feature_table: + # if feature[FEATURE.COMPATIBLE.value] == COMPATIBLE.LARGE.value: + # if Max_dataw < feature[FEATURE.DATAW.value]: + # Max_dataw = feature[FEATURE.DATAW.value] + + # result = "Max Data:"+ str(Max_dataw) + # print (result) + + + #Find Max Data Width + index = 0 + for feature in bram_feature_table: + + min_dataw = feature[FEATURE.DATAW.value] + + if feature[FEATURE.ADDRW.value] >= address_width: + break + + if feature[FEATURE.ADDRW.value] >= Max_addrw: + + # result = "Min Data:"+ str(min_dataw) + # print (result) + + if min_dataw <= data_width: + break + + + + min_dataw = feature[FEATURE.DATAW.value] + + index += 1 + + # result = "Min Data:"+ str(min_dataw) + # print (result) + # result = "Index:"+ str(index) + # print (result) + + primitive_dataw = bram_feature_table[index][FEATURE.DATAW.value] + primitive_addrw = bram_feature_table[index][FEATURE.ADDRW.value] + + + total_address = pow(2,address_width) + total_primitive_address = pow(2,primitive_addrw) + + if size != 0: + if size <= total_address: + total_address = size + + rows = int(total_address/total_primitive_address) + + if total_address % total_primitive_address : + rows += 1 + + + + return index, rows, primitive_addrw, primitive_dataw + +def create_decompose_column(address_width, data_width, size): + + #flag_find = true; + index = 0 + + Find_success = False + + Max_addrw = 0 + Max_dataw = 0 + min_dataw = 0 + rows = 0 + + #result = "Input Address:"+ str(address_width) +" data:" + str(data_width) + #print (result) + + #Find Max Address Width + for feature in bram_feature_table: + if feature[FEATURE.COMPATIBLE.value] == COMPATIBLE.LARGE.value: + if Max_addrw < feature[FEATURE.ADDRW.value]: + Max_addrw = feature[FEATURE.ADDRW.value] + if address_width <= Max_addrw: + break + + # result = "Max Address:"+ str(Max_addrw) + # print (result) + + + #Find Max Data Width + # for feature in bram_feature_table: + # if feature[FEATURE.COMPATIBLE.value] == COMPATIBLE.LARGE.value: + # if Max_dataw < feature[FEATURE.DATAW.value]: + # Max_dataw = feature[FEATURE.DATAW.value] + + # result = "Max Data:"+ str(Max_dataw) + # print (result) + + + #Find Max Data Width + index = 0 + for feature in bram_feature_table: + + min_dataw = feature[FEATURE.DATAW.value] + + if feature[FEATURE.ADDRW.value] >= address_width: + break + + if feature[FEATURE.ADDRW.value] >= Max_addrw: + + # result = "Min Data:"+ str(min_dataw) + # print (result) + + if min_dataw <= data_width: + break + + + + min_dataw = feature[FEATURE.DATAW.value] + + index += 1 + + # result = "Min Data:"+ str(min_dataw) + # print (result) + # result = "Index:"+ str(index) + # print (result) + + primitive_dataw = bram_feature_table[index][FEATURE.DATAW.value] + primitive_addrw = bram_feature_table[index][FEATURE.ADDRW.value] + + + total_address = pow(2,address_width) + total_primitive_address = pow(2,primitive_addrw) + + if size != 0: + if size <= total_address: + total_address = size + + rows = int(total_address/total_primitive_address) + + if total_address % total_primitive_address : + rows += 1 + + + + return index, rows, primitive_addrw, primitive_dataw + + + +def create_decompose_row(data_width, size, group_data_width): + + #flag_find = true; + index = 0 + + Find_success = False + + Max_addrw = 0 + Max_dataw = 0 + min_dataw = 0 + columns = 0 + + #result = "Input Address:"+ str(address_width) +" data:" + str(data_width) + #print (result) + + address_width = math.log2(size) + + #Find Max Address Width + for feature in bram_feature_table: + if Max_addrw < feature[FEATURE.ADDRW.value]: + Max_addrw = feature[FEATURE.ADDRW.value] + if address_width <= Max_addrw: + break + + # result = "Max Address:"+ str(Max_addrw) + # print (result) + + + #Find Max Data Width + # for feature in bram_feature_table: + # if feature[FEATURE.COMPATIBLE.value] == COMPATIBLE.LARGE.value: + # if Max_dataw < feature[FEATURE.DATAW.value]: + # Max_dataw = feature[FEATURE.DATAW.value] + + # result = "Max Data:"+ str(Max_dataw) + # print (result) + + + #Find Max Data Width + index = 0 + for feature in bram_feature_table: + + min_dataw = feature[FEATURE.DATAW.value] + + if feature[FEATURE.ADDRW.value] >= address_width: + break + + if feature[FEATURE.ADDRW.value] >= Max_addrw: + + # result = "Min Data:"+ str(min_dataw) + # print (result) + + if min_dataw <= data_width: + break + + # min_dataw = feature[FEATURE.DATAW.value] + + index += 1 + + # result = "Min Data:"+ str(min_dataw) + # print (result) + # result = "Index:"+ str(index) + # print (result) + + primitive_dataw = bram_feature_table[index][FEATURE.DATAW.value] + primitive_addrw = bram_feature_table[index][FEATURE.ADDRW.value] + + if group_data_width == 0: + columns = int(data_width/primitive_dataw) + + if data_width % primitive_dataw: + columns += 1 + else: + sub_columns = int(group_data_width/primitive_dataw) + + if group_data_width % primitive_dataw: + sub_columns += 1 + + columns = (int(data_width/group_data_width)) * sub_columns + + sub_columns_remain = (data_width % group_data_width) + + columns += int(sub_columns_remain/primitive_dataw) + + if sub_columns_remain % primitive_dataw: + columns += 1 + + return index, columns, primitive_addrw, primitive_dataw + + + +def create_decompose_table(address_width, data_width, size, decompose_mode): + + total_width = 0 + total_bram = 0 + column = 0 + while True: + + index, rows, column_addrw, column_dataw = create_decompose_column(address_width, (data_width-total_width), size, decompose_mode) + + total_width += column_dataw + total_bram += rows + + result = "Column " + str(column) + ") Primitive index: " + str(index) + " addr"+ str(column_addrw) + " data: " + str(column_dataw) + " number of rows:" +str(rows) + print (result) + + if total_width >= data_width: + break + + column += 1 + + result = "Total Bram used in:" + str(total_bram) + print (result) + + +def create_decompose_table_scan_col(address_width, data_width, size, group_data_width, address_width_B, data_width_B): + + + total_width = 0 + total_bram = 0 + column = 0 + global bram_decompose_mode + global in_addr_width_a + global in_data_width_a + global in_addr_width_b + global in_data_width_b + global byteen_width + global byteen_enable + global group_columns + global bram_decompose_table + global bram_decompose_byteen_table + global bram_mapping_table + global rMux_mapping_table_A + global rMux_mapping_table_B + global wen_sel_mapping_table_A + global wen_sel_mapping_table_B + global actual_size_A + global actual_size_B + + + bram_decompose_byteen_table = list() + + total_address = pow(2,address_width) + + if size != 0: + if size <= total_address: + total_address = size + + actual_size_A = total_address + actual_size_B = total_address + + + + group_data_count = 0; + group_data_ptr = 0; + for x in range(0, data_width): + bram_data_row = [group_data_ptr,1] + bram_decompose_byteen_table.append(bram_data_row) + + group_data_count += 1 + if(group_data_count == group_data_width): + group_data_ptr += 1 + group_data_count = 0 + + if group_data_width != 0: + byteen_enable = 1 + byteen_width = group_data_ptr + if ( ( data_width % group_data_width ) != 0): + byteen_width += 1 + result = "byteen width: " + str(byteen_width) + " Group Data Width: " + str(group_data_width) + print (result) + + bram_decompose_mode = 0 # 1: LOOP ROW FIRST", 0: LOOP COLUMN FIRST" + + in_addr_width_a = address_width + in_data_width_a = data_width + in_addr_width_b = address_width + in_data_width_b = data_width + + byteen_index = 0; + wen_index = 0; + + bram_decompose_table = list() + rMux_mapping_table_A = list() + rMux_mapping_table_B = list() + wen_sel_mapping_table_A = list() + wen_sel_mapping_table_B = list() + + wenSelIndex = 0 + + + data_start = 0 + + Flg_row_detected = False + + while True: + + if group_data_width == 0 : + + index, rows, column_addrw, column_dataw = create_decompose_column(address_width, (data_width-total_width), size) + + bram_column = [index,index, rows, 0,0] + bram_decompose_table.append(bram_column) + + data_start = total_width + data_end = data_start + column_dataw + if data_end > data_width: + data_end = data_width + data_end -= 1 + + + nBits = data_end - data_start +1 + interval = 0 + Repeat = 0 + + wenSel_Start = wenSelIndex + + + for x in range(0, rows): + bram_map = [x,column,data_end,data_start,Repeat,x,wenSelIndex,wenSelIndex,byteen_index,data_end,data_start,Repeat,x,wenSelIndex,wenSelIndex,byteen_index, column_addrw, column_dataw, column_addrw, column_dataw] + + bram_mapping_table.append(bram_map) + wenSelIndex += 1 + + Bypassed = 0 + if( address_width > column_addrw ) | (Flg_row_detected == True) : + Flg_row_detected = True + if (address_width <= column_addrw): + Bypassed = 1 + + rMuxA = [address_width-1,column_addrw, data_end,data_start, rows-1, 0 , Bypassed] + rMux_mapping_table_A.append(rMuxA) + + rMuxB = [address_width-1,column_addrw, data_end,data_start, rows-1, 0 , Bypassed] + rMux_mapping_table_B.append(rMuxB) + + WenSelA = [address_width-1,column_addrw, wenSelIndex-1,wenSel_Start , Bypassed] + wen_sel_mapping_table_A.append(WenSelA) + + WenSelB = [address_width-1,column_addrw, wenSelIndex-1,wenSel_Start , Bypassed] + wen_sel_mapping_table_B.append(WenSelB) + + + + total_width += column_dataw + total_bram += rows + result = "Column " + str(column) + ") Primitive index: " + str(index) + " addr"+ str(column_addrw) + " data: " + str(column_dataw) + " number of rows:" +str(rows) + print (result) + + if total_width >= data_width: + break + + column += 1 + else : + + total_group_data_width = 0; + + + while True: + + index, rows, column_addrw, column_dataw = create_decompose_column(address_width, (group_data_width-total_group_data_width), size) + + bram_column = [index,index, rows, 0,0] + bram_decompose_table.append(bram_column) + + data_start = total_width + total_group_data_width + data_end = data_start + column_dataw + + if (total_group_data_width+column_dataw) > group_data_width: + data_end = total_width + group_data_width + elif data_end > data_width: + data_end = data_width + data_end -= 1 + + nBits = data_end - data_start +1 + interval = 0 + Repeat = 0 + + wenSel_Start = wenSelIndex + + for x in range(0, rows): + bram_map = [x,column,data_end,data_start,Repeat,x,wenSelIndex,wenSelIndex,byteen_index,data_end,data_start,Repeat,x,wenSelIndex,wenSelIndex,byteen_index, column_addrw, column_dataw, column_addrw, column_dataw] + + bram_mapping_table.append(bram_map) + wenSelIndex += 1 + + Bypassed = 0 + if( address_width > column_addrw ) | (Flg_row_detected == True) : + Flg_row_detected = True + if (address_width <= column_addrw): + Bypassed = 1 + + rMuxA = [address_width-1,column_addrw, data_end,data_start, rows-1, 0 , Bypassed] + rMux_mapping_table_A.append(rMuxA) + + rMuxB = [address_width-1,column_addrw, data_end,data_start, rows-1, 0 , Bypassed] + rMux_mapping_table_B.append(rMuxB) + + WenSelA = [address_width-1,column_addrw, wenSelIndex-1,wenSel_Start , Bypassed] + wen_sel_mapping_table_A.append(WenSelA) + + WenSelB = [address_width-1,column_addrw, wenSelIndex-1,wenSel_Start , Bypassed] + wen_sel_mapping_table_B.append(WenSelB) + + result = "Column " + str(column) + ") Primitive index: " + str(index) + " addr"+ str(column_addrw) + " data: " + str(column_dataw) + " number of rows:" +str(rows) + print (result) + + + column += 1 + + total_group_data_width += column_dataw + total_bram += rows + if total_group_data_width >= group_data_width: + byteen_index += 1 + total_group_data_width = group_data_width + break + + if (total_width + total_group_data_width ) >= data_width: + byteen_index += 1 + break + + + + total_width += total_group_data_width + + if total_width >= data_width: + break + + + + + + result = "Total BRAM used :" + str(total_bram) + print (result) + print("") + + +def check_row_mwm (address_width_A, data_width_A, size_A, group_data_width, address_width_B, data_width_B): + + if(data_width_B != 0) | (address_width_B!=0): + if (data_width_B != 0): + + temp_address_width_B = int(0) + + if (data_width_A > data_width_B): + if (data_width_A % data_width_B) != 0: + #print("In Mixed Width Mode, Don't support remainder that Data Width A divided by Data Width of B.") + print("In Mixed Width Mode, please apply the equation : data_width_A = data_width_b x (n power of 2). ") + return False, 0, 0, 0, 0, 0, 0, 0 + + temp_data_width_B = data_width_A + while (True ): + temp_data_width_B /= 2 + if (temp_data_width_B <= data_width_B): + break; + + if temp_data_width_B != data_width_B: + print("In Mixed Width Mode, please apply the equation : data_width_A = data_width_b x (n power of 2). ") + return False, 0, 0, 0, 0, 0, 0, 0 + + extend_addr = (data_width_A / data_width_B) + + temp_address_width_B = address_width_A + math.log2(extend_addr) + + elif (data_width_B > data_width_A): + if (data_width_B % data_width_A) != 0: + #print("In Mixed Width Mode, Don't support remainder that Data Width B divided by Data Width of A.") + print("In Mixed Width Mode, please apply the equation : data_width_B = data_width_A x (n power of 2). ") + return False, 0, 0, 0, 0, 0, 0, 0 + + print(data_width_B, data_width_A) + temp_data_width_A = data_width_B + while (True ): + temp_data_width_A /= 2 + if (temp_data_width_A <= data_width_A): + break; + + if temp_data_width_A != data_width_A: + print(temp_data_width_A, data_width_A) + print("In Mixed Width Mode, please apply the equation : data_width_B = data_width_A x (n power of 2). ") + return False, 0, 0, 0, 0, 0, 0, 0 + + extend_addr = (data_width_B / data_width_A) + + temp_address_width_B = address_width_A - math.log2(extend_addr) + else: + temp_address_width_B = address_width_A + + if address_width_B != 0: + if address_width_B < temp_address_width_B: + print("In Mixed Width Mode, the address_width_B is lesser than expected address_width. ") + return False, 0, 0, 0, 0, 0, 0, 0 + else: + address_width_B = temp_address_width_B + + if (address_width_B != 0): + if address_width_B > address_width_A: + if (data_width_B == 0): + addr_diff = address_width_B - address_width_A + temp_data_width_B = data_width_A + + for i in range (0,addr_diff): + temp_data_width_B /= 2 + + if temp_data_width_B <= 0: + print("In Mixed Width Mode, please apply the equation : data_width_A = data_width_b X ( ( address_width_B - address_width_A ) power of 2). ") + return False, 0, 0, 0, 0, 0, 0, 0 + + data_width_B = temp_data_width_B + + if address_width_A > address_width_B: + if (data_width_B == 0): + addr_diff = address_width_A - address_width_B + temp_data_width_B = data_width_A + + for i in range (0,addr_diff): + temp_data_width_B *= 2 + + data_width_B = temp_data_width_B + + size_B = 0 + if size_A != 0: + if data_width_A != data_width_B: + #find Max Bram Address of Port A + max_primitive_addressA = 0 + for row in bram_decompose_table: + primitive_data = bram_feature_table[row[0]][FEATURE.DATAW.value] + primitive_addr = bram_feature_table[row[0]][FEATURE.ADDRW.value] + if max_primitive_addressA < primitive_addr: + max_primitive_addressA = primitive_addr + + if (size_A % pow(2, max_primitive_addressA )) != 0: + Rows = (size_A / pow(2, max_primitive_addressA ))+1 + size_A = Rows * pow(2, max_primitive_addressA ) + + + if data_width_A < data_width_B: + size_B = size_A / ( data_width_B/data_width_A) + elif data_width_A > data_width_B: + size_B = size_A * ( data_width_A/data_width_B) + else: + size_B = size_A + + + return True, int(address_width_A), int (data_width_A), int(size_A), int(group_data_width), int(address_width_B), int(data_width_B), int(size_B) + + + + + +def find_mixed_width_row(index, targetRatio ): + + primitive_dataw = bram_feature_table[index][FEATURE.DATAW.value] + compatible = bram_feature_table[index][FEATURE.COMPATIBLE.value] + TargetDataWidth = int(primitive_dataw*targetRatio) + + #print (TargetDataWidth, primitive_dataw, targetRatio) + + MaxDataWidth = primitive_dataw + + Index = 0 + MaxIndex = Index + TargetIndex = Index + + result = False + for feature in bram_feature_table: + if feature[FEATURE.COMPATIBLE.value] == compatible: + if MaxDataWidth <= feature[FEATURE.DATAW.value]: + MaxDataWidth = feature[FEATURE.DATAW.value] + MaxIndex = Index + if TargetDataWidth == feature[FEATURE.DATAW.value]: + result = True + TargetIndex = Index + break + + Index += 1 + + if result == False : + TargetIndex = MaxIndex + TargetDataWidth = MaxDataWidth + + TargetAddressWidth = bram_feature_table[TargetIndex][FEATURE.ADDRW.value] + + return result, TargetIndex, TargetDataWidth, TargetAddressWidth + + +def create_decompose_table_scan_row(scan_index, address_width_A, data_width_A, size_A, group_data_width_A, address_width_B, data_width_B, size_B, group_data_width_B): + + total_width = 0 + total_bram = 0 + row = 0 + mixed_row =0 + global bram_decompose_mode + global in_addr_width_a + global in_data_width_a + global in_addr_width_b + global in_data_width_b + global byteen_width + global byteen_width_A + global byteen_width_B + + global byteen_enable + global group_columns + global bram_decompose_table + global bram_decompose_byteen_table + global bram_mapping_table + global rMux_mapping_table_A + global rMux_mapping_table_B + global wen_sel_mapping_table_A + global wen_sel_mapping_table_B + global actual_size_A + global actual_size_B + + actual_size_A = pow(2,address_width_A) + if size_A != 0: + if size_A <= actual_size_A: + actual_size_A = size_A + + actual_size_B = pow(2,address_width_B) + if size_B != 0: + if size_B <= actual_size_B: + actual_size_B = size_B + + + if data_width_A <= data_width_B: + address_width = address_width_A + data_width = data_width_A + size = size_A + group_data_width = group_data_width_A + if data_width_A == data_width_B: + if group_data_width_A > group_data_width_B: + group_data_width = group_data_width_B + + else: + address_width = address_width_B + data_width = data_width_B + size = size_B + group_data_width = group_data_width_B + + mixed_total_width = 0 + extend_row_index = 0 + extend_data_width = 0 + + max_extend_row_index = 0 + + + + bram_decompose_byteen_table = list() + group_columns = 1 + group_data_count = 0; + group_data_ptr = 0; + for x in range(0, data_width): + bram_data_row = [group_data_ptr,1] + bram_decompose_byteen_table.append(bram_data_row) + + group_data_count += 1 + if(group_data_count == group_data_width): + group_data_ptr += 1 + group_data_count = 0 + + if group_data_width != 0: + byteen_width = group_data_ptr + byteen_enable = 1 + if ( ( data_width % group_data_width ) != 0): + byteen_width += 1 + result = "byteen width: " + str(byteen_width) + " Group Data Width: " + str(group_data_width) + byteen_width_A = byteen_width + byteen_width_B = byteen_width + print (result) + + + bram_decompose_mode = 1 # 1: LOOP ROW FIRST", 0: LOOP COLUMN FIRST" + + total_address = pow(2,address_width) + + if size != 0: + if size <= total_address: + total_address = size + + in_addr_width_a = address_width_A + in_data_width_a = data_width_A + in_addr_width_b = address_width_B + in_data_width_b = data_width_B + + bram_decompose_table = list() + bram_mapping_table = list() + + bram_mapping_table_index = 0 + + if group_data_width == 0: + group_data_width = data_width + + + Max_addrw = 0 + Min_addrw = 1000 + mwm_ratio = 1 + + #Find Max Address Width + for feature in bram_feature_table: + if Max_addrw < feature[FEATURE.ADDRW.value]: + Max_addrw = feature[FEATURE.ADDRW.value] + #Find Min Address Width + for feature in bram_feature_table: + if Min_addrw > feature[FEATURE.ADDRW.value]: + Min_addrw = feature[FEATURE.ADDRW.value] + + + + while True: + + index, columns, column_addrw, column_dataw = create_decompose_row(data_width, total_address,group_data_width) + + + if(data_width_A != data_width_B): + + temp_total_address = total_address + + limit = 0 + while(True): + + print (limit, Max_addrw,Min_addrw, column_addrw, temp_total_address, address_width_B, address_width_A) + + if(column_addrw == Max_addrw): + break + + if(data_width_A > data_width_B): + mwm_ratio = data_width_A/data_width_B + extend_mwm_addr = int(math.log2(mwm_ratio)); + + print ("A>B",column_addrw, (address_width_B+extend_mwm_addr), address_width_A, address_width_B, mwm_ratio, extend_mwm_addr, "Data",column_dataw,"Group", group_data_width ) + if (column_addrw < (Min_addrw+extend_mwm_addr)) : + + temp_total_address *= 2 + index, columns, column_addrw, column_dataw = create_decompose_row(data_width, temp_total_address,group_data_width) + else: + break + + if (data_width_A < data_width_B): + mwm_ratio = data_width_B/data_width_A + extend_mwm_addr = int(math.log2(mwm_ratio)); + + print ("B>A",column_addrw, (address_width_A+extend_mwm_addr), address_width_A, address_width_B, mwm_ratio, extend_mwm_addr, "Group", group_data_width ) + if(column_addrw < (Min_addrw+extend_mwm_addr)) : + temp_total_address *= 2 + index, columns, column_addrw, column_dataw = create_decompose_row(data_width, temp_total_address,group_data_width) + else: + break + + + limit += 1 + + if limit > 10: + return + + index_A = index + index_B = index + column_addr_A = column_addrw + column_data_A = column_dataw + + column_addr_B = column_addrw + column_data_B = column_dataw + + + if(data_width_A != data_width_B): + if data_width_A > data_width_B: + mixedResult, mixedIndex, MixedDataWidth, MixedAddressWidth = find_mixed_width_row( index, int(data_width_A/data_width_B) ) + index_A = mixedIndex + index_B = index + + column_addr_A = MixedAddressWidth + column_data_A = MixedDataWidth + + + elif data_width_A < data_width_B: + mixedResult, mixedIndex, MixedDataWidth, MixedAddressWidth = find_mixed_width_row(index, int(data_width_B/data_width_A)) + index_A = index + index_B = mixedIndex + + column_addr_B = MixedAddressWidth + column_data_B = MixedDataWidth + + + + + bram_row = [index_A,index_B, columns,0,0] + bram_decompose_table.append(bram_row) + + total_address -= pow(2,column_addrw) + + + total_width += column_dataw + total_bram += columns + + result = "row " + str(row) + ") Primitive index A: " + str(index_A) + " addrA "+ str(column_addr_A) + " dataA: " + str(column_data_A) + " index B: " + str(index_B) + " addrB "+ str(column_addr_B) + " dataB: " + str(column_data_B) + " number of columns:" +str(columns) + print (result) + + + # Basic Mapping A + + #for x in range(0, columns): + # + # data_start = byteen_index*group_data_width + total_group_width + # data_end = data_start + column_dataw + # if data_end > data_width: + # data_end = data_width + # if data_end > ((byteen_index+1)*group_data_width): + # data_end = ((byteen_index+1)*group_data_width) + # + # data_end -= 1 + # nBits = data_end - data_start +1 + # interval = 0 + # + # + # bram_map = [row,x,data_start,nBits,interval,row,row,row,byteen_index,data_start,nBits,interval,row,row,row,byteen_index] + # + # if group_data_width != 0: + # total_group_width += column_dataw + # if total_group_width >= group_data_width : + # total_group_width = 0 + # byteen_index += 1 + # + # bram_mapping_table.append(bram_map) + + # Basic Mapping for Scan First + + # Mapping A + data_start = 0 + byteen_index = 0 + total_group_width = 0 + + for x in range(0, columns): + + data_start = byteen_index*group_data_width + total_group_width + data_end = data_start + column_dataw + if data_end > data_width: + data_end = data_width + if data_end > ((byteen_index+1)*group_data_width): + data_end = ((byteen_index+1)*group_data_width) + + data_end -= 1 + Repeat = 0 + + + bram_map = [row,x,data_end,data_start,Repeat,row,row,row,byteen_index,data_end,data_start,Repeat,row,row,row,byteen_index, column_addr_A, column_data_A, column_addr_B, column_data_B] + + if group_data_width != 0: + total_group_width += column_dataw + if total_group_width >= group_data_width : + total_group_width = 0 + byteen_index += 1 + + bram_mapping_table.append(bram_map) + + + + + + # Mapping A + if data_width_A > data_width_B: + + if group_data_width_A == 0: + group_data_width_A = data_width_A + + + data_start = 0 + byteen_index = 0 + total_group_width = 0 + temp_data_width_A = 0 + + for x in range(0, columns): + + Repeat = int(column_data_A / column_data_B) + + bram_map_A = bram_mapping_table[bram_mapping_table_index + x] + + bram_map_A[2] += extend_row_index*extend_data_width + bram_map_A[3] += extend_row_index*extend_data_width + bram_map_A[4] = Repeat + bram_map_A[5] = mixed_row + bram_map_A[6] = mixed_row + bram_map_A[7] = mixed_row + bram_map_A[8] = byteen_index + + # print (bram_map_A) + + if group_data_width_A != 0: + total_group_width += column_data_A + if total_group_width >= group_data_width_A : + total_group_width = 0 + byteen_index += 1 + + + temp_data_width_A += column_data_A + + + + + mixed_total_width += temp_data_width_A + if mixed_total_width >= data_width_A: + mixed_total_width = 0 + extend_row_index = 0 + mixed_row += 1 + else: + extend_row_index += 1 + extend_data_width = temp_data_width_A + + + if max_extend_row_index < extend_row_index: + max_extend_row_index = extend_row_index + + + #print (extend_row_index) + + + # Mapping B + if data_width_A < data_width_B: + + if group_data_width_B == 0: + group_data_width_B = data_width_B + + + data_start = 0 + byteen_index = 0 + total_group_width = 0 + temp_data_width_B = 0 + + for x in range(0, columns): + + Repeat = int(column_data_B / column_data_A) + + bram_map_B = bram_mapping_table[bram_mapping_table_index + x] + + bram_map_B[9] += extend_row_index*extend_data_width + bram_map_B[10] += extend_row_index*extend_data_width + bram_map_B[11] = Repeat + bram_map_B[12] = mixed_row + bram_map_B[13] = mixed_row + bram_map_B[14] = mixed_row + bram_map_B[15] = byteen_index + + # print (bram_map_A) + + if group_data_width_B != 0: + total_group_width += column_data_B + if total_group_width >= group_data_width_B : + total_group_width = 0 + byteen_index += 1 + + + temp_data_width_B += column_data_B + + mixed_total_width += temp_data_width_B + if mixed_total_width >= data_width_B: + mixed_total_width = 0 + extend_row_index = 0 + mixed_row += 1 + else: + extend_row_index += 1 + extend_data_width = temp_data_width_B + + + if max_extend_row_index < extend_row_index: + max_extend_row_index = extend_row_index + + #print (extend_row_index) + + + if total_address <= 0: + break + + bram_mapping_table_index += columns + + row += 1 + + #find Max Bram Address of Port A + max_primitive_addressA = 0 + + for row in bram_decompose_table: + primitive_data = bram_feature_table[row[0]][FEATURE.DATAW.value] + primitive_addr = bram_feature_table[row[0]][FEATURE.ADDRW.value] + if max_primitive_addressA < primitive_addr: + max_primitive_addressA = primitive_addr + + max_primitive_addressB = 0 + + for row in bram_decompose_table: + primitive_data = bram_feature_table[row[1]][FEATURE.DATAW.value] + primitive_addr = bram_feature_table[row[1]][FEATURE.ADDRW.value] + if max_primitive_addressB < primitive_addr: + max_primitive_addressB = primitive_addr + + max_rMux_index_A = 0; + max_rMux_index_B = 0; + for row in bram_mapping_table: + if row[5] > max_rMux_index_A: + max_rMux_index_A = row[5]; + if row[12] > max_rMux_index_B: + max_rMux_index_B = row[12]; + + + max_WenSel_index_A = 0; + max_WenSel_index_B = 0; + for row in bram_mapping_table: + if row[6] > max_WenSel_index_A: + max_WenSel_index_A = row[6]; + if row[13] > max_WenSel_index_B: + max_WenSel_index_B = row[13]; + + + + + rMux_mapping_table_A = list() + rMux_mapping_table_B = list() + + wen_sel_mapping_table_A = list() + wen_sel_mapping_table_B = list() + + + if (len(bram_decompose_table) > 1 ): + + if (address_width_A> max_primitive_addressA): + rMuxA = [address_width_A-1,max_primitive_addressA, data_width_A-1,0, max_rMux_index_A, 0 , 0] + rMux_mapping_table_A.append(rMuxA) + + WenSelA = [address_width_A-1,max_primitive_addressA, max_WenSel_index_A,0 , 0] + wen_sel_mapping_table_A.append(WenSelA) + + if max_extend_row_index != 0: + + if data_width_A < data_width_B: + + mixed_addr_width = int(max_primitive_addressA -max_primitive_addressB ) + + extend_addr = int(math.log2(max_extend_row_index+1)) + + for index in range(0,mixed_addr_width): + row = index + address_mapping_table_A.append(row) + + for index in range(0,extend_addr): + row = index + max_primitive_addressA + address_mapping_table_A.append(row) + + for index in range(mixed_addr_width,max_primitive_addressA): + row = index + address_mapping_table_A.append(row) + + for index in range(max_primitive_addressA+extend_addr,address_width_A): + row = index + address_mapping_table_A.append(row) + + + if (address_width_B> max_primitive_addressB): + rMuxB = [address_width_B-1,max_primitive_addressB, data_width_B-1,0, max_rMux_index_B, 0, 0] + rMux_mapping_table_B.append(rMuxB) + + WenSelB = [address_width_B-1,max_primitive_addressB, max_WenSel_index_B,0 , 0] + wen_sel_mapping_table_B.append(WenSelB) + + if max_extend_row_index != 0: + + if data_width_B < data_width_A: + + mixed_addr_width = int(max_primitive_addressB -max_primitive_addressA ) + + extend_addr = int(math.log2(max_extend_row_index+1)) + + for index in range(0,mixed_addr_width): + row = index + address_mapping_table_B.append(row) + + for index in range(0,extend_addr): + row = index + max_primitive_addressB + address_mapping_table_B.append(row) + + for index in range(mixed_addr_width,max_primitive_addressB): + row = index + address_mapping_table_B.append(row) + + for index in range(max_primitive_addressB+extend_addr,address_width_B): + row = index + address_mapping_table_B.append(row) + + + result = "Total BRAM used:" + str(total_bram) + print (result) + print("") + +#def create_decompose_table_scan_row(address_width, data_width, size, group_data_width ): +# +# total_width = 0 +# total_bram = 0 +# row = 0 +# global bram_decompose_mode +# global in_addr_width_a +# global in_data_width_a +# global in_addr_width_b +# global in_data_width_b +# global byteen_width +# global byteen_enable +# global group_columns +# global bram_decompose_table +# global bram_decompose_byteen_table +# global bram_mapping_table +# global rMux_mapping_table_A +# global rMux_mapping_table_B +# global wen_sel_mapping_table_A +# global wen_sel_mapping_table_B +# global actual_size +# +# bram_decompose_byteen_table = list() +# group_columns = 1 +# group_data_count = 0; +# group_data_ptr = 0; +# for x in range(0, data_width): +# bram_data_row = [group_data_ptr,1] +# bram_decompose_byteen_table.append(bram_data_row) +# +# group_data_count += 1 +# if(group_data_count == group_data_width): +# group_data_ptr += 1 +# group_data_count = 0 +# +# if group_data_width != 0: +# byteen_width = group_data_ptr +# byteen_enable = 1 +# if ( ( data_width % group_data_width ) != 0): +# byteen_width += 1 +# result = "byteen width: " + str(byteen_width) + " Group Data Width: " + str(group_data_width) +# print (result) +# +# +# bram_decompose_mode = 1 # 1: LOOP ROW FIRST", 0: LOOP COLUMN FIRST" +# +# total_address = pow(2,address_width) +# +# if size != 0: +# if size <= total_address: +# total_address = size +# +# actual_size = total_address +# +# in_addr_width_a = address_width +# in_data_width_a = data_width +# in_addr_width_b = address_width +# in_data_width_b = data_width +# +# bram_decompose_table = list() +# bram_mapping_table = list() +# +# if group_data_width == 0: +# group_data_width = data_width +# while True: +# +# index, columns, column_addrw, column_dataw = create_decompose_row(data_width, total_address,group_data_width) +# bram_row = [index,index, columns,0,0] +# bram_decompose_table.append(bram_row) +# +# total_address -= pow(2,column_addrw) +# +# +# total_width += column_dataw +# total_bram += columns +# +# result = "row " + str(row) + ") Primitive index: " + str(index) + " addr"+ str(column_addrw) + " data: " + str(column_dataw) + " number of columns:" +str(columns) +# print (result) +# +# data_start = 0 +# byteen_index = 0 +# total_group_width = 0 +# for x in range(0, columns): +# +# data_start = byteen_index*group_data_width + total_group_width +# data_end = data_start + column_dataw +# if data_end > data_width: +# data_end = data_width +# if data_end > ((byteen_index+1)*group_data_width): +# data_end = ((byteen_index+1)*group_data_width) +# +# data_end -= 1 +# nBits = data_end - data_start +1 +# interval = 0 +# +# +# bram_map = [row,x,data_start,nBits,interval,row,row,row,byteen_index,data_start,nBits,interval,row,row,row,byteen_index] +# +# if group_data_width != 0: +# total_group_width += column_dataw +# if total_group_width >= group_data_width : +# total_group_width = 0 +# byteen_index += 1 +# +# bram_mapping_table.append(bram_map) +# +# +# +# +# if total_address <= 0: +# break +# +# row += 1 +# +# #find Max Bram Address of Port A +# max_primitive_addressA = 0 +# for row in bram_decompose_table: +# primitive_data = bram_feature_table[row[0]][FEATURE.DATAW.value] +# primitive_addr = bram_feature_table[row[0]][FEATURE.ADDRW.value] +# if max_primitive_addressA < primitive_addr: +# max_primitive_addressA = primitive_addr +# +# +# max_primitive_addressB = 0 +# for row in bram_decompose_table: +# primitive_data = bram_feature_table[row[1]][FEATURE.DATAW.value] +# primitive_addr = bram_feature_table[row[1]][FEATURE.ADDRW.value] +# if max_primitive_addressB < primitive_addr: +# max_primitive_addressB = primitive_addr +# +# max_rMux_index_A = 0; +# max_rMux_index_B = 0; +# for row in bram_mapping_table: +# if row[4] > max_rMux_index_A: +# max_rMux_index_A = row[4]; +# if row[10] > max_rMux_index_B: +# max_rMux_index_B = row[10]; +# +# rMux_mapping_table_A = list() +# rMux_mapping_table_B = list() +# +# wen_sel_mapping_table_A = list() +# wen_sel_mapping_table_B = list() +# +# if (len(bram_decompose_table) > 1 ): +# rMuxA = [address_width-1,max_primitive_addressA, data_width-1,0, max_rMux_index_A, 0] +# rMux_mapping_table_A.append(rMuxA) +# +# rMuxB = [address_width-1,max_primitive_addressB, data_width-1,0, max_rMux_index_B, 0] +# rMux_mapping_table_B.append(rMuxB) +# +# WenSelA = [address_width-1,max_primitive_addressB, len(bram_decompose_table)-1,0] +# wen_sel_mapping_table_A.append(WenSelA) +# +# WenSelB = [address_width-1,max_primitive_addressB, len(bram_decompose_table)-1,0] +# wen_sel_mapping_table_B.append(WenSelB) +# +# result = "Total BRam used:" + str(total_bram) +# print (result) + + +def mapping_mux_wen(address_width_A, data_width_A, address_width_B, data_width_B) : + + global bram_decompose_table + global bram_decompose_byteen_table + global bram_mapping_table + global rMux_mapping_table_A + global rMux_mapping_table_B + global wen_sel_mapping_table_A + global wen_sel_mapping_table_B + global address_mapping_table_A + global address_mapping_table_B + global byteen_width_A + global byteen_width_B + + + #find Max Bram Address of Port A + max_primitive_addressA = 0 + + for row in bram_decompose_table: + primitive_data = bram_feature_table[row[0]][FEATURE.DATAW.value] + primitive_addr = bram_feature_table[row[0]][FEATURE.ADDRW.value] + if max_primitive_addressA < primitive_addr: + max_primitive_addressA = primitive_addr + + max_primitive_addressB = 0 + + for row in bram_decompose_table: + primitive_data = bram_feature_table[row[1]][FEATURE.DATAW.value] + primitive_addr = bram_feature_table[row[1]][FEATURE.ADDRW.value] + if max_primitive_addressB < primitive_addr: + max_primitive_addressB = primitive_addr + + max_rMux_index_A = 0; + max_rMux_index_B = 0; + for row in bram_mapping_table: + if row[5] > max_rMux_index_A: + max_rMux_index_A = row[5]; + if row[12] > max_rMux_index_B: + max_rMux_index_B = row[12]; + + + max_WenSel_index_A = 0; + max_WenSel_index_B = 0; + for row in bram_mapping_table: + if row[6] > max_WenSel_index_A: + max_WenSel_index_A = row[6]; + if row[13] > max_WenSel_index_B: + max_WenSel_index_B = row[13]; + max_extend_row_index=0 + + if data_width_A > data_width_B : + wen_sel_mapping_table_B = list() + rMux_mapping_table_B = list() + address_mapping_table_B = list() + + max_extend_row_index = data_width_A/data_width_B + + extend_addr = int(math.log2(max_extend_row_index+1)) + if (len(wen_sel_mapping_table_A)>0): + for wen_sel_A in wen_sel_mapping_table_A: + + rMuxB = [wen_sel_A[0] + extend_addr, wen_sel_A[1], data_width_B-1,0, max_rMux_index_B, 0 , 0] + rMux_mapping_table_B.append(rMuxB) + + WenSelB = [wen_sel_A[0] + extend_addr, wen_sel_A[1], max_WenSel_index_B,0 , 0] + wen_sel_mapping_table_B.append(WenSelB) + + else: + rMuxB = [max_primitive_addressA + extend_addr - 1,max_primitive_addressA, data_width_B-1,0, max_rMux_index_B, 0 , 0] + rMux_mapping_table_B.append(rMuxB) + + WenSelB = [max_primitive_addressA + extend_addr - 1,max_primitive_addressA, max_WenSel_index_B,0 , 0] + wen_sel_mapping_table_B.append(WenSelB) + + for index in range(0,extend_addr): + row = index + max_primitive_addressA + address_mapping_table_B.append(row) + + for index in range(0,max_primitive_addressA): + row = index + address_mapping_table_B.append(row) + + for index in range(max_primitive_addressA+extend_addr,address_width_B): + row = index + address_mapping_table_B.append(row) + + + + + + + if data_width_B > data_width_A : + wen_sel_mapping_table_A = list() + rMux_mapping_table_A = list() + address_mapping_table_A = list() + + max_extend_row_index = data_width_B/data_width_A + + extend_addr = int(math.log2(max_extend_row_index+1)) + if (len(wen_sel_mapping_table_A)>0): + for wen_sel_B in wen_sel_mapping_table_B: + + rMuxA = [wen_sel_B[0] + extend_addr, wen_sel_B[1], data_width_A-1,0, max_rMux_index_A, 0 , 0] + rMux_mapping_table_A.append(rMuxA) + + WenSelA = [wen_sel_B[0] + extend_addr, wen_sel_B[1], max_WenSel_index_A,0 , 0] + wen_sel_mapping_table_A.append(WenSelA) + + else: + rMuxA = [max_primitive_addressB + extend_addr - 1,max_primitive_addressB, data_width_A-1,0, max_rMux_index_A, 0 , 0] + rMux_mapping_table_A.append(rMuxA) + + WenSelA = [max_primitive_addressB + extend_addr - 1,max_primitive_addressB, max_WenSel_index_A,0 , 0] + wen_sel_mapping_table_A.append(WenSelA) + + for index in range(0,extend_addr): + row = index + max_primitive_addressB + address_mapping_table_A.append(row) + + for index in range(0,max_primitive_addressB): + row = index + address_mapping_table_A.append(row) + + for index in range(max_primitive_addressB+extend_addr,address_width_A): + row = index + address_mapping_table_A.append(row) + + + + +def create_decompose_table_scan_row_mwm(address_width_A, data_width_A, size, group_data_width, address_width_B, data_width_B, group_data_width_B, memory_type): + + result = True + if(data_width_B != 0) | (address_width_B!=0): + result, address_width_A, data_width_A, size_A, group_data_width, address_width_B, data_width_B, size_B = check_row_mwm (address_width_A, data_width_A, size, group_data_width, address_width_B, data_width_B) + else: + size_A = size + size_B = size + + + if result == False: + print("Error! don't support current setting in Mixed Width Mode ") + return + + print (address_width_A, data_width_A, size_A, group_data_width, address_width_B, data_width_B, size_B, group_data_width_B) + + scan_index = 0 + + if (data_width_B == 0) | (data_width_B == data_width_A) : + create_decompose_table_scan_row(scan_index, address_width_A, data_width_A, size_A, group_data_width, address_width_A, data_width_A, size_A, group_data_width_B) + + + else:# Mixed Width Mode + print("Mixed Width Mode is Enabled!") + if data_width_A > data_width_B: + scan_index = 1 + + #separate tdp and sdp since tdp doesnt want to pickup default gdw=8 + if args.memory_type == 'sdp_ram': + create_decompose_table_scan_row(scan_index, address_width_A, data_width_A, size_A, group_data_width, address_width_B, data_width_B, size_B, group_data_width_B) + elif args.memory_type == 'tdp_ram': + group_data_width = 0 + group_data_width_B = 0 + create_decompose_table_scan_row(scan_index, address_width_A, data_width_A, size_A, group_data_width, address_width_B, data_width_B, size_B, group_data_width_B) + + #result = "group_data_width:" + str(group_data_width) + " group_data_width_B: " + str(group_data_width_B) + #print(result) + + +def create_decompose_table_scan_row_mwm_byteEn(address_width_A, data_width_A, size, group_data_width, address_width_B, data_width_B, group_data_width_A, group_data_width_B, memory_type): + + global in_addr_width_a + global in_data_width_a + global in_addr_width_b + global in_data_width_b + global byteen_width_A + global byteen_width_B + global actual_size_A + global actual_size_B + + + result = True + if(data_width_B != 0) | (address_width_B!=0): + result, address_width_A, data_width_A, size_A, group_data_width, address_width_B, data_width_B, size_B = check_row_mwm (address_width_A, data_width_A, size, group_data_width, address_width_B, data_width_B) + else: + size_A = size + size_B = size + + + if result == False: + print("Error! don't support current setting in Mixed Width Mode ") + return + + if (group_data_width_A == 0): + if(group_data_width !=0): + group_data_width_A = group_data_width + else: + print("Please input paramter group_data_width_A or group_data_width ") + return + + if (group_data_width_B == 0): + if(group_data_width !=0): + group_data_width_B = group_data_width + else: + print("Please input paramter group_data_width_B or group_data_width ") + return + + if(data_width_A == data_width_B): + create_decompose_table_scan_row_mwm(address_width_A, data_width_A, size, group_data_width_A, address_width_A, data_width_A, group_data_width_B, memory_type) + + Max_byteen_index_A = 0 + Max_byteen_index_B = 0 + + + for row in bram_mapping_table: + msb_data_A = row[3] + msb_data_B = row[9] + + byteen_index_A = int( (msb_data_A) / group_data_width_A ) + byteen_index_B = int( (msb_data_B) / group_data_width_B ) + + if byteen_index_A> Max_byteen_index_A : + Max_byteen_index_A = byteen_index_A + + if byteen_index_B> Max_byteen_index_B : + Max_byteen_index_B = byteen_index_B + + row[8] = byteen_index_A + row[15]= byteen_index_B + + + + byteen_width_A = Max_byteen_index_A+1 + byteen_width_B = Max_byteen_index_B+1 + + + elif (data_width_A > data_width_B): + create_decompose_table_scan_row_mwm(address_width_A, data_width_A, size, group_data_width_A, address_width_A, data_width_A, group_data_width_A, memory_type) + + print("MWM remapping Byte Enable mode") + + current_data_ptr = 0 + + group_data_ptr = 0 + + + row_index = 0 + byteen_index = 0 + + + for row in bram_mapping_table: + + index_row = row[0] + index_column = row[1] + + msb_data_A = row[2] + lsb_data_A = row[3] + + primitive_dataB = row[19] + + + row_index = int(msb_data_A/data_width_B) + + lsb_data_B = int(lsb_data_A%data_width_B) + msb_data_B = int(msb_data_A%data_width_B) + + byteen_index = int(lsb_data_B/group_data_width_B) + + row[9] = msb_data_B + row[10] = lsb_data_B + + row[12] = row_index + row[13] = row_index + row[14] = row_index + row[15] = byteen_index + + + # lsb_data_B = current_data_ptr + # + # msb_data_B = current_data_ptr + primitive_dataB + # + # + # if(msb_data_B>= data_width_B): + # msb_data_B = data_width_B + # + # row[9] = msb_data_B-1 + # row[10] = lsb_data_B + # + # row[12] = row_index + # row[13] = row_index + # row[14] = row_index + # row[15] = byteen_index + + + # current_data_ptr += primitive_dataB + # if(current_data_ptr>= data_width_B): + # current_data_ptr = 0 + # group_data_ptr = 0 + # byteen_index = 0 + # row_index += 1 + # + # else: + # group_data_ptr += primitive_dataB + # if (group_data_ptr >= group_data_width_B): + # group_data_ptr = 0 + # byteen_index += 1; + + print("Mapping ", address_width_A, data_width_A, address_width_B, data_width_B) + mapping_mux_wen(address_width_A, data_width_A, address_width_B, data_width_B) + + in_addr_width_a = address_width_A + in_data_width_a = data_width_A + in_addr_width_b = address_width_B + in_data_width_b = data_width_B + + byteen_width_A = int(data_width_A / group_data_width_A) + byteen_width_B = int(data_width_B / group_data_width_B) + + actual_size_A = pow(2,address_width_A) + if size_A != 0: + if size_A <= actual_size_A: + actual_size_A = size_A + + actual_size_B = pow(2,address_width_B) + if size_B != 0: + if size_B <= actual_size_B: + actual_size_B = size_B + + + print("PortA: ", in_addr_width_a, in_data_width_a, actual_size_A, group_data_width_A, byteen_width_A) + print("PortB: ", in_addr_width_b, in_data_width_b, actual_size_B, group_data_width_B, byteen_width_B) + print("") + + elif (data_width_A < data_width_B): + create_decompose_table_scan_row_mwm(address_width_B, data_width_B, size, group_data_width_B, address_width_B, data_width_B, group_data_width_B, memory_type) + + print("MWM remapping Byte Enable mode") + + current_data_ptr = 0 + + group_data_ptr = 0 + + + row_index = 0 + byteen_index = 0 + + + for row in bram_mapping_table: + + index_row = row[0] + index_column = row[1] + + msb_data_B = row[9] + lsb_data_B = row[10] + + primitive_dataA = row[17] + + row_index = int(msb_data_B/data_width_A) + + lsb_data_A = int(lsb_data_B%data_width_A) + msb_data_A = int(msb_data_B%data_width_A) + + byteen_index = int(lsb_data_A/group_data_width_A) + + row[2] = msb_data_A + row[3] = lsb_data_A + + row[5] = row_index + row[6] = row_index + row[7] = row_index + row[8] = byteen_index + + #lsb_data_A = current_data_ptr + # + #msb_data_A = current_data_ptr + primitive_dataA + # + # + #if(msb_data_A>= data_width_A): + # msb_data_A = data_width_A + # + #row[2] = msb_data_A-1 + #row[3] = lsb_data_A + # + #row[5] = row_index + #row[6] = row_index + #row[7] = row_index + #row[8] = byteen_index + # + # + #current_data_ptr += primitive_dataA + #if(current_data_ptr>= data_width_A): + # current_data_ptr = 0 + # group_data_ptr = 0 + # byteen_index = 0 + # row_index += 1 + # + #else: + # group_data_ptr += primitive_dataA + # if (group_data_ptr >= group_data_width_A): + # group_data_ptr = 0 + # byteen_index += 1; + + print("Mapping ", address_width_A, data_width_A, address_width_B, data_width_B) + mapping_mux_wen(address_width_A, data_width_A, address_width_B, data_width_B) + + in_addr_width_a = address_width_A + in_data_width_a = data_width_A + in_addr_width_b = address_width_B + in_data_width_b = data_width_B + + if (group_data_width_A != 0): + byteen_width_A = int(data_width_A / group_data_width_A) + + if (group_data_width_B != 0): + byteen_width_B = int(data_width_B / group_data_width_B) + + actual_size_A = pow(2,address_width_A) + if size_A != 0: + if size_A <= actual_size_A: + actual_size_A = size_A + + actual_size_B = pow(2,address_width_B) + if size_B != 0: + if size_B <= actual_size_B: + actual_size_B = size_B + + + print("PortA: ", in_addr_width_a, in_data_width_a, actual_size_A, group_data_width_A, byteen_width_A) + print("PortB: ", in_addr_width_b, in_data_width_b, actual_size_B, group_data_width_B, byteen_width_B) + print("") + + +def write_config_file(): + + config_param = list() + + config_param.append(FAMILY) + config_param.append(in_addr_width_a) + config_param.append(in_data_width_a) + config_param.append(in_addr_width_b) + config_param.append(in_data_width_b) + + config_param.append(actual_size_A) + config_param.append(actual_size_B) + config_param.append(byteen_width) + config_param.append(group_data_width) + config_param.append(group_columns) + + config_param.append(bram_decompose_mode) + config_param.append(bram_feature_table) + config_param.append(group_columns) + + config_param.append(bram_decompose_table) + config_param.append(bram_mapping_table) + config_param.append(rMux_mapping_table_A) + config_param.append(wen_sel_mapping_table_A) + config_param.append(rMux_mapping_table_B) + config_param.append(wen_sel_mapping_table_B) + + config_param.append(data_mapping_table_A) + config_param.append(data_mapping_table_B) + + config_param.append(address_mapping_table_A) + config_param.append(address_mapping_table_B) + + with open('mem_config.txt', 'w') as f: + f.write(json.dumps(config_param)) + +if __name__ == "__main__": + + parser = argparse.ArgumentParser(description='Memory Decompose to BRAM') + parser.add_argument("memory_type", choices=['sp_ram', 'sdp_ram', 'tdp_ram'], help="Memory type") + parser.add_argument("address_width", help="Address Width") + parser.add_argument("data_width", help="Data Width") + parser.add_argument("--size", default=0, help="Memory Size, it will be limited by the address_width") + parser.add_argument("--address_width_B", default=0, help="address width of Port B or Read Port") + parser.add_argument("--data_width_B" , default=0, help="data width of Port B or Read Port") + parser.add_argument("--family", choices=['Trion', 'Titanium'], default='Trion', help="Device family (SVF only)") + parser.add_argument("--decompose", choices=['area', 'speed'], default='speed', help="Decompose mode") + parser.add_argument("--group_data_width",default=8,help="Group data width for each byteen Enable. If 0, it will disable byte enable.") + parser.add_argument("--group_data_width_A",default=0,help="Group data width for each byteen Enable in Port A. If 0, it will disable byte enable.") + parser.add_argument("--group_data_width_B",default=0,help="Group data width for each byteen Enable in Port B. If 0, it will disable byte enable.") + + + # run parser + args = parser.parse_args() + + if args.memory_type == 'sp_ram': + print("\nSingle-port RAM") + print("-----------------") + + if args.family == 'Titanium': + bram_feature_table = EFX_RAM10_feature_table + FAMILY = 1 + elif args.family == 'Trion': + bram_feature_table = EFX_RAM_5K_feature_table + FAMILY = 0 + + if args.decompose == 'speed': + if ((args.data_width_B == 0 )|(args.data_width==args.data_width_B)) & ((args.address_width_B == 0 )|(args.address_width==args.address_width_B)): + create_decompose_table_scan_row_mwm(int(args.address_width), int(args.data_width), int(args.size), int(args.group_data_width), int(args.address_width_B), int(args.data_width_B), int(args.group_data_width), str(args.memory_type)) + else: + print("Single Port RAM has no Mixed Width Mode ! \n") + + #if args.family == 'Titanium': + # bram_feature_table = EFX_RAM10_MWM_feature_table + # FAMILY = 1 + #elif args.family == 'Trion': + # bram_feature_table = EFX_RAM_5K_MWM_feature_table + # FAMILY = 0 + # + #create_decompose_table_scan_row_mwm(int(args.address_width), int(args.data_width), int(args.size), int(args.group_data_width), int(args.address_width_B), int(args.data_width_B), int(args.group_data_width)) + + + elif args.decompose == 'area': + print("Currently support decompose-Speed Mode only\n") + #if (args.data_width_B == 0 ) & (args.address_width_B == 0 ): + # create_decompose_table_scan_col(int(args.address_width), int(args.data_width), int(args.size), int(args.group_data_width), int(args.address_width_B), int(args.data_width_B)) + #else: + # print("Area Mode don't support Mixed Width Mode./n ") + + group_data_width = args.group_data_width + group_data_width_A = args.group_data_width_A + group_data_width_B = args.group_data_width_B + + + #create_feature_file() + create_decompose_file() + create_memory_init_file() + + write_config_file() + + elif args.memory_type == 'sdp_ram': + print("\nSimple Dual-port RAM") + print("----------------------") + + + if args.family == 'Titanium': + bram_feature_table = EFX_RAM10_feature_table + FAMILY = 1 + elif args.family == 'Trion': + bram_feature_table = EFX_RAM_5K_feature_table + FAMILY = 0 + + if ((args.data_width_B == 0 )|(args.data_width==args.data_width_B)) & ((args.address_width_B == 0 )|(args.address_width==args.address_width_B)): + args.data_width_B = args.data_width + args.address_width_B = args.address_width + if args.decompose == 'speed': + if (args.group_data_width == 0) & (args.group_data_width_A == 0) & (args.group_data_width_B == 0) : + create_decompose_table_scan_row_mwm(int(args.address_width), int(args.data_width), int(args.size), int(args.group_data_width), int(args.address_width_B), int(args.data_width_B), int(args.group_data_width), str(args.memory_type)) + else: + print("Byte Enable Mode!") + create_decompose_table_scan_row_mwm_byteEn(int(args.address_width), int(args.data_width), int(args.size), int(args.group_data_width), int(args.address_width_B), int(args.data_width_B), int(args.group_data_width_A),int(args.group_data_width_B), str(args.memory_type)) + + elif args.decompose == 'area': + print("Currently Support decompose-Speed Mode only\n") + #create_decompose_table_scan_col(int(args.address_width), int(args.data_width), int(args.size), int(args.group_data_width), int(args.address_width_B), int(args.data_width_B)) + else: + print("Mixed Width Mode is Enabled!") + + if args.family == 'Titanium': + bram_feature_table = EFX_RAM10_MWM_feature_table + FAMILY = 1 + elif args.family == 'Trion': + bram_feature_table = EFX_RAM_5K_MWM_feature_table + FAMILY = 0 + + if (args.group_data_width == 0) & (args.group_data_width_A == 0) & (args.group_data_width_B == 0) : + if args.decompose == 'speed': + print("Speed Mode.") + create_decompose_table_scan_row_mwm(int(args.address_width), int(args.data_width), int(args.size), int(args.group_data_width), int(args.address_width_B), int(args.data_width_B), int(args.group_data_width), str(args.memory_type)) + + elif args.decompose == 'area': + print("Area Mode don't support Mixed Width Configuration ") + + + else: + print("Byte Enable Mode!") + + if args.decompose == 'speed': + print("Speed Mode") + create_decompose_table_scan_row_mwm_byteEn(int(args.address_width), int(args.data_width), int(args.size), int(args.group_data_width), int(args.address_width_B), int(args.data_width_B), int(args.group_data_width_A),int(args.group_data_width_B), str(args.memory_type)) + + elif args.decompose == 'area': + print("Area Mode") + print("------------------------------------------------------- ") + print("Oopps! Area Mode dont support Mixed Width Configuration \n") + + + + + group_data_width = args.group_data_width + group_data_width_A = args.group_data_width_A + group_data_width_B = args.group_data_width_B + + + #create_feature_file() + create_decompose_file() + create_memory_init_file() + + write_config_file() + + elif args.memory_type == 'tdp_ram': + print("\nTrue Dual-port RAM") + print("-------------------") + + #if (args.group_data_width_A ==0) & (args.group_data_width_B ==0): + # if (args.group_data_width != 0 ): + # print("Please use the group_data_width_A or group_data_width_B to define group data width of corresponding port. ") + + + if args.family == 'Titanium': + bram_feature_table = EFX_DPRAM10_feature_table + FAMILY = 1 + elif args.family == 'Trion': + bram_feature_table = EFX_DPRAM_5K_feature_table + FAMILY = 0 + + + if ((args.data_width_B == 0 )|(args.data_width==args.data_width_B)) & ((args.address_width_B == 0 )|(args.address_width==args.address_width_B)): + args.data_width_B = args.data_width + args.address_width_B = args.address_width + if args.decompose == 'speed': + if (args.group_data_width == 0) & (args.group_data_width_A == 0) & (args.group_data_width_B == 0) : + create_decompose_table_scan_row_mwm(int(args.address_width), int(args.data_width), int(args.size), int(args.group_data_width), int(args.address_width_B), int(args.data_width_B), int(args.group_data_width), str(args.memory_type)) + else: + print("Byte Enable Mode!") + create_decompose_table_scan_row_mwm_byteEn(int(args.address_width), int(args.data_width), int(args.size), int(args.group_data_width), int(args.address_width_B), int(args.data_width_B), int(args.group_data_width_A),int(args.group_data_width_B), str(args.memory_type)) + + elif args.decompose == 'area': + print("Current support decompose-Speed Mode only\n") + #create_decompose_table_scan_col(int(args.address_width), int(args.data_width), int(args.size), int(args.group_data_width), int(args.address_width_B), int(args.data_width_B)) + else: + print("Mixed Width Mode is Enabled!") + print("Oopps! Currently not support Mixed Width Mode!\n") + + #if args.family == 'Titanium': + # bram_feature_table = EFX_DPRAM10_MWM_feature_table + # FAMILY = 1 + #elif args.family == 'Trion': + # bram_feature_table = EFX_DPRAM_5K_MWM_feature_table + # FAMILY = 0 + # + #if (args.group_data_width_A == 0) & (args.group_data_width_B == 0) : + # if args.decompose == 'speed': + # print("Speed Mode") + # create_decompose_table_scan_row_mwm(int(args.address_width), int(args.data_width), int(args.size), int(args.group_data_width), int(args.address_width_B), int(args.data_width_B), int(args.group_data_width), str(args.memory_type)) + # + # elif args.decompose == 'area': + # print("Area Mode don't support Mixed Width Case ") + + + if (args.group_data_width_A != 0) & (args.group_data_width_B != 0): + print("Byte Enable Mode!") + print("Oopps! Currently not support Byte Enable Mode!\n") + + #if args.decompose == 'speed': + # create_decompose_table_scan_row_mwm_byteEn(int(args.address_width), int(args.data_width), int(args.size), int(args.group_data_width), int(args.address_width_B), int(args.data_width_B), int(args.group_data_width_A),int(args.group_data_width_B), str(args.memory_type)) + #elif args.decompose == 'area': + # print("Area Mode dont support Mixed Width Case") + + + + group_data_width = args.group_data_width + group_data_width_A = args.group_data_width_A + group_data_width_B = args.group_data_width_B + + #create_feature_file() + create_decompose_file() + create_memory_init_file() + + write_config_file() + + + + \ No newline at end of file diff --git a/hw/efinix_fpga/ip/bram/efx_mem_init_script.py b/hw/efinix_fpga/ip/bram/efx_mem_init_script.py new file mode 100644 index 0000000..5bf8073 --- /dev/null +++ b/hw/efinix_fpga/ip/bram/efx_mem_init_script.py @@ -0,0 +1,420 @@ +""" + +Copyright (C) 2022 Efinix Inc. All rights reserved. + +No portion of this code may be reused, modified or +distributed in any way without the expressed written +consent of Efinix Inc. + +Created on Dec 22, 2021 + +@author: Dragon Lai +""" +import sys +import os +import argparse +import math +import json + +from enum import Enum + +FAMILY = 0 +in_addr_width_a = 0 +in_data_width_a = 0 +in_addr_width_b = 0 +in_data_width_b = 0 + +actual_size_A = 0 +actual_size_B = 0 +byteen_width = 0 +group_data_width = 0 +group_columns = 0 + +bram_decompose_mode = 0 +bram_feature_table = list() +group_columns = list() + +bram_decompose_table = list() +bram_mapping_table = list() +rMux_mapping_table_A = list() +wen_sel_mapping_table_A = list() +rMux_mapping_table_B = list() +wen_sel_mapping_table_B = list() + +data_mapping_table_A = list() +data_mapping_table_B = list() + +address_mapping_table_A = list() +address_mapping_table_B = list() + + +mem_table = list() + +def remove_comment(InString): + + result = False + + outString = InString + + #find comment sytnax '//' + Index_start = InString.find('//') + + + #find end of line \n after // + if (Index_start != -1 ): + Index_end = InString.find('\n',Index_start) + + if (Index_end == -1): + Index_end = len(InString) + + if (Index_start == 0 ): + outString = InString[Index_end:] + else: + outString = InString[:Index_start] + InString[Index_end:] + + result = True + + return result, outString + +def remove_comments(InString): + + result = True + TempString = InString + + while(result): + result, OutString = remove_comment(TempString) + TempString = OutString + + return OutString + +def dump2memTable(InString,in_format, port, in_data_width, in_addr_width): + ProcesseData = remove_comments(InString) + + #print( in_format, in_data_width, in_addr_width) + + #print(ProcesseData) + + lines = ProcesseData.split() + + #print(lines) + + bit_count = 1 + + if (in_format == 'hex'): + bit_count = 4 + + line_ptr = 0 + for line in lines: + if (line_ptr+1) > (2**in_addr_width): + break + + bit_ptr = 0 + + for bits in reversed(line): + + if (bit_ptr+1) > in_data_width: + break + + value = int(bits, 16) + + + for x in range(0,bit_count): + # print ( line_ptr, bit_ptr) + if (bit_ptr+1) > in_data_width: + break + + mem_table[line_ptr][bit_ptr] = (value % 2) + + value = int(value / 2) + bit_ptr = bit_ptr + 1 + + #print(mem_table[line_ptr]) + line_ptr = line_ptr+1 + + + #print(mem_table) + create_memory_init_file(port,in_data_width, in_addr_width ) + + +def create_prmitive_map(data_width, addr_width, primitive_addr_width, primiive_data_width, map_data_msb, map_data_lsb, repeat, interval, row_index): + + #print(data_width, addr_width, primitive_addr_width, primiive_data_width, map_data_msb, map_data_lsb, repeat, row_index) + #print(data_width, addr_width, primitive_addr_width, primiive_data_width, map_data_msb, map_data_lsb, repeat, interval, row_index) + + primitive_mem = list() + + #initial primitive memory profile + for y in range(0,(2**primitive_addr_width)): + row = list() + for x in range(0,primiive_data_width): + row.append(int(0)) + primitive_mem.append(row) + + + primitive_y = int(0) + primitive_x = int(0) + + addr_start = row_index * (2**primitive_addr_width) + addr_End = (row_index+1)* (2**primitive_addr_width) -1 + + #print(addr_start, addr_End, primiive_data_width, map_data_lsb,map_data_msb ) + + if(addr_End > (2**addr_width)-1): + addr_End = (2**addr_width)-1 + + for y in range(addr_start, addr_End+1 ): + init_row = mem_table[y] + + primitive_x = int(0) + if repeat == 0: + for x in range(map_data_lsb, map_data_msb +1 ) : + if (primitive_x+1) > primiive_data_width: + break + + primitive_mem[primitive_y][primitive_x] = init_row[x] + primitive_x = primitive_x+1 + + #if (map_data_lsb == 10 ): + # print (y, primitive_y,primitive_x, primitive_mem[primitive_y], init_row, map_data_lsb,( map_data_msb-map_data_lsb) +1 ) + else: + for r_x in range(0,repeat): + temp_data_lsb = map_data_lsb + (interval * r_x) + temp_data_msb = map_data_msb + (interval * r_x) + for x in range(temp_data_lsb, temp_data_msb +1 ) : + if (primitive_x+1) > primiive_data_width: + break + + primitive_mem[primitive_y][primitive_x] = init_row[x] + primitive_x = primitive_x+1 + + primitive_y = primitive_y+1 + + + #print(primitive_mem) + converted_init_mem = list() + + #initial primitive init profile + for y in range(0,40): + row =list() + for x in range(0,32): + row.append(int(0)) + converted_init_mem.append(row) + + + #initial primitive memory profile + + primitive_bit_ptr = int(0) + primitive_byte = int(0) + + primitive_x_ptr = int(31) + primitive_y_ptr = int(0) + + + for y in range(0,(2**primitive_addr_width)): + for x in range(0,primiive_data_width): + primitive_byte = primitive_byte + primitive_mem[y][x] * (2** primitive_bit_ptr) + + primitive_bit_ptr = primitive_bit_ptr + 1 + if primitive_bit_ptr >= 8: + converted_init_mem[primitive_y_ptr][primitive_x_ptr] = primitive_byte + primitive_bit_ptr = 0 + primitive_byte = 0 + + primitive_x_ptr = primitive_x_ptr-1 + if primitive_x_ptr < 0: + primitive_x_ptr = 31 + + primitive_y_ptr = primitive_y_ptr +1 + if primitive_y_ptr >= 40: + break + + + return converted_init_mem + +def create_memory_init_file(port, data_width, addr_width ): + f = open("bram_ini.vh", "w") + + line = '\n' + line += 'function [255:0] bram_ini_table;\n' + line += 'input integer index;//Mode type \n' + line += 'input integer val_; //Port A index, Port B Index, Number of Items in Loop, Port A Start, Port B Start, reserved \n' + line += 'case (index)\n' + f.write (line) + y = 0 + + for row in bram_mapping_table: + + line = "" + x = 0 + + line += '%4s: bram_ini_table=\n' %(y) + + index_primitive_row = row[0] + index_primitive_column = row[1] + + DataA_MSB = row[2] + DataA_LSB = row[3] + DataA_REPEAT = row[4] + DataA_RdMux = row[5] + + DataB_MSB = row[9] + DataB_LSB = row[10] + DataB_REPEAT = row[11] + DataB_RdMux = row[12] + + + primitive_addrW_A = row[16] + primitive_dataW_A = row[17] + primitive_addrW_B = row[18] + primitive_dataW_B = row[19] + + maptable = list() + + if port == 'a': + maptable = create_prmitive_map(data_width, addr_width, primitive_addrW_A, primitive_dataW_A, DataA_MSB, DataA_LSB, DataA_REPEAT, in_data_width_b, DataA_RdMux) + + + elif port == 'b': + maptable = create_prmitive_map(data_width, addr_width, primitive_addrW_B, primitive_dataW_B, DataB_MSB, DataB_LSB, DataB_REPEAT, in_data_width_a, DataB_RdMux) + + + + + stringline = "" + + for Values in maptable: + stringline ="256'h" + for value in Values: + stringline += '%02x' % (value) + + line += '(val_==%2s)?' % (x) + line += stringline + line += ":\n" + x = x + 1 + line += '0;\n' + f.write (line) + + + #stringline ="256'h" + #for hexChar in range(0,32): + # #stringline += '%02x' % (y) + # stringline += '%02x' % (0) + # + # + #for x in range(0, 40): + # #line += '(val_==' + str(x) + ')?' + str(feature) + ':' + # line += '(val_==%2s)?' % (x) + # + # line += stringline + # #line += "256'h0000000000000000000000000000000000000000000000000000000000000000" + # + # line += ":\n" + # x = x + 1 + #line += '0;\n' + #f.write (line) + + + + y = y +1 + + + line = "" + line += " endcase\n" + line += "endfunction \n" + f.write (line) + + + + + f.close() + +if __name__ == "__main__": + + parser = argparse.ArgumentParser(description='Memory Decompose to BRAM') + parser.add_argument("format", choices=['hex', 'bin'], help="Memory file format") + parser.add_argument("init_file", help="Input file name") + parser.add_argument("--port", choices=['a', 'b'], default='b', help="inital data width based on port A(Write) , or port B(Read)") + + + # run parser + args = parser.parse_args() + text_file = open(args.init_file, "r") + + try: + with open('mem_config.txt', 'r') as f: + mem_config = json.loads(f.read()) + FAMILY = mem_config[0] + in_addr_width_a = mem_config[1] + in_data_width_a = mem_config[2] + in_addr_width_b = mem_config[3] + in_data_width_b = mem_config[4] + + actual_size_A = mem_config[5] + actual_size_B = mem_config[6] + byteen_width = mem_config[7] + group_data_width = mem_config[8] + group_columns = mem_config[9] + + bram_decompose_mode = mem_config[10] + bram_feature_table = mem_config[11] + group_columns = mem_config[12] + + bram_decompose_table = mem_config[13] + bram_mapping_table = mem_config[14] + rMux_mapping_table_A = mem_config[15] + wen_sel_mapping_table_A = mem_config[16] + rMux_mapping_table_B = mem_config[17] + wen_sel_mapping_table_B = mem_config[18] + + data_mapping_table_A = mem_config[19] + data_mapping_table_B = mem_config[20] + + address_mapping_table_A = mem_config[21] + address_mapping_table_B = mem_config[22] + + data_width = 0 + addr_width = 0 + + + if args.port == 'a': + data_width = in_data_width_a + addr_width = in_addr_width_a + + elif args.port == 'b': + data_width = in_data_width_b + addr_width = in_addr_width_b + + for y in range(0,2 ** addr_width): + column = list() + for x in range(0,data_width): + column.append(0) + mem_table.append(column) + + + + + #read whole file to a string + InString = text_file.read() + result = "Data width = " + str(data_width) + " Address width = " + str(addr_width) + print (result) + print ("Status : Memory Initialization has completed") + dump2memTable(InString,args.format,args.port, data_width, addr_width) + + #close file + text_file.close() + + + + except OSError as e: + print(f"{type(e)}: {e}") + + + + + + + + + + + \ No newline at end of file diff --git a/hw/efinix_fpga/ip/bram/efx_single_port_ram.v b/hw/efinix_fpga/ip/bram/efx_single_port_ram.v new file mode 100644 index 0000000..2ee878f --- /dev/null +++ b/hw/efinix_fpga/ip/bram/efx_single_port_ram.v @@ -0,0 +1,153 @@ +//////////////////////////////////////////////////////////////////////////// +// _____ +// / _______ Copyright (C) 2013-2022 Efinix Inc. All rights reserved. +// / / \ +// / / .. / efx_single_port_ram.v +// / / .' / +// __/ /.' / Description: +// __ \ / +// /_/ /\ \_____/ / +// ____/ \_______/ +// +// ******************************* +// Revisions: +// 0.0 Initial rev +// +// ******************************* + +module efx_single_port_ram #( + //Trion and Titanium parameters + parameter CLK_POLARITY = 1'b1, //clk polarity, 0:falling edge, 1:rising edge + + parameter WCLKE_POLARITY = 1'b1, //wclke polarity, 0:active low, 1:active high + parameter WE_POLARITY = 1'b1, //we polarity, 0:active low, 1:active high + parameter WRITE_MODE = "READ_UNKNOWN",//write mode, "READ_FIRST" :Old memory content is read. (default) + // "WRITE_FIRST" :Write data is passed to the read port. + // "READ_UNKNOWN": Read and writes are unsynchronized, therefore, the results of the address can conflict. + parameter RE_POLARITY = 1'b1, // re polarity, 0:active low , 1:active high + parameter OUTPUT_REG = 1'b0, // Output register enable, 1:add pipe-line read register + + parameter BYTEEN_POLARITY = 1'b1, //byteen polarity, 0:active low, 1:active high + + //Port Enable + parameter WCLKE_ENABLE = 1'b1, //1: Enable the port for waddren pin , 0: disable + + parameter WE_ENABLE = 1'b1, //1: Enable the port for WE pin , 0: disable + parameter RE_ENABLE = 1'b1, //1: Enable the port for RE pin , 0: disable + parameter BYTEEN_ENABLE = 1'b1, //1: Enable the port for Byteen pins , 0: disable + + //Titanium extra paramters + parameter RST_POLARITY = 1'b1, // rst polarity + parameter RESET_RAM = "ASYNC", // reset mode on ram, "NONE": RST signals does not affect the RAM output. + // "ASYNC": RAM output resets asynchronously to RCLK. + // "SYNC": RAM output resets synchronously to RCLK. + parameter RESET_OUTREG = "ASYNC", // reset mode on output register + // "NONE": RST signals does not affect the RAM output register + // "ASYNC": RAM output register resets asynchronously to RCLK. + parameter ADDREN_POLARITY = 1'b1, // addren polarity + + + //Port Enable + parameter RESET_ENABLE = 1'b1, //1: Enable the port for reset pin , 0: disable + + parameter ADDREN_ENABLE = 1'b1 //1: Enable the port for addren pin , 0: disable + +) +( + //Trion and Titanium ports + clk, // clock input for one clock mode + addr, // address input + + wclke, // Write clock-enable input + byteen, // Byteen input + we, // Write-enable input + wdata, // Write data input + + re, // Read-enable input + rdata, // Read data output + + //Titanium extra ports + reset, // reset + addren, // address enable + ); + +`include "bram_decompose.vh" + +//Trion and Titanium ports +input clk; +input [ADDR_WIDTH_A-1:0] addr; + +input wclke; +input [BYTEEN_WIDTH-1:0] byteen; +input we; +input [DATA_WIDTH_A-1:0] wdata; + +input re; +output [DATA_WIDTH_B-1:0] rdata; + +//Titanium extra ports +input reset; +input addren; + +wire w_wclk; +wire w_rclk; +wire w_wclke; +wire [BYTEEN_WIDTH-1:0] w_byteen; +wire w_we; +wire w_re; +wire w_reset; +wire w_addren; + +assign w_wclke = (WCLKE_ENABLE==1) ? wclke : WCLKE_POLARITY; +assign w_byteen= (BYTEEN_ENABLE==1) ? byteen : {BYTEEN_WIDTH{BYTEEN_POLARITY}}; +assign w_we = (WE_ENABLE==1) ? we : WE_POLARITY; +assign w_re = (RE_ENABLE==1) ? re : RE_POLARITY; + +//Titanium extra ports +assign w_reset = (RESET_ENABLE==1) ? reset : (RST_POLARITY==1'b1) ? 1'b0: 1'b1; +assign w_addren = (ADDREN_ENABLE==1)? addren : ADDREN_POLARITY; + + bram_wrapper_mwm #( + //.FAMILY(FAMILY), + //Trion and Titanium parameters + .WCLK_POLARITY(CLK_POLARITY), + .WCLKE_POLARITY(WCLKE_POLARITY), + .WE_POLARITY(WE_POLARITY), + .WRITE_MODE(WRITE_MODE), + + .RCLK_POLARITY(CLK_POLARITY), + .RE_POLARITY(RE_POLARITY), + .OUTPUT_REG(OUTPUT_REG), + + .BYTEEN_POLARITY(BYTEEN_POLARITY), + + //Titanium extra paramters + .RST_POLARITY(RST_POLARITY), + .RESET_RAM(RESET_RAM), + .RESET_OUTREG(RESET_OUTREG), + .WADDREN_POLARITY(ADDREN_POLARITY), + .RADDREN_POLARITY(ADDREN_POLARITY) + + ) brams ( + .wclk(clk), + .wclke(w_wclke), + .we(w_we), + .byteen(w_byteen), + + .waddr(addr), + .wdata(wdata), + + .rclk(clk), + .re(w_re), + .raddr(addr), + .rdata(rdata), + + + //Titanium extra ports + .reset(w_reset), // reset + .waddren(w_addren), // write address enable + .raddren(w_addren) // read address enable + ); + + +endmodule \ No newline at end of file diff --git a/hw/efinix_fpga/ip/bram/init_bin.mem b/hw/efinix_fpga/ip/bram/init_bin.mem new file mode 100644 index 0000000..f305cf0 --- /dev/null +++ b/hw/efinix_fpga/ip/bram/init_bin.mem @@ -0,0 +1,4096 @@ +0000000000000000 // 0 +0000000000000001 // 1 +0000000000000010 // 2 +0000000000000011 // 3 +0000000000000100 // 4 +0000000000000101 // 5 +0000000000000110 // 6 +0000000000000111 // 7 +0000000000001000 // 8 +0000000000001001 // 9 +0000000000001010 // 10 +0000000000001011 // 11 +0000000000001100 // 12 +0000000000001101 // 13 +0000000000001110 // 14 +0000000000001111 // 15 +0000000000010000 // 16 +0000000000010001 // 17 +0000000000010010 // 18 +0000000000010011 // 19 +0000000000010100 // 20 +0000000000010101 // 21 +0000000000010110 // 22 +0000000000010111 // 23 +0000000000011000 // 24 +0000000000011001 // 25 +0000000000011010 // 26 +0000000000011011 // 27 +0000000000011100 // 28 +0000000000011101 // 29 +0000000000011110 // 30 +0000000000011111 // 31 +0000000000100000 // 32 +0000000000100001 // 33 +0000000000100010 // 34 +0000000000100011 // 35 +0000000000100100 // 36 +0000000000100101 // 37 +0000000000100110 // 38 +0000000000100111 // 39 +0000000000101000 // 40 +0000000000101001 // 41 +0000000000101010 // 42 +0000000000101011 // 43 +0000000000101100 // 44 +0000000000101101 // 45 +0000000000101110 // 46 +0000000000101111 // 47 +0000000000110000 // 48 +0000000000110001 // 49 +0000000000110010 // 50 +0000000000110011 // 51 +0000000000110100 // 52 +0000000000110101 // 53 +0000000000110110 // 54 +0000000000110111 // 55 +0000000000111000 // 56 +0000000000111001 // 57 +0000000000111010 // 58 +0000000000111011 // 59 +0000000000111100 // 60 +0000000000111101 // 61 +0000000000111110 // 62 +0000000000111111 // 63 +0000000001000000 // 64 +0000000001000001 // 65 +0000000001000010 // 66 +0000000001000011 // 67 +0000000001000100 // 68 +0000000001000101 // 69 +0000000001000110 // 70 +0000000001000111 // 71 +0000000001001000 // 72 +0000000001001001 // 73 +0000000001001010 // 74 +0000000001001011 // 75 +0000000001001100 // 76 +0000000001001101 // 77 +0000000001001110 // 78 +0000000001001111 // 79 +0000000001010000 // 80 +0000000001010001 // 81 +0000000001010010 // 82 +0000000001010011 // 83 +0000000001010100 // 84 +0000000001010101 // 85 +0000000001010110 // 86 +0000000001010111 // 87 +0000000001011000 // 88 +0000000001011001 // 89 +0000000001011010 // 90 +0000000001011011 // 91 +0000000001011100 // 92 +0000000001011101 // 93 +0000000001011110 // 94 +0000000001011111 // 95 +0000000001100000 // 96 +0000000001100001 // 97 +0000000001100010 // 98 +0000000001100011 // 99 +0000000001100100 // 100 +0000000001100101 // 101 +0000000001100110 // 102 +0000000001100111 // 103 +0000000001101000 // 104 +0000000001101001 // 105 +0000000001101010 // 106 +0000000001101011 // 107 +0000000001101100 // 108 +0000000001101101 // 109 +0000000001101110 // 110 +0000000001101111 // 111 +0000000001110000 // 112 +0000000001110001 // 113 +0000000001110010 // 114 +0000000001110011 // 115 +0000000001110100 // 116 +0000000001110101 // 117 +0000000001110110 // 118 +0000000001110111 // 119 +0000000001111000 // 120 +0000000001111001 // 121 +0000000001111010 // 122 +0000000001111011 // 123 +0000000001111100 // 124 +0000000001111101 // 125 +0000000001111110 // 126 +0000000001111111 // 127 +0000000010000000 // 128 +0000000010000001 // 129 +0000000010000010 // 130 +0000000010000011 // 131 +0000000010000100 // 132 +0000000010000101 // 133 +0000000010000110 // 134 +0000000010000111 // 135 +0000000010001000 // 136 +0000000010001001 // 137 +0000000010001010 // 138 +0000000010001011 // 139 +0000000010001100 // 140 +0000000010001101 // 141 +0000000010001110 // 142 +0000000010001111 // 143 +0000000010010000 // 144 +0000000010010001 // 145 +0000000010010010 // 146 +0000000010010011 // 147 +0000000010010100 // 148 +0000000010010101 // 149 +0000000010010110 // 150 +0000000010010111 // 151 +0000000010011000 // 152 +0000000010011001 // 153 +0000000010011010 // 154 +0000000010011011 // 155 +0000000010011100 // 156 +0000000010011101 // 157 +0000000010011110 // 158 +0000000010011111 // 159 +0000000010100000 // 160 +0000000010100001 // 161 +0000000010100010 // 162 +0000000010100011 // 163 +0000000010100100 // 164 +0000000010100101 // 165 +0000000010100110 // 166 +0000000010100111 // 167 +0000000010101000 // 168 +0000000010101001 // 169 +0000000010101010 // 170 +0000000010101011 // 171 +0000000010101100 // 172 +0000000010101101 // 173 +0000000010101110 // 174 +0000000010101111 // 175 +0000000010110000 // 176 +0000000010110001 // 177 +0000000010110010 // 178 +0000000010110011 // 179 +0000000010110100 // 180 +0000000010110101 // 181 +0000000010110110 // 182 +0000000010110111 // 183 +0000000010111000 // 184 +0000000010111001 // 185 +0000000010111010 // 186 +0000000010111011 // 187 +0000000010111100 // 188 +0000000010111101 // 189 +0000000010111110 // 190 +0000000010111111 // 191 +0000000011000000 // 192 +0000000011000001 // 193 +0000000011000010 // 194 +0000000011000011 // 195 +0000000011000100 // 196 +0000000011000101 // 197 +0000000011000110 // 198 +0000000011000111 // 199 +0000000011001000 // 200 +0000000011001001 // 201 +0000000011001010 // 202 +0000000011001011 // 203 +0000000011001100 // 204 +0000000011001101 // 205 +0000000011001110 // 206 +0000000011001111 // 207 +0000000011010000 // 208 +0000000011010001 // 209 +0000000011010010 // 210 +0000000011010011 // 211 +0000000011010100 // 212 +0000000011010101 // 213 +0000000011010110 // 214 +0000000011010111 // 215 +0000000011011000 // 216 +0000000011011001 // 217 +0000000011011010 // 218 +0000000011011011 // 219 +0000000011011100 // 220 +0000000011011101 // 221 +0000000011011110 // 222 +0000000011011111 // 223 +0000000011100000 // 224 +0000000011100001 // 225 +0000000011100010 // 226 +0000000011100011 // 227 +0000000011100100 // 228 +0000000011100101 // 229 +0000000011100110 // 230 +0000000011100111 // 231 +0000000011101000 // 232 +0000000011101001 // 233 +0000000011101010 // 234 +0000000011101011 // 235 +0000000011101100 // 236 +0000000011101101 // 237 +0000000011101110 // 238 +0000000011101111 // 239 +0000000011110000 // 240 +0000000011110001 // 241 +0000000011110010 // 242 +0000000011110011 // 243 +0000000011110100 // 244 +0000000011110101 // 245 +0000000011110110 // 246 +0000000011110111 // 247 +0000000011111000 // 248 +0000000011111001 // 249 +0000000011111010 // 250 +0000000011111011 // 251 +0000000011111100 // 252 +0000000011111101 // 253 +0000000011111110 // 254 +0000000011111111 // 255 +0000000100000000 // 256 +0000000100000001 // 257 +0000000100000010 // 258 +0000000100000011 // 259 +0000000100000100 // 260 +0000000100000101 // 261 +0000000100000110 // 262 +0000000100000111 // 263 +0000000100001000 // 264 +0000000100001001 // 265 +0000000100001010 // 266 +0000000100001011 // 267 +0000000100001100 // 268 +0000000100001101 // 269 +0000000100001110 // 270 +0000000100001111 // 271 +0000000100010000 // 272 +0000000100010001 // 273 +0000000100010010 // 274 +0000000100010011 // 275 +0000000100010100 // 276 +0000000100010101 // 277 +0000000100010110 // 278 +0000000100010111 // 279 +0000000100011000 // 280 +0000000100011001 // 281 +0000000100011010 // 282 +0000000100011011 // 283 +0000000100011100 // 284 +0000000100011101 // 285 +0000000100011110 // 286 +0000000100011111 // 287 +0000000100100000 // 288 +0000000100100001 // 289 +0000000100100010 // 290 +0000000100100011 // 291 +0000000100100100 // 292 +0000000100100101 // 293 +0000000100100110 // 294 +0000000100100111 // 295 +0000000100101000 // 296 +0000000100101001 // 297 +0000000100101010 // 298 +0000000100101011 // 299 +0000000100101100 // 300 +0000000100101101 // 301 +0000000100101110 // 302 +0000000100101111 // 303 +0000000100110000 // 304 +0000000100110001 // 305 +0000000100110010 // 306 +0000000100110011 // 307 +0000000100110100 // 308 +0000000100110101 // 309 +0000000100110110 // 310 +0000000100110111 // 311 +0000000100111000 // 312 +0000000100111001 // 313 +0000000100111010 // 314 +0000000100111011 // 315 +0000000100111100 // 316 +0000000100111101 // 317 +0000000100111110 // 318 +0000000100111111 // 319 +0000000101000000 // 320 +0000000101000001 // 321 +0000000101000010 // 322 +0000000101000011 // 323 +0000000101000100 // 324 +0000000101000101 // 325 +0000000101000110 // 326 +0000000101000111 // 327 +0000000101001000 // 328 +0000000101001001 // 329 +0000000101001010 // 330 +0000000101001011 // 331 +0000000101001100 // 332 +0000000101001101 // 333 +0000000101001110 // 334 +0000000101001111 // 335 +0000000101010000 // 336 +0000000101010001 // 337 +0000000101010010 // 338 +0000000101010011 // 339 +0000000101010100 // 340 +0000000101010101 // 341 +0000000101010110 // 342 +0000000101010111 // 343 +0000000101011000 // 344 +0000000101011001 // 345 +0000000101011010 // 346 +0000000101011011 // 347 +0000000101011100 // 348 +0000000101011101 // 349 +0000000101011110 // 350 +0000000101011111 // 351 +0000000101100000 // 352 +0000000101100001 // 353 +0000000101100010 // 354 +0000000101100011 // 355 +0000000101100100 // 356 +0000000101100101 // 357 +0000000101100110 // 358 +0000000101100111 // 359 +0000000101101000 // 360 +0000000101101001 // 361 +0000000101101010 // 362 +0000000101101011 // 363 +0000000101101100 // 364 +0000000101101101 // 365 +0000000101101110 // 366 +0000000101101111 // 367 +0000000101110000 // 368 +0000000101110001 // 369 +0000000101110010 // 370 +0000000101110011 // 371 +0000000101110100 // 372 +0000000101110101 // 373 +0000000101110110 // 374 +0000000101110111 // 375 +0000000101111000 // 376 +0000000101111001 // 377 +0000000101111010 // 378 +0000000101111011 // 379 +0000000101111100 // 380 +0000000101111101 // 381 +0000000101111110 // 382 +0000000101111111 // 383 +0000000110000000 // 384 +0000000110000001 // 385 +0000000110000010 // 386 +0000000110000011 // 387 +0000000110000100 // 388 +0000000110000101 // 389 +0000000110000110 // 390 +0000000110000111 // 391 +0000000110001000 // 392 +0000000110001001 // 393 +0000000110001010 // 394 +0000000110001011 // 395 +0000000110001100 // 396 +0000000110001101 // 397 +0000000110001110 // 398 +0000000110001111 // 399 +0000000110010000 // 400 +0000000110010001 // 401 +0000000110010010 // 402 +0000000110010011 // 403 +0000000110010100 // 404 +0000000110010101 // 405 +0000000110010110 // 406 +0000000110010111 // 407 +0000000110011000 // 408 +0000000110011001 // 409 +0000000110011010 // 410 +0000000110011011 // 411 +0000000110011100 // 412 +0000000110011101 // 413 +0000000110011110 // 414 +0000000110011111 // 415 +0000000110100000 // 416 +0000000110100001 // 417 +0000000110100010 // 418 +0000000110100011 // 419 +0000000110100100 // 420 +0000000110100101 // 421 +0000000110100110 // 422 +0000000110100111 // 423 +0000000110101000 // 424 +0000000110101001 // 425 +0000000110101010 // 426 +0000000110101011 // 427 +0000000110101100 // 428 +0000000110101101 // 429 +0000000110101110 // 430 +0000000110101111 // 431 +0000000110110000 // 432 +0000000110110001 // 433 +0000000110110010 // 434 +0000000110110011 // 435 +0000000110110100 // 436 +0000000110110101 // 437 +0000000110110110 // 438 +0000000110110111 // 439 +0000000110111000 // 440 +0000000110111001 // 441 +0000000110111010 // 442 +0000000110111011 // 443 +0000000110111100 // 444 +0000000110111101 // 445 +0000000110111110 // 446 +0000000110111111 // 447 +0000000111000000 // 448 +0000000111000001 // 449 +0000000111000010 // 450 +0000000111000011 // 451 +0000000111000100 // 452 +0000000111000101 // 453 +0000000111000110 // 454 +0000000111000111 // 455 +0000000111001000 // 456 +0000000111001001 // 457 +0000000111001010 // 458 +0000000111001011 // 459 +0000000111001100 // 460 +0000000111001101 // 461 +0000000111001110 // 462 +0000000111001111 // 463 +0000000111010000 // 464 +0000000111010001 // 465 +0000000111010010 // 466 +0000000111010011 // 467 +0000000111010100 // 468 +0000000111010101 // 469 +0000000111010110 // 470 +0000000111010111 // 471 +0000000111011000 // 472 +0000000111011001 // 473 +0000000111011010 // 474 +0000000111011011 // 475 +0000000111011100 // 476 +0000000111011101 // 477 +0000000111011110 // 478 +0000000111011111 // 479 +0000000111100000 // 480 +0000000111100001 // 481 +0000000111100010 // 482 +0000000111100011 // 483 +0000000111100100 // 484 +0000000111100101 // 485 +0000000111100110 // 486 +0000000111100111 // 487 +0000000111101000 // 488 +0000000111101001 // 489 +0000000111101010 // 490 +0000000111101011 // 491 +0000000111101100 // 492 +0000000111101101 // 493 +0000000111101110 // 494 +0000000111101111 // 495 +0000000111110000 // 496 +0000000111110001 // 497 +0000000111110010 // 498 +0000000111110011 // 499 +0000000111110100 // 500 +0000000111110101 // 501 +0000000111110110 // 502 +0000000111110111 // 503 +0000000111111000 // 504 +0000000111111001 // 505 +0000000111111010 // 506 +0000000111111011 // 507 +0000000111111100 // 508 +0000000111111101 // 509 +0000000111111110 // 510 +0000000111111111 // 511 +0000001000000000 // 512 +0000001000000001 // 513 +0000001000000010 // 514 +0000001000000011 // 515 +0000001000000100 // 516 +0000001000000101 // 517 +0000001000000110 // 518 +0000001000000111 // 519 +0000001000001000 // 520 +0000001000001001 // 521 +0000001000001010 // 522 +0000001000001011 // 523 +0000001000001100 // 524 +0000001000001101 // 525 +0000001000001110 // 526 +0000001000001111 // 527 +0000001000010000 // 528 +0000001000010001 // 529 +0000001000010010 // 530 +0000001000010011 // 531 +0000001000010100 // 532 +0000001000010101 // 533 +0000001000010110 // 534 +0000001000010111 // 535 +0000001000011000 // 536 +0000001000011001 // 537 +0000001000011010 // 538 +0000001000011011 // 539 +0000001000011100 // 540 +0000001000011101 // 541 +0000001000011110 // 542 +0000001000011111 // 543 +0000001000100000 // 544 +0000001000100001 // 545 +0000001000100010 // 546 +0000001000100011 // 547 +0000001000100100 // 548 +0000001000100101 // 549 +0000001000100110 // 550 +0000001000100111 // 551 +0000001000101000 // 552 +0000001000101001 // 553 +0000001000101010 // 554 +0000001000101011 // 555 +0000001000101100 // 556 +0000001000101101 // 557 +0000001000101110 // 558 +0000001000101111 // 559 +0000001000110000 // 560 +0000001000110001 // 561 +0000001000110010 // 562 +0000001000110011 // 563 +0000001000110100 // 564 +0000001000110101 // 565 +0000001000110110 // 566 +0000001000110111 // 567 +0000001000111000 // 568 +0000001000111001 // 569 +0000001000111010 // 570 +0000001000111011 // 571 +0000001000111100 // 572 +0000001000111101 // 573 +0000001000111110 // 574 +0000001000111111 // 575 +0000001001000000 // 576 +0000001001000001 // 577 +0000001001000010 // 578 +0000001001000011 // 579 +0000001001000100 // 580 +0000001001000101 // 581 +0000001001000110 // 582 +0000001001000111 // 583 +0000001001001000 // 584 +0000001001001001 // 585 +0000001001001010 // 586 +0000001001001011 // 587 +0000001001001100 // 588 +0000001001001101 // 589 +0000001001001110 // 590 +0000001001001111 // 591 +0000001001010000 // 592 +0000001001010001 // 593 +0000001001010010 // 594 +0000001001010011 // 595 +0000001001010100 // 596 +0000001001010101 // 597 +0000001001010110 // 598 +0000001001010111 // 599 +0000001001011000 // 600 +0000001001011001 // 601 +0000001001011010 // 602 +0000001001011011 // 603 +0000001001011100 // 604 +0000001001011101 // 605 +0000001001011110 // 606 +0000001001011111 // 607 +0000001001100000 // 608 +0000001001100001 // 609 +0000001001100010 // 610 +0000001001100011 // 611 +0000001001100100 // 612 +0000001001100101 // 613 +0000001001100110 // 614 +0000001001100111 // 615 +0000001001101000 // 616 +0000001001101001 // 617 +0000001001101010 // 618 +0000001001101011 // 619 +0000001001101100 // 620 +0000001001101101 // 621 +0000001001101110 // 622 +0000001001101111 // 623 +0000001001110000 // 624 +0000001001110001 // 625 +0000001001110010 // 626 +0000001001110011 // 627 +0000001001110100 // 628 +0000001001110101 // 629 +0000001001110110 // 630 +0000001001110111 // 631 +0000001001111000 // 632 +0000001001111001 // 633 +0000001001111010 // 634 +0000001001111011 // 635 +0000001001111100 // 636 +0000001001111101 // 637 +0000001001111110 // 638 +0000001001111111 // 639 +0000001010000000 // 640 +0000001010000001 // 641 +0000001010000010 // 642 +0000001010000011 // 643 +0000001010000100 // 644 +0000001010000101 // 645 +0000001010000110 // 646 +0000001010000111 // 647 +0000001010001000 // 648 +0000001010001001 // 649 +0000001010001010 // 650 +0000001010001011 // 651 +0000001010001100 // 652 +0000001010001101 // 653 +0000001010001110 // 654 +0000001010001111 // 655 +0000001010010000 // 656 +0000001010010001 // 657 +0000001010010010 // 658 +0000001010010011 // 659 +0000001010010100 // 660 +0000001010010101 // 661 +0000001010010110 // 662 +0000001010010111 // 663 +0000001010011000 // 664 +0000001010011001 // 665 +0000001010011010 // 666 +0000001010011011 // 667 +0000001010011100 // 668 +0000001010011101 // 669 +0000001010011110 // 670 +0000001010011111 // 671 +0000001010100000 // 672 +0000001010100001 // 673 +0000001010100010 // 674 +0000001010100011 // 675 +0000001010100100 // 676 +0000001010100101 // 677 +0000001010100110 // 678 +0000001010100111 // 679 +0000001010101000 // 680 +0000001010101001 // 681 +0000001010101010 // 682 +0000001010101011 // 683 +0000001010101100 // 684 +0000001010101101 // 685 +0000001010101110 // 686 +0000001010101111 // 687 +0000001010110000 // 688 +0000001010110001 // 689 +0000001010110010 // 690 +0000001010110011 // 691 +0000001010110100 // 692 +0000001010110101 // 693 +0000001010110110 // 694 +0000001010110111 // 695 +0000001010111000 // 696 +0000001010111001 // 697 +0000001010111010 // 698 +0000001010111011 // 699 +0000001010111100 // 700 +0000001010111101 // 701 +0000001010111110 // 702 +0000001010111111 // 703 +0000001011000000 // 704 +0000001011000001 // 705 +0000001011000010 // 706 +0000001011000011 // 707 +0000001011000100 // 708 +0000001011000101 // 709 +0000001011000110 // 710 +0000001011000111 // 711 +0000001011001000 // 712 +0000001011001001 // 713 +0000001011001010 // 714 +0000001011001011 // 715 +0000001011001100 // 716 +0000001011001101 // 717 +0000001011001110 // 718 +0000001011001111 // 719 +0000001011010000 // 720 +0000001011010001 // 721 +0000001011010010 // 722 +0000001011010011 // 723 +0000001011010100 // 724 +0000001011010101 // 725 +0000001011010110 // 726 +0000001011010111 // 727 +0000001011011000 // 728 +0000001011011001 // 729 +0000001011011010 // 730 +0000001011011011 // 731 +0000001011011100 // 732 +0000001011011101 // 733 +0000001011011110 // 734 +0000001011011111 // 735 +0000001011100000 // 736 +0000001011100001 // 737 +0000001011100010 // 738 +0000001011100011 // 739 +0000001011100100 // 740 +0000001011100101 // 741 +0000001011100110 // 742 +0000001011100111 // 743 +0000001011101000 // 744 +0000001011101001 // 745 +0000001011101010 // 746 +0000001011101011 // 747 +0000001011101100 // 748 +0000001011101101 // 749 +0000001011101110 // 750 +0000001011101111 // 751 +0000001011110000 // 752 +0000001011110001 // 753 +0000001011110010 // 754 +0000001011110011 // 755 +0000001011110100 // 756 +0000001011110101 // 757 +0000001011110110 // 758 +0000001011110111 // 759 +0000001011111000 // 760 +0000001011111001 // 761 +0000001011111010 // 762 +0000001011111011 // 763 +0000001011111100 // 764 +0000001011111101 // 765 +0000001011111110 // 766 +0000001011111111 // 767 +0000001100000000 // 768 +0000001100000001 // 769 +0000001100000010 // 770 +0000001100000011 // 771 +0000001100000100 // 772 +0000001100000101 // 773 +0000001100000110 // 774 +0000001100000111 // 775 +0000001100001000 // 776 +0000001100001001 // 777 +0000001100001010 // 778 +0000001100001011 // 779 +0000001100001100 // 780 +0000001100001101 // 781 +0000001100001110 // 782 +0000001100001111 // 783 +0000001100010000 // 784 +0000001100010001 // 785 +0000001100010010 // 786 +0000001100010011 // 787 +0000001100010100 // 788 +0000001100010101 // 789 +0000001100010110 // 790 +0000001100010111 // 791 +0000001100011000 // 792 +0000001100011001 // 793 +0000001100011010 // 794 +0000001100011011 // 795 +0000001100011100 // 796 +0000001100011101 // 797 +0000001100011110 // 798 +0000001100011111 // 799 +0000001100100000 // 800 +0000001100100001 // 801 +0000001100100010 // 802 +0000001100100011 // 803 +0000001100100100 // 804 +0000001100100101 // 805 +0000001100100110 // 806 +0000001100100111 // 807 +0000001100101000 // 808 +0000001100101001 // 809 +0000001100101010 // 810 +0000001100101011 // 811 +0000001100101100 // 812 +0000001100101101 // 813 +0000001100101110 // 814 +0000001100101111 // 815 +0000001100110000 // 816 +0000001100110001 // 817 +0000001100110010 // 818 +0000001100110011 // 819 +0000001100110100 // 820 +0000001100110101 // 821 +0000001100110110 // 822 +0000001100110111 // 823 +0000001100111000 // 824 +0000001100111001 // 825 +0000001100111010 // 826 +0000001100111011 // 827 +0000001100111100 // 828 +0000001100111101 // 829 +0000001100111110 // 830 +0000001100111111 // 831 +0000001101000000 // 832 +0000001101000001 // 833 +0000001101000010 // 834 +0000001101000011 // 835 +0000001101000100 // 836 +0000001101000101 // 837 +0000001101000110 // 838 +0000001101000111 // 839 +0000001101001000 // 840 +0000001101001001 // 841 +0000001101001010 // 842 +0000001101001011 // 843 +0000001101001100 // 844 +0000001101001101 // 845 +0000001101001110 // 846 +0000001101001111 // 847 +0000001101010000 // 848 +0000001101010001 // 849 +0000001101010010 // 850 +0000001101010011 // 851 +0000001101010100 // 852 +0000001101010101 // 853 +0000001101010110 // 854 +0000001101010111 // 855 +0000001101011000 // 856 +0000001101011001 // 857 +0000001101011010 // 858 +0000001101011011 // 859 +0000001101011100 // 860 +0000001101011101 // 861 +0000001101011110 // 862 +0000001101011111 // 863 +0000001101100000 // 864 +0000001101100001 // 865 +0000001101100010 // 866 +0000001101100011 // 867 +0000001101100100 // 868 +0000001101100101 // 869 +0000001101100110 // 870 +0000001101100111 // 871 +0000001101101000 // 872 +0000001101101001 // 873 +0000001101101010 // 874 +0000001101101011 // 875 +0000001101101100 // 876 +0000001101101101 // 877 +0000001101101110 // 878 +0000001101101111 // 879 +0000001101110000 // 880 +0000001101110001 // 881 +0000001101110010 // 882 +0000001101110011 // 883 +0000001101110100 // 884 +0000001101110101 // 885 +0000001101110110 // 886 +0000001101110111 // 887 +0000001101111000 // 888 +0000001101111001 // 889 +0000001101111010 // 890 +0000001101111011 // 891 +0000001101111100 // 892 +0000001101111101 // 893 +0000001101111110 // 894 +0000001101111111 // 895 +0000001110000000 // 896 +0000001110000001 // 897 +0000001110000010 // 898 +0000001110000011 // 899 +0000001110000100 // 900 +0000001110000101 // 901 +0000001110000110 // 902 +0000001110000111 // 903 +0000001110001000 // 904 +0000001110001001 // 905 +0000001110001010 // 906 +0000001110001011 // 907 +0000001110001100 // 908 +0000001110001101 // 909 +0000001110001110 // 910 +0000001110001111 // 911 +0000001110010000 // 912 +0000001110010001 // 913 +0000001110010010 // 914 +0000001110010011 // 915 +0000001110010100 // 916 +0000001110010101 // 917 +0000001110010110 // 918 +0000001110010111 // 919 +0000001110011000 // 920 +0000001110011001 // 921 +0000001110011010 // 922 +0000001110011011 // 923 +0000001110011100 // 924 +0000001110011101 // 925 +0000001110011110 // 926 +0000001110011111 // 927 +0000001110100000 // 928 +0000001110100001 // 929 +0000001110100010 // 930 +0000001110100011 // 931 +0000001110100100 // 932 +0000001110100101 // 933 +0000001110100110 // 934 +0000001110100111 // 935 +0000001110101000 // 936 +0000001110101001 // 937 +0000001110101010 // 938 +0000001110101011 // 939 +0000001110101100 // 940 +0000001110101101 // 941 +0000001110101110 // 942 +0000001110101111 // 943 +0000001110110000 // 944 +0000001110110001 // 945 +0000001110110010 // 946 +0000001110110011 // 947 +0000001110110100 // 948 +0000001110110101 // 949 +0000001110110110 // 950 +0000001110110111 // 951 +0000001110111000 // 952 +0000001110111001 // 953 +0000001110111010 // 954 +0000001110111011 // 955 +0000001110111100 // 956 +0000001110111101 // 957 +0000001110111110 // 958 +0000001110111111 // 959 +0000001111000000 // 960 +0000001111000001 // 961 +0000001111000010 // 962 +0000001111000011 // 963 +0000001111000100 // 964 +0000001111000101 // 965 +0000001111000110 // 966 +0000001111000111 // 967 +0000001111001000 // 968 +0000001111001001 // 969 +0000001111001010 // 970 +0000001111001011 // 971 +0000001111001100 // 972 +0000001111001101 // 973 +0000001111001110 // 974 +0000001111001111 // 975 +0000001111010000 // 976 +0000001111010001 // 977 +0000001111010010 // 978 +0000001111010011 // 979 +0000001111010100 // 980 +0000001111010101 // 981 +0000001111010110 // 982 +0000001111010111 // 983 +0000001111011000 // 984 +0000001111011001 // 985 +0000001111011010 // 986 +0000001111011011 // 987 +0000001111011100 // 988 +0000001111011101 // 989 +0000001111011110 // 990 +0000001111011111 // 991 +0000001111100000 // 992 +0000001111100001 // 993 +0000001111100010 // 994 +0000001111100011 // 995 +0000001111100100 // 996 +0000001111100101 // 997 +0000001111100110 // 998 +0000001111100111 // 999 +0000001111101000 // 1000 +0000001111101001 // 1001 +0000001111101010 // 1002 +0000001111101011 // 1003 +0000001111101100 // 1004 +0000001111101101 // 1005 +0000001111101110 // 1006 +0000001111101111 // 1007 +0000001111110000 // 1008 +0000001111110001 // 1009 +0000001111110010 // 1010 +0000001111110011 // 1011 +0000001111110100 // 1012 +0000001111110101 // 1013 +0000001111110110 // 1014 +0000001111110111 // 1015 +0000001111111000 // 1016 +0000001111111001 // 1017 +0000001111111010 // 1018 +0000001111111011 // 1019 +0000001111111100 // 1020 +0000001111111101 // 1021 +0000001111111110 // 1022 +0000001111111111 // 1023 +0000010000000000 // 1024 +0000010000000001 // 1025 +0000010000000010 // 1026 +0000010000000011 // 1027 +0000010000000100 // 1028 +0000010000000101 // 1029 +0000010000000110 // 1030 +0000010000000111 // 1031 +0000010000001000 // 1032 +0000010000001001 // 1033 +0000010000001010 // 1034 +0000010000001011 // 1035 +0000010000001100 // 1036 +0000010000001101 // 1037 +0000010000001110 // 1038 +0000010000001111 // 1039 +0000010000010000 // 1040 +0000010000010001 // 1041 +0000010000010010 // 1042 +0000010000010011 // 1043 +0000010000010100 // 1044 +0000010000010101 // 1045 +0000010000010110 // 1046 +0000010000010111 // 1047 +0000010000011000 // 1048 +0000010000011001 // 1049 +0000010000011010 // 1050 +0000010000011011 // 1051 +0000010000011100 // 1052 +0000010000011101 // 1053 +0000010000011110 // 1054 +0000010000011111 // 1055 +0000010000100000 // 1056 +0000010000100001 // 1057 +0000010000100010 // 1058 +0000010000100011 // 1059 +0000010000100100 // 1060 +0000010000100101 // 1061 +0000010000100110 // 1062 +0000010000100111 // 1063 +0000010000101000 // 1064 +0000010000101001 // 1065 +0000010000101010 // 1066 +0000010000101011 // 1067 +0000010000101100 // 1068 +0000010000101101 // 1069 +0000010000101110 // 1070 +0000010000101111 // 1071 +0000010000110000 // 1072 +0000010000110001 // 1073 +0000010000110010 // 1074 +0000010000110011 // 1075 +0000010000110100 // 1076 +0000010000110101 // 1077 +0000010000110110 // 1078 +0000010000110111 // 1079 +0000010000111000 // 1080 +0000010000111001 // 1081 +0000010000111010 // 1082 +0000010000111011 // 1083 +0000010000111100 // 1084 +0000010000111101 // 1085 +0000010000111110 // 1086 +0000010000111111 // 1087 +0000010001000000 // 1088 +0000010001000001 // 1089 +0000010001000010 // 1090 +0000010001000011 // 1091 +0000010001000100 // 1092 +0000010001000101 // 1093 +0000010001000110 // 1094 +0000010001000111 // 1095 +0000010001001000 // 1096 +0000010001001001 // 1097 +0000010001001010 // 1098 +0000010001001011 // 1099 +0000010001001100 // 1100 +0000010001001101 // 1101 +0000010001001110 // 1102 +0000010001001111 // 1103 +0000010001010000 // 1104 +0000010001010001 // 1105 +0000010001010010 // 1106 +0000010001010011 // 1107 +0000010001010100 // 1108 +0000010001010101 // 1109 +0000010001010110 // 1110 +0000010001010111 // 1111 +0000010001011000 // 1112 +0000010001011001 // 1113 +0000010001011010 // 1114 +0000010001011011 // 1115 +0000010001011100 // 1116 +0000010001011101 // 1117 +0000010001011110 // 1118 +0000010001011111 // 1119 +0000010001100000 // 1120 +0000010001100001 // 1121 +0000010001100010 // 1122 +0000010001100011 // 1123 +0000010001100100 // 1124 +0000010001100101 // 1125 +0000010001100110 // 1126 +0000010001100111 // 1127 +0000010001101000 // 1128 +0000010001101001 // 1129 +0000010001101010 // 1130 +0000010001101011 // 1131 +0000010001101100 // 1132 +0000010001101101 // 1133 +0000010001101110 // 1134 +0000010001101111 // 1135 +0000010001110000 // 1136 +0000010001110001 // 1137 +0000010001110010 // 1138 +0000010001110011 // 1139 +0000010001110100 // 1140 +0000010001110101 // 1141 +0000010001110110 // 1142 +0000010001110111 // 1143 +0000010001111000 // 1144 +0000010001111001 // 1145 +0000010001111010 // 1146 +0000010001111011 // 1147 +0000010001111100 // 1148 +0000010001111101 // 1149 +0000010001111110 // 1150 +0000010001111111 // 1151 +0000010010000000 // 1152 +0000010010000001 // 1153 +0000010010000010 // 1154 +0000010010000011 // 1155 +0000010010000100 // 1156 +0000010010000101 // 1157 +0000010010000110 // 1158 +0000010010000111 // 1159 +0000010010001000 // 1160 +0000010010001001 // 1161 +0000010010001010 // 1162 +0000010010001011 // 1163 +0000010010001100 // 1164 +0000010010001101 // 1165 +0000010010001110 // 1166 +0000010010001111 // 1167 +0000010010010000 // 1168 +0000010010010001 // 1169 +0000010010010010 // 1170 +0000010010010011 // 1171 +0000010010010100 // 1172 +0000010010010101 // 1173 +0000010010010110 // 1174 +0000010010010111 // 1175 +0000010010011000 // 1176 +0000010010011001 // 1177 +0000010010011010 // 1178 +0000010010011011 // 1179 +0000010010011100 // 1180 +0000010010011101 // 1181 +0000010010011110 // 1182 +0000010010011111 // 1183 +0000010010100000 // 1184 +0000010010100001 // 1185 +0000010010100010 // 1186 +0000010010100011 // 1187 +0000010010100100 // 1188 +0000010010100101 // 1189 +0000010010100110 // 1190 +0000010010100111 // 1191 +0000010010101000 // 1192 +0000010010101001 // 1193 +0000010010101010 // 1194 +0000010010101011 // 1195 +0000010010101100 // 1196 +0000010010101101 // 1197 +0000010010101110 // 1198 +0000010010101111 // 1199 +0000010010110000 // 1200 +0000010010110001 // 1201 +0000010010110010 // 1202 +0000010010110011 // 1203 +0000010010110100 // 1204 +0000010010110101 // 1205 +0000010010110110 // 1206 +0000010010110111 // 1207 +0000010010111000 // 1208 +0000010010111001 // 1209 +0000010010111010 // 1210 +0000010010111011 // 1211 +0000010010111100 // 1212 +0000010010111101 // 1213 +0000010010111110 // 1214 +0000010010111111 // 1215 +0000010011000000 // 1216 +0000010011000001 // 1217 +0000010011000010 // 1218 +0000010011000011 // 1219 +0000010011000100 // 1220 +0000010011000101 // 1221 +0000010011000110 // 1222 +0000010011000111 // 1223 +0000010011001000 // 1224 +0000010011001001 // 1225 +0000010011001010 // 1226 +0000010011001011 // 1227 +0000010011001100 // 1228 +0000010011001101 // 1229 +0000010011001110 // 1230 +0000010011001111 // 1231 +0000010011010000 // 1232 +0000010011010001 // 1233 +0000010011010010 // 1234 +0000010011010011 // 1235 +0000010011010100 // 1236 +0000010011010101 // 1237 +0000010011010110 // 1238 +0000010011010111 // 1239 +0000010011011000 // 1240 +0000010011011001 // 1241 +0000010011011010 // 1242 +0000010011011011 // 1243 +0000010011011100 // 1244 +0000010011011101 // 1245 +0000010011011110 // 1246 +0000010011011111 // 1247 +0000010011100000 // 1248 +0000010011100001 // 1249 +0000010011100010 // 1250 +0000010011100011 // 1251 +0000010011100100 // 1252 +0000010011100101 // 1253 +0000010011100110 // 1254 +0000010011100111 // 1255 +0000010011101000 // 1256 +0000010011101001 // 1257 +0000010011101010 // 1258 +0000010011101011 // 1259 +0000010011101100 // 1260 +0000010011101101 // 1261 +0000010011101110 // 1262 +0000010011101111 // 1263 +0000010011110000 // 1264 +0000010011110001 // 1265 +0000010011110010 // 1266 +0000010011110011 // 1267 +0000010011110100 // 1268 +0000010011110101 // 1269 +0000010011110110 // 1270 +0000010011110111 // 1271 +0000010011111000 // 1272 +0000010011111001 // 1273 +0000010011111010 // 1274 +0000010011111011 // 1275 +0000010011111100 // 1276 +0000010011111101 // 1277 +0000010011111110 // 1278 +0000010011111111 // 1279 +0000010100000000 // 1280 +0000010100000001 // 1281 +0000010100000010 // 1282 +0000010100000011 // 1283 +0000010100000100 // 1284 +0000010100000101 // 1285 +0000010100000110 // 1286 +0000010100000111 // 1287 +0000010100001000 // 1288 +0000010100001001 // 1289 +0000010100001010 // 1290 +0000010100001011 // 1291 +0000010100001100 // 1292 +0000010100001101 // 1293 +0000010100001110 // 1294 +0000010100001111 // 1295 +0000010100010000 // 1296 +0000010100010001 // 1297 +0000010100010010 // 1298 +0000010100010011 // 1299 +0000010100010100 // 1300 +0000010100010101 // 1301 +0000010100010110 // 1302 +0000010100010111 // 1303 +0000010100011000 // 1304 +0000010100011001 // 1305 +0000010100011010 // 1306 +0000010100011011 // 1307 +0000010100011100 // 1308 +0000010100011101 // 1309 +0000010100011110 // 1310 +0000010100011111 // 1311 +0000010100100000 // 1312 +0000010100100001 // 1313 +0000010100100010 // 1314 +0000010100100011 // 1315 +0000010100100100 // 1316 +0000010100100101 // 1317 +0000010100100110 // 1318 +0000010100100111 // 1319 +0000010100101000 // 1320 +0000010100101001 // 1321 +0000010100101010 // 1322 +0000010100101011 // 1323 +0000010100101100 // 1324 +0000010100101101 // 1325 +0000010100101110 // 1326 +0000010100101111 // 1327 +0000010100110000 // 1328 +0000010100110001 // 1329 +0000010100110010 // 1330 +0000010100110011 // 1331 +0000010100110100 // 1332 +0000010100110101 // 1333 +0000010100110110 // 1334 +0000010100110111 // 1335 +0000010100111000 // 1336 +0000010100111001 // 1337 +0000010100111010 // 1338 +0000010100111011 // 1339 +0000010100111100 // 1340 +0000010100111101 // 1341 +0000010100111110 // 1342 +0000010100111111 // 1343 +0000010101000000 // 1344 +0000010101000001 // 1345 +0000010101000010 // 1346 +0000010101000011 // 1347 +0000010101000100 // 1348 +0000010101000101 // 1349 +0000010101000110 // 1350 +0000010101000111 // 1351 +0000010101001000 // 1352 +0000010101001001 // 1353 +0000010101001010 // 1354 +0000010101001011 // 1355 +0000010101001100 // 1356 +0000010101001101 // 1357 +0000010101001110 // 1358 +0000010101001111 // 1359 +0000010101010000 // 1360 +0000010101010001 // 1361 +0000010101010010 // 1362 +0000010101010011 // 1363 +0000010101010100 // 1364 +0000010101010101 // 1365 +0000010101010110 // 1366 +0000010101010111 // 1367 +0000010101011000 // 1368 +0000010101011001 // 1369 +0000010101011010 // 1370 +0000010101011011 // 1371 +0000010101011100 // 1372 +0000010101011101 // 1373 +0000010101011110 // 1374 +0000010101011111 // 1375 +0000010101100000 // 1376 +0000010101100001 // 1377 +0000010101100010 // 1378 +0000010101100011 // 1379 +0000010101100100 // 1380 +0000010101100101 // 1381 +0000010101100110 // 1382 +0000010101100111 // 1383 +0000010101101000 // 1384 +0000010101101001 // 1385 +0000010101101010 // 1386 +0000010101101011 // 1387 +0000010101101100 // 1388 +0000010101101101 // 1389 +0000010101101110 // 1390 +0000010101101111 // 1391 +0000010101110000 // 1392 +0000010101110001 // 1393 +0000010101110010 // 1394 +0000010101110011 // 1395 +0000010101110100 // 1396 +0000010101110101 // 1397 +0000010101110110 // 1398 +0000010101110111 // 1399 +0000010101111000 // 1400 +0000010101111001 // 1401 +0000010101111010 // 1402 +0000010101111011 // 1403 +0000010101111100 // 1404 +0000010101111101 // 1405 +0000010101111110 // 1406 +0000010101111111 // 1407 +0000010110000000 // 1408 +0000010110000001 // 1409 +0000010110000010 // 1410 +0000010110000011 // 1411 +0000010110000100 // 1412 +0000010110000101 // 1413 +0000010110000110 // 1414 +0000010110000111 // 1415 +0000010110001000 // 1416 +0000010110001001 // 1417 +0000010110001010 // 1418 +0000010110001011 // 1419 +0000010110001100 // 1420 +0000010110001101 // 1421 +0000010110001110 // 1422 +0000010110001111 // 1423 +0000010110010000 // 1424 +0000010110010001 // 1425 +0000010110010010 // 1426 +0000010110010011 // 1427 +0000010110010100 // 1428 +0000010110010101 // 1429 +0000010110010110 // 1430 +0000010110010111 // 1431 +0000010110011000 // 1432 +0000010110011001 // 1433 +0000010110011010 // 1434 +0000010110011011 // 1435 +0000010110011100 // 1436 +0000010110011101 // 1437 +0000010110011110 // 1438 +0000010110011111 // 1439 +0000010110100000 // 1440 +0000010110100001 // 1441 +0000010110100010 // 1442 +0000010110100011 // 1443 +0000010110100100 // 1444 +0000010110100101 // 1445 +0000010110100110 // 1446 +0000010110100111 // 1447 +0000010110101000 // 1448 +0000010110101001 // 1449 +0000010110101010 // 1450 +0000010110101011 // 1451 +0000010110101100 // 1452 +0000010110101101 // 1453 +0000010110101110 // 1454 +0000010110101111 // 1455 +0000010110110000 // 1456 +0000010110110001 // 1457 +0000010110110010 // 1458 +0000010110110011 // 1459 +0000010110110100 // 1460 +0000010110110101 // 1461 +0000010110110110 // 1462 +0000010110110111 // 1463 +0000010110111000 // 1464 +0000010110111001 // 1465 +0000010110111010 // 1466 +0000010110111011 // 1467 +0000010110111100 // 1468 +0000010110111101 // 1469 +0000010110111110 // 1470 +0000010110111111 // 1471 +0000010111000000 // 1472 +0000010111000001 // 1473 +0000010111000010 // 1474 +0000010111000011 // 1475 +0000010111000100 // 1476 +0000010111000101 // 1477 +0000010111000110 // 1478 +0000010111000111 // 1479 +0000010111001000 // 1480 +0000010111001001 // 1481 +0000010111001010 // 1482 +0000010111001011 // 1483 +0000010111001100 // 1484 +0000010111001101 // 1485 +0000010111001110 // 1486 +0000010111001111 // 1487 +0000010111010000 // 1488 +0000010111010001 // 1489 +0000010111010010 // 1490 +0000010111010011 // 1491 +0000010111010100 // 1492 +0000010111010101 // 1493 +0000010111010110 // 1494 +0000010111010111 // 1495 +0000010111011000 // 1496 +0000010111011001 // 1497 +0000010111011010 // 1498 +0000010111011011 // 1499 +0000010111011100 // 1500 +0000010111011101 // 1501 +0000010111011110 // 1502 +0000010111011111 // 1503 +0000010111100000 // 1504 +0000010111100001 // 1505 +0000010111100010 // 1506 +0000010111100011 // 1507 +0000010111100100 // 1508 +0000010111100101 // 1509 +0000010111100110 // 1510 +0000010111100111 // 1511 +0000010111101000 // 1512 +0000010111101001 // 1513 +0000010111101010 // 1514 +0000010111101011 // 1515 +0000010111101100 // 1516 +0000010111101101 // 1517 +0000010111101110 // 1518 +0000010111101111 // 1519 +0000010111110000 // 1520 +0000010111110001 // 1521 +0000010111110010 // 1522 +0000010111110011 // 1523 +0000010111110100 // 1524 +0000010111110101 // 1525 +0000010111110110 // 1526 +0000010111110111 // 1527 +0000010111111000 // 1528 +0000010111111001 // 1529 +0000010111111010 // 1530 +0000010111111011 // 1531 +0000010111111100 // 1532 +0000010111111101 // 1533 +0000010111111110 // 1534 +0000010111111111 // 1535 +0000011000000000 // 1536 +0000011000000001 // 1537 +0000011000000010 // 1538 +0000011000000011 // 1539 +0000011000000100 // 1540 +0000011000000101 // 1541 +0000011000000110 // 1542 +0000011000000111 // 1543 +0000011000001000 // 1544 +0000011000001001 // 1545 +0000011000001010 // 1546 +0000011000001011 // 1547 +0000011000001100 // 1548 +0000011000001101 // 1549 +0000011000001110 // 1550 +0000011000001111 // 1551 +0000011000010000 // 1552 +0000011000010001 // 1553 +0000011000010010 // 1554 +0000011000010011 // 1555 +0000011000010100 // 1556 +0000011000010101 // 1557 +0000011000010110 // 1558 +0000011000010111 // 1559 +0000011000011000 // 1560 +0000011000011001 // 1561 +0000011000011010 // 1562 +0000011000011011 // 1563 +0000011000011100 // 1564 +0000011000011101 // 1565 +0000011000011110 // 1566 +0000011000011111 // 1567 +0000011000100000 // 1568 +0000011000100001 // 1569 +0000011000100010 // 1570 +0000011000100011 // 1571 +0000011000100100 // 1572 +0000011000100101 // 1573 +0000011000100110 // 1574 +0000011000100111 // 1575 +0000011000101000 // 1576 +0000011000101001 // 1577 +0000011000101010 // 1578 +0000011000101011 // 1579 +0000011000101100 // 1580 +0000011000101101 // 1581 +0000011000101110 // 1582 +0000011000101111 // 1583 +0000011000110000 // 1584 +0000011000110001 // 1585 +0000011000110010 // 1586 +0000011000110011 // 1587 +0000011000110100 // 1588 +0000011000110101 // 1589 +0000011000110110 // 1590 +0000011000110111 // 1591 +0000011000111000 // 1592 +0000011000111001 // 1593 +0000011000111010 // 1594 +0000011000111011 // 1595 +0000011000111100 // 1596 +0000011000111101 // 1597 +0000011000111110 // 1598 +0000011000111111 // 1599 +0000011001000000 // 1600 +0000011001000001 // 1601 +0000011001000010 // 1602 +0000011001000011 // 1603 +0000011001000100 // 1604 +0000011001000101 // 1605 +0000011001000110 // 1606 +0000011001000111 // 1607 +0000011001001000 // 1608 +0000011001001001 // 1609 +0000011001001010 // 1610 +0000011001001011 // 1611 +0000011001001100 // 1612 +0000011001001101 // 1613 +0000011001001110 // 1614 +0000011001001111 // 1615 +0000011001010000 // 1616 +0000011001010001 // 1617 +0000011001010010 // 1618 +0000011001010011 // 1619 +0000011001010100 // 1620 +0000011001010101 // 1621 +0000011001010110 // 1622 +0000011001010111 // 1623 +0000011001011000 // 1624 +0000011001011001 // 1625 +0000011001011010 // 1626 +0000011001011011 // 1627 +0000011001011100 // 1628 +0000011001011101 // 1629 +0000011001011110 // 1630 +0000011001011111 // 1631 +0000011001100000 // 1632 +0000011001100001 // 1633 +0000011001100010 // 1634 +0000011001100011 // 1635 +0000011001100100 // 1636 +0000011001100101 // 1637 +0000011001100110 // 1638 +0000011001100111 // 1639 +0000011001101000 // 1640 +0000011001101001 // 1641 +0000011001101010 // 1642 +0000011001101011 // 1643 +0000011001101100 // 1644 +0000011001101101 // 1645 +0000011001101110 // 1646 +0000011001101111 // 1647 +0000011001110000 // 1648 +0000011001110001 // 1649 +0000011001110010 // 1650 +0000011001110011 // 1651 +0000011001110100 // 1652 +0000011001110101 // 1653 +0000011001110110 // 1654 +0000011001110111 // 1655 +0000011001111000 // 1656 +0000011001111001 // 1657 +0000011001111010 // 1658 +0000011001111011 // 1659 +0000011001111100 // 1660 +0000011001111101 // 1661 +0000011001111110 // 1662 +0000011001111111 // 1663 +0000011010000000 // 1664 +0000011010000001 // 1665 +0000011010000010 // 1666 +0000011010000011 // 1667 +0000011010000100 // 1668 +0000011010000101 // 1669 +0000011010000110 // 1670 +0000011010000111 // 1671 +0000011010001000 // 1672 +0000011010001001 // 1673 +0000011010001010 // 1674 +0000011010001011 // 1675 +0000011010001100 // 1676 +0000011010001101 // 1677 +0000011010001110 // 1678 +0000011010001111 // 1679 +0000011010010000 // 1680 +0000011010010001 // 1681 +0000011010010010 // 1682 +0000011010010011 // 1683 +0000011010010100 // 1684 +0000011010010101 // 1685 +0000011010010110 // 1686 +0000011010010111 // 1687 +0000011010011000 // 1688 +0000011010011001 // 1689 +0000011010011010 // 1690 +0000011010011011 // 1691 +0000011010011100 // 1692 +0000011010011101 // 1693 +0000011010011110 // 1694 +0000011010011111 // 1695 +0000011010100000 // 1696 +0000011010100001 // 1697 +0000011010100010 // 1698 +0000011010100011 // 1699 +0000011010100100 // 1700 +0000011010100101 // 1701 +0000011010100110 // 1702 +0000011010100111 // 1703 +0000011010101000 // 1704 +0000011010101001 // 1705 +0000011010101010 // 1706 +0000011010101011 // 1707 +0000011010101100 // 1708 +0000011010101101 // 1709 +0000011010101110 // 1710 +0000011010101111 // 1711 +0000011010110000 // 1712 +0000011010110001 // 1713 +0000011010110010 // 1714 +0000011010110011 // 1715 +0000011010110100 // 1716 +0000011010110101 // 1717 +0000011010110110 // 1718 +0000011010110111 // 1719 +0000011010111000 // 1720 +0000011010111001 // 1721 +0000011010111010 // 1722 +0000011010111011 // 1723 +0000011010111100 // 1724 +0000011010111101 // 1725 +0000011010111110 // 1726 +0000011010111111 // 1727 +0000011011000000 // 1728 +0000011011000001 // 1729 +0000011011000010 // 1730 +0000011011000011 // 1731 +0000011011000100 // 1732 +0000011011000101 // 1733 +0000011011000110 // 1734 +0000011011000111 // 1735 +0000011011001000 // 1736 +0000011011001001 // 1737 +0000011011001010 // 1738 +0000011011001011 // 1739 +0000011011001100 // 1740 +0000011011001101 // 1741 +0000011011001110 // 1742 +0000011011001111 // 1743 +0000011011010000 // 1744 +0000011011010001 // 1745 +0000011011010010 // 1746 +0000011011010011 // 1747 +0000011011010100 // 1748 +0000011011010101 // 1749 +0000011011010110 // 1750 +0000011011010111 // 1751 +0000011011011000 // 1752 +0000011011011001 // 1753 +0000011011011010 // 1754 +0000011011011011 // 1755 +0000011011011100 // 1756 +0000011011011101 // 1757 +0000011011011110 // 1758 +0000011011011111 // 1759 +0000011011100000 // 1760 +0000011011100001 // 1761 +0000011011100010 // 1762 +0000011011100011 // 1763 +0000011011100100 // 1764 +0000011011100101 // 1765 +0000011011100110 // 1766 +0000011011100111 // 1767 +0000011011101000 // 1768 +0000011011101001 // 1769 +0000011011101010 // 1770 +0000011011101011 // 1771 +0000011011101100 // 1772 +0000011011101101 // 1773 +0000011011101110 // 1774 +0000011011101111 // 1775 +0000011011110000 // 1776 +0000011011110001 // 1777 +0000011011110010 // 1778 +0000011011110011 // 1779 +0000011011110100 // 1780 +0000011011110101 // 1781 +0000011011110110 // 1782 +0000011011110111 // 1783 +0000011011111000 // 1784 +0000011011111001 // 1785 +0000011011111010 // 1786 +0000011011111011 // 1787 +0000011011111100 // 1788 +0000011011111101 // 1789 +0000011011111110 // 1790 +0000011011111111 // 1791 +0000011100000000 // 1792 +0000011100000001 // 1793 +0000011100000010 // 1794 +0000011100000011 // 1795 +0000011100000100 // 1796 +0000011100000101 // 1797 +0000011100000110 // 1798 +0000011100000111 // 1799 +0000011100001000 // 1800 +0000011100001001 // 1801 +0000011100001010 // 1802 +0000011100001011 // 1803 +0000011100001100 // 1804 +0000011100001101 // 1805 +0000011100001110 // 1806 +0000011100001111 // 1807 +0000011100010000 // 1808 +0000011100010001 // 1809 +0000011100010010 // 1810 +0000011100010011 // 1811 +0000011100010100 // 1812 +0000011100010101 // 1813 +0000011100010110 // 1814 +0000011100010111 // 1815 +0000011100011000 // 1816 +0000011100011001 // 1817 +0000011100011010 // 1818 +0000011100011011 // 1819 +0000011100011100 // 1820 +0000011100011101 // 1821 +0000011100011110 // 1822 +0000011100011111 // 1823 +0000011100100000 // 1824 +0000011100100001 // 1825 +0000011100100010 // 1826 +0000011100100011 // 1827 +0000011100100100 // 1828 +0000011100100101 // 1829 +0000011100100110 // 1830 +0000011100100111 // 1831 +0000011100101000 // 1832 +0000011100101001 // 1833 +0000011100101010 // 1834 +0000011100101011 // 1835 +0000011100101100 // 1836 +0000011100101101 // 1837 +0000011100101110 // 1838 +0000011100101111 // 1839 +0000011100110000 // 1840 +0000011100110001 // 1841 +0000011100110010 // 1842 +0000011100110011 // 1843 +0000011100110100 // 1844 +0000011100110101 // 1845 +0000011100110110 // 1846 +0000011100110111 // 1847 +0000011100111000 // 1848 +0000011100111001 // 1849 +0000011100111010 // 1850 +0000011100111011 // 1851 +0000011100111100 // 1852 +0000011100111101 // 1853 +0000011100111110 // 1854 +0000011100111111 // 1855 +0000011101000000 // 1856 +0000011101000001 // 1857 +0000011101000010 // 1858 +0000011101000011 // 1859 +0000011101000100 // 1860 +0000011101000101 // 1861 +0000011101000110 // 1862 +0000011101000111 // 1863 +0000011101001000 // 1864 +0000011101001001 // 1865 +0000011101001010 // 1866 +0000011101001011 // 1867 +0000011101001100 // 1868 +0000011101001101 // 1869 +0000011101001110 // 1870 +0000011101001111 // 1871 +0000011101010000 // 1872 +0000011101010001 // 1873 +0000011101010010 // 1874 +0000011101010011 // 1875 +0000011101010100 // 1876 +0000011101010101 // 1877 +0000011101010110 // 1878 +0000011101010111 // 1879 +0000011101011000 // 1880 +0000011101011001 // 1881 +0000011101011010 // 1882 +0000011101011011 // 1883 +0000011101011100 // 1884 +0000011101011101 // 1885 +0000011101011110 // 1886 +0000011101011111 // 1887 +0000011101100000 // 1888 +0000011101100001 // 1889 +0000011101100010 // 1890 +0000011101100011 // 1891 +0000011101100100 // 1892 +0000011101100101 // 1893 +0000011101100110 // 1894 +0000011101100111 // 1895 +0000011101101000 // 1896 +0000011101101001 // 1897 +0000011101101010 // 1898 +0000011101101011 // 1899 +0000011101101100 // 1900 +0000011101101101 // 1901 +0000011101101110 // 1902 +0000011101101111 // 1903 +0000011101110000 // 1904 +0000011101110001 // 1905 +0000011101110010 // 1906 +0000011101110011 // 1907 +0000011101110100 // 1908 +0000011101110101 // 1909 +0000011101110110 // 1910 +0000011101110111 // 1911 +0000011101111000 // 1912 +0000011101111001 // 1913 +0000011101111010 // 1914 +0000011101111011 // 1915 +0000011101111100 // 1916 +0000011101111101 // 1917 +0000011101111110 // 1918 +0000011101111111 // 1919 +0000011110000000 // 1920 +0000011110000001 // 1921 +0000011110000010 // 1922 +0000011110000011 // 1923 +0000011110000100 // 1924 +0000011110000101 // 1925 +0000011110000110 // 1926 +0000011110000111 // 1927 +0000011110001000 // 1928 +0000011110001001 // 1929 +0000011110001010 // 1930 +0000011110001011 // 1931 +0000011110001100 // 1932 +0000011110001101 // 1933 +0000011110001110 // 1934 +0000011110001111 // 1935 +0000011110010000 // 1936 +0000011110010001 // 1937 +0000011110010010 // 1938 +0000011110010011 // 1939 +0000011110010100 // 1940 +0000011110010101 // 1941 +0000011110010110 // 1942 +0000011110010111 // 1943 +0000011110011000 // 1944 +0000011110011001 // 1945 +0000011110011010 // 1946 +0000011110011011 // 1947 +0000011110011100 // 1948 +0000011110011101 // 1949 +0000011110011110 // 1950 +0000011110011111 // 1951 +0000011110100000 // 1952 +0000011110100001 // 1953 +0000011110100010 // 1954 +0000011110100011 // 1955 +0000011110100100 // 1956 +0000011110100101 // 1957 +0000011110100110 // 1958 +0000011110100111 // 1959 +0000011110101000 // 1960 +0000011110101001 // 1961 +0000011110101010 // 1962 +0000011110101011 // 1963 +0000011110101100 // 1964 +0000011110101101 // 1965 +0000011110101110 // 1966 +0000011110101111 // 1967 +0000011110110000 // 1968 +0000011110110001 // 1969 +0000011110110010 // 1970 +0000011110110011 // 1971 +0000011110110100 // 1972 +0000011110110101 // 1973 +0000011110110110 // 1974 +0000011110110111 // 1975 +0000011110111000 // 1976 +0000011110111001 // 1977 +0000011110111010 // 1978 +0000011110111011 // 1979 +0000011110111100 // 1980 +0000011110111101 // 1981 +0000011110111110 // 1982 +0000011110111111 // 1983 +0000011111000000 // 1984 +0000011111000001 // 1985 +0000011111000010 // 1986 +0000011111000011 // 1987 +0000011111000100 // 1988 +0000011111000101 // 1989 +0000011111000110 // 1990 +0000011111000111 // 1991 +0000011111001000 // 1992 +0000011111001001 // 1993 +0000011111001010 // 1994 +0000011111001011 // 1995 +0000011111001100 // 1996 +0000011111001101 // 1997 +0000011111001110 // 1998 +0000011111001111 // 1999 +0000011111010000 // 2000 +0000011111010001 // 2001 +0000011111010010 // 2002 +0000011111010011 // 2003 +0000011111010100 // 2004 +0000011111010101 // 2005 +0000011111010110 // 2006 +0000011111010111 // 2007 +0000011111011000 // 2008 +0000011111011001 // 2009 +0000011111011010 // 2010 +0000011111011011 // 2011 +0000011111011100 // 2012 +0000011111011101 // 2013 +0000011111011110 // 2014 +0000011111011111 // 2015 +0000011111100000 // 2016 +0000011111100001 // 2017 +0000011111100010 // 2018 +0000011111100011 // 2019 +0000011111100100 // 2020 +0000011111100101 // 2021 +0000011111100110 // 2022 +0000011111100111 // 2023 +0000011111101000 // 2024 +0000011111101001 // 2025 +0000011111101010 // 2026 +0000011111101011 // 2027 +0000011111101100 // 2028 +0000011111101101 // 2029 +0000011111101110 // 2030 +0000011111101111 // 2031 +0000011111110000 // 2032 +0000011111110001 // 2033 +0000011111110010 // 2034 +0000011111110011 // 2035 +0000011111110100 // 2036 +0000011111110101 // 2037 +0000011111110110 // 2038 +0000011111110111 // 2039 +0000011111111000 // 2040 +0000011111111001 // 2041 +0000011111111010 // 2042 +0000011111111011 // 2043 +0000011111111100 // 2044 +0000011111111101 // 2045 +0000011111111110 // 2046 +0000011111111111 // 2047 +0000100000000000 // 2048 +0000100000000001 // 2049 +0000100000000010 // 2050 +0000100000000011 // 2051 +0000100000000100 // 2052 +0000100000000101 // 2053 +0000100000000110 // 2054 +0000100000000111 // 2055 +0000100000001000 // 2056 +0000100000001001 // 2057 +0000100000001010 // 2058 +0000100000001011 // 2059 +0000100000001100 // 2060 +0000100000001101 // 2061 +0000100000001110 // 2062 +0000100000001111 // 2063 +0000100000010000 // 2064 +0000100000010001 // 2065 +0000100000010010 // 2066 +0000100000010011 // 2067 +0000100000010100 // 2068 +0000100000010101 // 2069 +0000100000010110 // 2070 +0000100000010111 // 2071 +0000100000011000 // 2072 +0000100000011001 // 2073 +0000100000011010 // 2074 +0000100000011011 // 2075 +0000100000011100 // 2076 +0000100000011101 // 2077 +0000100000011110 // 2078 +0000100000011111 // 2079 +0000100000100000 // 2080 +0000100000100001 // 2081 +0000100000100010 // 2082 +0000100000100011 // 2083 +0000100000100100 // 2084 +0000100000100101 // 2085 +0000100000100110 // 2086 +0000100000100111 // 2087 +0000100000101000 // 2088 +0000100000101001 // 2089 +0000100000101010 // 2090 +0000100000101011 // 2091 +0000100000101100 // 2092 +0000100000101101 // 2093 +0000100000101110 // 2094 +0000100000101111 // 2095 +0000100000110000 // 2096 +0000100000110001 // 2097 +0000100000110010 // 2098 +0000100000110011 // 2099 +0000100000110100 // 2100 +0000100000110101 // 2101 +0000100000110110 // 2102 +0000100000110111 // 2103 +0000100000111000 // 2104 +0000100000111001 // 2105 +0000100000111010 // 2106 +0000100000111011 // 2107 +0000100000111100 // 2108 +0000100000111101 // 2109 +0000100000111110 // 2110 +0000100000111111 // 2111 +0000100001000000 // 2112 +0000100001000001 // 2113 +0000100001000010 // 2114 +0000100001000011 // 2115 +0000100001000100 // 2116 +0000100001000101 // 2117 +0000100001000110 // 2118 +0000100001000111 // 2119 +0000100001001000 // 2120 +0000100001001001 // 2121 +0000100001001010 // 2122 +0000100001001011 // 2123 +0000100001001100 // 2124 +0000100001001101 // 2125 +0000100001001110 // 2126 +0000100001001111 // 2127 +0000100001010000 // 2128 +0000100001010001 // 2129 +0000100001010010 // 2130 +0000100001010011 // 2131 +0000100001010100 // 2132 +0000100001010101 // 2133 +0000100001010110 // 2134 +0000100001010111 // 2135 +0000100001011000 // 2136 +0000100001011001 // 2137 +0000100001011010 // 2138 +0000100001011011 // 2139 +0000100001011100 // 2140 +0000100001011101 // 2141 +0000100001011110 // 2142 +0000100001011111 // 2143 +0000100001100000 // 2144 +0000100001100001 // 2145 +0000100001100010 // 2146 +0000100001100011 // 2147 +0000100001100100 // 2148 +0000100001100101 // 2149 +0000100001100110 // 2150 +0000100001100111 // 2151 +0000100001101000 // 2152 +0000100001101001 // 2153 +0000100001101010 // 2154 +0000100001101011 // 2155 +0000100001101100 // 2156 +0000100001101101 // 2157 +0000100001101110 // 2158 +0000100001101111 // 2159 +0000100001110000 // 2160 +0000100001110001 // 2161 +0000100001110010 // 2162 +0000100001110011 // 2163 +0000100001110100 // 2164 +0000100001110101 // 2165 +0000100001110110 // 2166 +0000100001110111 // 2167 +0000100001111000 // 2168 +0000100001111001 // 2169 +0000100001111010 // 2170 +0000100001111011 // 2171 +0000100001111100 // 2172 +0000100001111101 // 2173 +0000100001111110 // 2174 +0000100001111111 // 2175 +0000100010000000 // 2176 +0000100010000001 // 2177 +0000100010000010 // 2178 +0000100010000011 // 2179 +0000100010000100 // 2180 +0000100010000101 // 2181 +0000100010000110 // 2182 +0000100010000111 // 2183 +0000100010001000 // 2184 +0000100010001001 // 2185 +0000100010001010 // 2186 +0000100010001011 // 2187 +0000100010001100 // 2188 +0000100010001101 // 2189 +0000100010001110 // 2190 +0000100010001111 // 2191 +0000100010010000 // 2192 +0000100010010001 // 2193 +0000100010010010 // 2194 +0000100010010011 // 2195 +0000100010010100 // 2196 +0000100010010101 // 2197 +0000100010010110 // 2198 +0000100010010111 // 2199 +0000100010011000 // 2200 +0000100010011001 // 2201 +0000100010011010 // 2202 +0000100010011011 // 2203 +0000100010011100 // 2204 +0000100010011101 // 2205 +0000100010011110 // 2206 +0000100010011111 // 2207 +0000100010100000 // 2208 +0000100010100001 // 2209 +0000100010100010 // 2210 +0000100010100011 // 2211 +0000100010100100 // 2212 +0000100010100101 // 2213 +0000100010100110 // 2214 +0000100010100111 // 2215 +0000100010101000 // 2216 +0000100010101001 // 2217 +0000100010101010 // 2218 +0000100010101011 // 2219 +0000100010101100 // 2220 +0000100010101101 // 2221 +0000100010101110 // 2222 +0000100010101111 // 2223 +0000100010110000 // 2224 +0000100010110001 // 2225 +0000100010110010 // 2226 +0000100010110011 // 2227 +0000100010110100 // 2228 +0000100010110101 // 2229 +0000100010110110 // 2230 +0000100010110111 // 2231 +0000100010111000 // 2232 +0000100010111001 // 2233 +0000100010111010 // 2234 +0000100010111011 // 2235 +0000100010111100 // 2236 +0000100010111101 // 2237 +0000100010111110 // 2238 +0000100010111111 // 2239 +0000100011000000 // 2240 +0000100011000001 // 2241 +0000100011000010 // 2242 +0000100011000011 // 2243 +0000100011000100 // 2244 +0000100011000101 // 2245 +0000100011000110 // 2246 +0000100011000111 // 2247 +0000100011001000 // 2248 +0000100011001001 // 2249 +0000100011001010 // 2250 +0000100011001011 // 2251 +0000100011001100 // 2252 +0000100011001101 // 2253 +0000100011001110 // 2254 +0000100011001111 // 2255 +0000100011010000 // 2256 +0000100011010001 // 2257 +0000100011010010 // 2258 +0000100011010011 // 2259 +0000100011010100 // 2260 +0000100011010101 // 2261 +0000100011010110 // 2262 +0000100011010111 // 2263 +0000100011011000 // 2264 +0000100011011001 // 2265 +0000100011011010 // 2266 +0000100011011011 // 2267 +0000100011011100 // 2268 +0000100011011101 // 2269 +0000100011011110 // 2270 +0000100011011111 // 2271 +0000100011100000 // 2272 +0000100011100001 // 2273 +0000100011100010 // 2274 +0000100011100011 // 2275 +0000100011100100 // 2276 +0000100011100101 // 2277 +0000100011100110 // 2278 +0000100011100111 // 2279 +0000100011101000 // 2280 +0000100011101001 // 2281 +0000100011101010 // 2282 +0000100011101011 // 2283 +0000100011101100 // 2284 +0000100011101101 // 2285 +0000100011101110 // 2286 +0000100011101111 // 2287 +0000100011110000 // 2288 +0000100011110001 // 2289 +0000100011110010 // 2290 +0000100011110011 // 2291 +0000100011110100 // 2292 +0000100011110101 // 2293 +0000100011110110 // 2294 +0000100011110111 // 2295 +0000100011111000 // 2296 +0000100011111001 // 2297 +0000100011111010 // 2298 +0000100011111011 // 2299 +0000100011111100 // 2300 +0000100011111101 // 2301 +0000100011111110 // 2302 +0000100011111111 // 2303 +0000100100000000 // 2304 +0000100100000001 // 2305 +0000100100000010 // 2306 +0000100100000011 // 2307 +0000100100000100 // 2308 +0000100100000101 // 2309 +0000100100000110 // 2310 +0000100100000111 // 2311 +0000100100001000 // 2312 +0000100100001001 // 2313 +0000100100001010 // 2314 +0000100100001011 // 2315 +0000100100001100 // 2316 +0000100100001101 // 2317 +0000100100001110 // 2318 +0000100100001111 // 2319 +0000100100010000 // 2320 +0000100100010001 // 2321 +0000100100010010 // 2322 +0000100100010011 // 2323 +0000100100010100 // 2324 +0000100100010101 // 2325 +0000100100010110 // 2326 +0000100100010111 // 2327 +0000100100011000 // 2328 +0000100100011001 // 2329 +0000100100011010 // 2330 +0000100100011011 // 2331 +0000100100011100 // 2332 +0000100100011101 // 2333 +0000100100011110 // 2334 +0000100100011111 // 2335 +0000100100100000 // 2336 +0000100100100001 // 2337 +0000100100100010 // 2338 +0000100100100011 // 2339 +0000100100100100 // 2340 +0000100100100101 // 2341 +0000100100100110 // 2342 +0000100100100111 // 2343 +0000100100101000 // 2344 +0000100100101001 // 2345 +0000100100101010 // 2346 +0000100100101011 // 2347 +0000100100101100 // 2348 +0000100100101101 // 2349 +0000100100101110 // 2350 +0000100100101111 // 2351 +0000100100110000 // 2352 +0000100100110001 // 2353 +0000100100110010 // 2354 +0000100100110011 // 2355 +0000100100110100 // 2356 +0000100100110101 // 2357 +0000100100110110 // 2358 +0000100100110111 // 2359 +0000100100111000 // 2360 +0000100100111001 // 2361 +0000100100111010 // 2362 +0000100100111011 // 2363 +0000100100111100 // 2364 +0000100100111101 // 2365 +0000100100111110 // 2366 +0000100100111111 // 2367 +0000100101000000 // 2368 +0000100101000001 // 2369 +0000100101000010 // 2370 +0000100101000011 // 2371 +0000100101000100 // 2372 +0000100101000101 // 2373 +0000100101000110 // 2374 +0000100101000111 // 2375 +0000100101001000 // 2376 +0000100101001001 // 2377 +0000100101001010 // 2378 +0000100101001011 // 2379 +0000100101001100 // 2380 +0000100101001101 // 2381 +0000100101001110 // 2382 +0000100101001111 // 2383 +0000100101010000 // 2384 +0000100101010001 // 2385 +0000100101010010 // 2386 +0000100101010011 // 2387 +0000100101010100 // 2388 +0000100101010101 // 2389 +0000100101010110 // 2390 +0000100101010111 // 2391 +0000100101011000 // 2392 +0000100101011001 // 2393 +0000100101011010 // 2394 +0000100101011011 // 2395 +0000100101011100 // 2396 +0000100101011101 // 2397 +0000100101011110 // 2398 +0000100101011111 // 2399 +0000100101100000 // 2400 +0000100101100001 // 2401 +0000100101100010 // 2402 +0000100101100011 // 2403 +0000100101100100 // 2404 +0000100101100101 // 2405 +0000100101100110 // 2406 +0000100101100111 // 2407 +0000100101101000 // 2408 +0000100101101001 // 2409 +0000100101101010 // 2410 +0000100101101011 // 2411 +0000100101101100 // 2412 +0000100101101101 // 2413 +0000100101101110 // 2414 +0000100101101111 // 2415 +0000100101110000 // 2416 +0000100101110001 // 2417 +0000100101110010 // 2418 +0000100101110011 // 2419 +0000100101110100 // 2420 +0000100101110101 // 2421 +0000100101110110 // 2422 +0000100101110111 // 2423 +0000100101111000 // 2424 +0000100101111001 // 2425 +0000100101111010 // 2426 +0000100101111011 // 2427 +0000100101111100 // 2428 +0000100101111101 // 2429 +0000100101111110 // 2430 +0000100101111111 // 2431 +0000100110000000 // 2432 +0000100110000001 // 2433 +0000100110000010 // 2434 +0000100110000011 // 2435 +0000100110000100 // 2436 +0000100110000101 // 2437 +0000100110000110 // 2438 +0000100110000111 // 2439 +0000100110001000 // 2440 +0000100110001001 // 2441 +0000100110001010 // 2442 +0000100110001011 // 2443 +0000100110001100 // 2444 +0000100110001101 // 2445 +0000100110001110 // 2446 +0000100110001111 // 2447 +0000100110010000 // 2448 +0000100110010001 // 2449 +0000100110010010 // 2450 +0000100110010011 // 2451 +0000100110010100 // 2452 +0000100110010101 // 2453 +0000100110010110 // 2454 +0000100110010111 // 2455 +0000100110011000 // 2456 +0000100110011001 // 2457 +0000100110011010 // 2458 +0000100110011011 // 2459 +0000100110011100 // 2460 +0000100110011101 // 2461 +0000100110011110 // 2462 +0000100110011111 // 2463 +0000100110100000 // 2464 +0000100110100001 // 2465 +0000100110100010 // 2466 +0000100110100011 // 2467 +0000100110100100 // 2468 +0000100110100101 // 2469 +0000100110100110 // 2470 +0000100110100111 // 2471 +0000100110101000 // 2472 +0000100110101001 // 2473 +0000100110101010 // 2474 +0000100110101011 // 2475 +0000100110101100 // 2476 +0000100110101101 // 2477 +0000100110101110 // 2478 +0000100110101111 // 2479 +0000100110110000 // 2480 +0000100110110001 // 2481 +0000100110110010 // 2482 +0000100110110011 // 2483 +0000100110110100 // 2484 +0000100110110101 // 2485 +0000100110110110 // 2486 +0000100110110111 // 2487 +0000100110111000 // 2488 +0000100110111001 // 2489 +0000100110111010 // 2490 +0000100110111011 // 2491 +0000100110111100 // 2492 +0000100110111101 // 2493 +0000100110111110 // 2494 +0000100110111111 // 2495 +0000100111000000 // 2496 +0000100111000001 // 2497 +0000100111000010 // 2498 +0000100111000011 // 2499 +0000100111000100 // 2500 +0000100111000101 // 2501 +0000100111000110 // 2502 +0000100111000111 // 2503 +0000100111001000 // 2504 +0000100111001001 // 2505 +0000100111001010 // 2506 +0000100111001011 // 2507 +0000100111001100 // 2508 +0000100111001101 // 2509 +0000100111001110 // 2510 +0000100111001111 // 2511 +0000100111010000 // 2512 +0000100111010001 // 2513 +0000100111010010 // 2514 +0000100111010011 // 2515 +0000100111010100 // 2516 +0000100111010101 // 2517 +0000100111010110 // 2518 +0000100111010111 // 2519 +0000100111011000 // 2520 +0000100111011001 // 2521 +0000100111011010 // 2522 +0000100111011011 // 2523 +0000100111011100 // 2524 +0000100111011101 // 2525 +0000100111011110 // 2526 +0000100111011111 // 2527 +0000100111100000 // 2528 +0000100111100001 // 2529 +0000100111100010 // 2530 +0000100111100011 // 2531 +0000100111100100 // 2532 +0000100111100101 // 2533 +0000100111100110 // 2534 +0000100111100111 // 2535 +0000100111101000 // 2536 +0000100111101001 // 2537 +0000100111101010 // 2538 +0000100111101011 // 2539 +0000100111101100 // 2540 +0000100111101101 // 2541 +0000100111101110 // 2542 +0000100111101111 // 2543 +0000100111110000 // 2544 +0000100111110001 // 2545 +0000100111110010 // 2546 +0000100111110011 // 2547 +0000100111110100 // 2548 +0000100111110101 // 2549 +0000100111110110 // 2550 +0000100111110111 // 2551 +0000100111111000 // 2552 +0000100111111001 // 2553 +0000100111111010 // 2554 +0000100111111011 // 2555 +0000100111111100 // 2556 +0000100111111101 // 2557 +0000100111111110 // 2558 +0000100111111111 // 2559 +0000101000000000 // 2560 +0000101000000001 // 2561 +0000101000000010 // 2562 +0000101000000011 // 2563 +0000101000000100 // 2564 +0000101000000101 // 2565 +0000101000000110 // 2566 +0000101000000111 // 2567 +0000101000001000 // 2568 +0000101000001001 // 2569 +0000101000001010 // 2570 +0000101000001011 // 2571 +0000101000001100 // 2572 +0000101000001101 // 2573 +0000101000001110 // 2574 +0000101000001111 // 2575 +0000101000010000 // 2576 +0000101000010001 // 2577 +0000101000010010 // 2578 +0000101000010011 // 2579 +0000101000010100 // 2580 +0000101000010101 // 2581 +0000101000010110 // 2582 +0000101000010111 // 2583 +0000101000011000 // 2584 +0000101000011001 // 2585 +0000101000011010 // 2586 +0000101000011011 // 2587 +0000101000011100 // 2588 +0000101000011101 // 2589 +0000101000011110 // 2590 +0000101000011111 // 2591 +0000101000100000 // 2592 +0000101000100001 // 2593 +0000101000100010 // 2594 +0000101000100011 // 2595 +0000101000100100 // 2596 +0000101000100101 // 2597 +0000101000100110 // 2598 +0000101000100111 // 2599 +0000101000101000 // 2600 +0000101000101001 // 2601 +0000101000101010 // 2602 +0000101000101011 // 2603 +0000101000101100 // 2604 +0000101000101101 // 2605 +0000101000101110 // 2606 +0000101000101111 // 2607 +0000101000110000 // 2608 +0000101000110001 // 2609 +0000101000110010 // 2610 +0000101000110011 // 2611 +0000101000110100 // 2612 +0000101000110101 // 2613 +0000101000110110 // 2614 +0000101000110111 // 2615 +0000101000111000 // 2616 +0000101000111001 // 2617 +0000101000111010 // 2618 +0000101000111011 // 2619 +0000101000111100 // 2620 +0000101000111101 // 2621 +0000101000111110 // 2622 +0000101000111111 // 2623 +0000101001000000 // 2624 +0000101001000001 // 2625 +0000101001000010 // 2626 +0000101001000011 // 2627 +0000101001000100 // 2628 +0000101001000101 // 2629 +0000101001000110 // 2630 +0000101001000111 // 2631 +0000101001001000 // 2632 +0000101001001001 // 2633 +0000101001001010 // 2634 +0000101001001011 // 2635 +0000101001001100 // 2636 +0000101001001101 // 2637 +0000101001001110 // 2638 +0000101001001111 // 2639 +0000101001010000 // 2640 +0000101001010001 // 2641 +0000101001010010 // 2642 +0000101001010011 // 2643 +0000101001010100 // 2644 +0000101001010101 // 2645 +0000101001010110 // 2646 +0000101001010111 // 2647 +0000101001011000 // 2648 +0000101001011001 // 2649 +0000101001011010 // 2650 +0000101001011011 // 2651 +0000101001011100 // 2652 +0000101001011101 // 2653 +0000101001011110 // 2654 +0000101001011111 // 2655 +0000101001100000 // 2656 +0000101001100001 // 2657 +0000101001100010 // 2658 +0000101001100011 // 2659 +0000101001100100 // 2660 +0000101001100101 // 2661 +0000101001100110 // 2662 +0000101001100111 // 2663 +0000101001101000 // 2664 +0000101001101001 // 2665 +0000101001101010 // 2666 +0000101001101011 // 2667 +0000101001101100 // 2668 +0000101001101101 // 2669 +0000101001101110 // 2670 +0000101001101111 // 2671 +0000101001110000 // 2672 +0000101001110001 // 2673 +0000101001110010 // 2674 +0000101001110011 // 2675 +0000101001110100 // 2676 +0000101001110101 // 2677 +0000101001110110 // 2678 +0000101001110111 // 2679 +0000101001111000 // 2680 +0000101001111001 // 2681 +0000101001111010 // 2682 +0000101001111011 // 2683 +0000101001111100 // 2684 +0000101001111101 // 2685 +0000101001111110 // 2686 +0000101001111111 // 2687 +0000101010000000 // 2688 +0000101010000001 // 2689 +0000101010000010 // 2690 +0000101010000011 // 2691 +0000101010000100 // 2692 +0000101010000101 // 2693 +0000101010000110 // 2694 +0000101010000111 // 2695 +0000101010001000 // 2696 +0000101010001001 // 2697 +0000101010001010 // 2698 +0000101010001011 // 2699 +0000101010001100 // 2700 +0000101010001101 // 2701 +0000101010001110 // 2702 +0000101010001111 // 2703 +0000101010010000 // 2704 +0000101010010001 // 2705 +0000101010010010 // 2706 +0000101010010011 // 2707 +0000101010010100 // 2708 +0000101010010101 // 2709 +0000101010010110 // 2710 +0000101010010111 // 2711 +0000101010011000 // 2712 +0000101010011001 // 2713 +0000101010011010 // 2714 +0000101010011011 // 2715 +0000101010011100 // 2716 +0000101010011101 // 2717 +0000101010011110 // 2718 +0000101010011111 // 2719 +0000101010100000 // 2720 +0000101010100001 // 2721 +0000101010100010 // 2722 +0000101010100011 // 2723 +0000101010100100 // 2724 +0000101010100101 // 2725 +0000101010100110 // 2726 +0000101010100111 // 2727 +0000101010101000 // 2728 +0000101010101001 // 2729 +0000101010101010 // 2730 +0000101010101011 // 2731 +0000101010101100 // 2732 +0000101010101101 // 2733 +0000101010101110 // 2734 +0000101010101111 // 2735 +0000101010110000 // 2736 +0000101010110001 // 2737 +0000101010110010 // 2738 +0000101010110011 // 2739 +0000101010110100 // 2740 +0000101010110101 // 2741 +0000101010110110 // 2742 +0000101010110111 // 2743 +0000101010111000 // 2744 +0000101010111001 // 2745 +0000101010111010 // 2746 +0000101010111011 // 2747 +0000101010111100 // 2748 +0000101010111101 // 2749 +0000101010111110 // 2750 +0000101010111111 // 2751 +0000101011000000 // 2752 +0000101011000001 // 2753 +0000101011000010 // 2754 +0000101011000011 // 2755 +0000101011000100 // 2756 +0000101011000101 // 2757 +0000101011000110 // 2758 +0000101011000111 // 2759 +0000101011001000 // 2760 +0000101011001001 // 2761 +0000101011001010 // 2762 +0000101011001011 // 2763 +0000101011001100 // 2764 +0000101011001101 // 2765 +0000101011001110 // 2766 +0000101011001111 // 2767 +0000101011010000 // 2768 +0000101011010001 // 2769 +0000101011010010 // 2770 +0000101011010011 // 2771 +0000101011010100 // 2772 +0000101011010101 // 2773 +0000101011010110 // 2774 +0000101011010111 // 2775 +0000101011011000 // 2776 +0000101011011001 // 2777 +0000101011011010 // 2778 +0000101011011011 // 2779 +0000101011011100 // 2780 +0000101011011101 // 2781 +0000101011011110 // 2782 +0000101011011111 // 2783 +0000101011100000 // 2784 +0000101011100001 // 2785 +0000101011100010 // 2786 +0000101011100011 // 2787 +0000101011100100 // 2788 +0000101011100101 // 2789 +0000101011100110 // 2790 +0000101011100111 // 2791 +0000101011101000 // 2792 +0000101011101001 // 2793 +0000101011101010 // 2794 +0000101011101011 // 2795 +0000101011101100 // 2796 +0000101011101101 // 2797 +0000101011101110 // 2798 +0000101011101111 // 2799 +0000101011110000 // 2800 +0000101011110001 // 2801 +0000101011110010 // 2802 +0000101011110011 // 2803 +0000101011110100 // 2804 +0000101011110101 // 2805 +0000101011110110 // 2806 +0000101011110111 // 2807 +0000101011111000 // 2808 +0000101011111001 // 2809 +0000101011111010 // 2810 +0000101011111011 // 2811 +0000101011111100 // 2812 +0000101011111101 // 2813 +0000101011111110 // 2814 +0000101011111111 // 2815 +0000101100000000 // 2816 +0000101100000001 // 2817 +0000101100000010 // 2818 +0000101100000011 // 2819 +0000101100000100 // 2820 +0000101100000101 // 2821 +0000101100000110 // 2822 +0000101100000111 // 2823 +0000101100001000 // 2824 +0000101100001001 // 2825 +0000101100001010 // 2826 +0000101100001011 // 2827 +0000101100001100 // 2828 +0000101100001101 // 2829 +0000101100001110 // 2830 +0000101100001111 // 2831 +0000101100010000 // 2832 +0000101100010001 // 2833 +0000101100010010 // 2834 +0000101100010011 // 2835 +0000101100010100 // 2836 +0000101100010101 // 2837 +0000101100010110 // 2838 +0000101100010111 // 2839 +0000101100011000 // 2840 +0000101100011001 // 2841 +0000101100011010 // 2842 +0000101100011011 // 2843 +0000101100011100 // 2844 +0000101100011101 // 2845 +0000101100011110 // 2846 +0000101100011111 // 2847 +0000101100100000 // 2848 +0000101100100001 // 2849 +0000101100100010 // 2850 +0000101100100011 // 2851 +0000101100100100 // 2852 +0000101100100101 // 2853 +0000101100100110 // 2854 +0000101100100111 // 2855 +0000101100101000 // 2856 +0000101100101001 // 2857 +0000101100101010 // 2858 +0000101100101011 // 2859 +0000101100101100 // 2860 +0000101100101101 // 2861 +0000101100101110 // 2862 +0000101100101111 // 2863 +0000101100110000 // 2864 +0000101100110001 // 2865 +0000101100110010 // 2866 +0000101100110011 // 2867 +0000101100110100 // 2868 +0000101100110101 // 2869 +0000101100110110 // 2870 +0000101100110111 // 2871 +0000101100111000 // 2872 +0000101100111001 // 2873 +0000101100111010 // 2874 +0000101100111011 // 2875 +0000101100111100 // 2876 +0000101100111101 // 2877 +0000101100111110 // 2878 +0000101100111111 // 2879 +0000101101000000 // 2880 +0000101101000001 // 2881 +0000101101000010 // 2882 +0000101101000011 // 2883 +0000101101000100 // 2884 +0000101101000101 // 2885 +0000101101000110 // 2886 +0000101101000111 // 2887 +0000101101001000 // 2888 +0000101101001001 // 2889 +0000101101001010 // 2890 +0000101101001011 // 2891 +0000101101001100 // 2892 +0000101101001101 // 2893 +0000101101001110 // 2894 +0000101101001111 // 2895 +0000101101010000 // 2896 +0000101101010001 // 2897 +0000101101010010 // 2898 +0000101101010011 // 2899 +0000101101010100 // 2900 +0000101101010101 // 2901 +0000101101010110 // 2902 +0000101101010111 // 2903 +0000101101011000 // 2904 +0000101101011001 // 2905 +0000101101011010 // 2906 +0000101101011011 // 2907 +0000101101011100 // 2908 +0000101101011101 // 2909 +0000101101011110 // 2910 +0000101101011111 // 2911 +0000101101100000 // 2912 +0000101101100001 // 2913 +0000101101100010 // 2914 +0000101101100011 // 2915 +0000101101100100 // 2916 +0000101101100101 // 2917 +0000101101100110 // 2918 +0000101101100111 // 2919 +0000101101101000 // 2920 +0000101101101001 // 2921 +0000101101101010 // 2922 +0000101101101011 // 2923 +0000101101101100 // 2924 +0000101101101101 // 2925 +0000101101101110 // 2926 +0000101101101111 // 2927 +0000101101110000 // 2928 +0000101101110001 // 2929 +0000101101110010 // 2930 +0000101101110011 // 2931 +0000101101110100 // 2932 +0000101101110101 // 2933 +0000101101110110 // 2934 +0000101101110111 // 2935 +0000101101111000 // 2936 +0000101101111001 // 2937 +0000101101111010 // 2938 +0000101101111011 // 2939 +0000101101111100 // 2940 +0000101101111101 // 2941 +0000101101111110 // 2942 +0000101101111111 // 2943 +0000101110000000 // 2944 +0000101110000001 // 2945 +0000101110000010 // 2946 +0000101110000011 // 2947 +0000101110000100 // 2948 +0000101110000101 // 2949 +0000101110000110 // 2950 +0000101110000111 // 2951 +0000101110001000 // 2952 +0000101110001001 // 2953 +0000101110001010 // 2954 +0000101110001011 // 2955 +0000101110001100 // 2956 +0000101110001101 // 2957 +0000101110001110 // 2958 +0000101110001111 // 2959 +0000101110010000 // 2960 +0000101110010001 // 2961 +0000101110010010 // 2962 +0000101110010011 // 2963 +0000101110010100 // 2964 +0000101110010101 // 2965 +0000101110010110 // 2966 +0000101110010111 // 2967 +0000101110011000 // 2968 +0000101110011001 // 2969 +0000101110011010 // 2970 +0000101110011011 // 2971 +0000101110011100 // 2972 +0000101110011101 // 2973 +0000101110011110 // 2974 +0000101110011111 // 2975 +0000101110100000 // 2976 +0000101110100001 // 2977 +0000101110100010 // 2978 +0000101110100011 // 2979 +0000101110100100 // 2980 +0000101110100101 // 2981 +0000101110100110 // 2982 +0000101110100111 // 2983 +0000101110101000 // 2984 +0000101110101001 // 2985 +0000101110101010 // 2986 +0000101110101011 // 2987 +0000101110101100 // 2988 +0000101110101101 // 2989 +0000101110101110 // 2990 +0000101110101111 // 2991 +0000101110110000 // 2992 +0000101110110001 // 2993 +0000101110110010 // 2994 +0000101110110011 // 2995 +0000101110110100 // 2996 +0000101110110101 // 2997 +0000101110110110 // 2998 +0000101110110111 // 2999 +0000101110111000 // 3000 +0000101110111001 // 3001 +0000101110111010 // 3002 +0000101110111011 // 3003 +0000101110111100 // 3004 +0000101110111101 // 3005 +0000101110111110 // 3006 +0000101110111111 // 3007 +0000101111000000 // 3008 +0000101111000001 // 3009 +0000101111000010 // 3010 +0000101111000011 // 3011 +0000101111000100 // 3012 +0000101111000101 // 3013 +0000101111000110 // 3014 +0000101111000111 // 3015 +0000101111001000 // 3016 +0000101111001001 // 3017 +0000101111001010 // 3018 +0000101111001011 // 3019 +0000101111001100 // 3020 +0000101111001101 // 3021 +0000101111001110 // 3022 +0000101111001111 // 3023 +0000101111010000 // 3024 +0000101111010001 // 3025 +0000101111010010 // 3026 +0000101111010011 // 3027 +0000101111010100 // 3028 +0000101111010101 // 3029 +0000101111010110 // 3030 +0000101111010111 // 3031 +0000101111011000 // 3032 +0000101111011001 // 3033 +0000101111011010 // 3034 +0000101111011011 // 3035 +0000101111011100 // 3036 +0000101111011101 // 3037 +0000101111011110 // 3038 +0000101111011111 // 3039 +0000101111100000 // 3040 +0000101111100001 // 3041 +0000101111100010 // 3042 +0000101111100011 // 3043 +0000101111100100 // 3044 +0000101111100101 // 3045 +0000101111100110 // 3046 +0000101111100111 // 3047 +0000101111101000 // 3048 +0000101111101001 // 3049 +0000101111101010 // 3050 +0000101111101011 // 3051 +0000101111101100 // 3052 +0000101111101101 // 3053 +0000101111101110 // 3054 +0000101111101111 // 3055 +0000101111110000 // 3056 +0000101111110001 // 3057 +0000101111110010 // 3058 +0000101111110011 // 3059 +0000101111110100 // 3060 +0000101111110101 // 3061 +0000101111110110 // 3062 +0000101111110111 // 3063 +0000101111111000 // 3064 +0000101111111001 // 3065 +0000101111111010 // 3066 +0000101111111011 // 3067 +0000101111111100 // 3068 +0000101111111101 // 3069 +0000101111111110 // 3070 +0000101111111111 // 3071 +0000110000000000 // 3072 +0000110000000001 // 3073 +0000110000000010 // 3074 +0000110000000011 // 3075 +0000110000000100 // 3076 +0000110000000101 // 3077 +0000110000000110 // 3078 +0000110000000111 // 3079 +0000110000001000 // 3080 +0000110000001001 // 3081 +0000110000001010 // 3082 +0000110000001011 // 3083 +0000110000001100 // 3084 +0000110000001101 // 3085 +0000110000001110 // 3086 +0000110000001111 // 3087 +0000110000010000 // 3088 +0000110000010001 // 3089 +0000110000010010 // 3090 +0000110000010011 // 3091 +0000110000010100 // 3092 +0000110000010101 // 3093 +0000110000010110 // 3094 +0000110000010111 // 3095 +0000110000011000 // 3096 +0000110000011001 // 3097 +0000110000011010 // 3098 +0000110000011011 // 3099 +0000110000011100 // 3100 +0000110000011101 // 3101 +0000110000011110 // 3102 +0000110000011111 // 3103 +0000110000100000 // 3104 +0000110000100001 // 3105 +0000110000100010 // 3106 +0000110000100011 // 3107 +0000110000100100 // 3108 +0000110000100101 // 3109 +0000110000100110 // 3110 +0000110000100111 // 3111 +0000110000101000 // 3112 +0000110000101001 // 3113 +0000110000101010 // 3114 +0000110000101011 // 3115 +0000110000101100 // 3116 +0000110000101101 // 3117 +0000110000101110 // 3118 +0000110000101111 // 3119 +0000110000110000 // 3120 +0000110000110001 // 3121 +0000110000110010 // 3122 +0000110000110011 // 3123 +0000110000110100 // 3124 +0000110000110101 // 3125 +0000110000110110 // 3126 +0000110000110111 // 3127 +0000110000111000 // 3128 +0000110000111001 // 3129 +0000110000111010 // 3130 +0000110000111011 // 3131 +0000110000111100 // 3132 +0000110000111101 // 3133 +0000110000111110 // 3134 +0000110000111111 // 3135 +0000110001000000 // 3136 +0000110001000001 // 3137 +0000110001000010 // 3138 +0000110001000011 // 3139 +0000110001000100 // 3140 +0000110001000101 // 3141 +0000110001000110 // 3142 +0000110001000111 // 3143 +0000110001001000 // 3144 +0000110001001001 // 3145 +0000110001001010 // 3146 +0000110001001011 // 3147 +0000110001001100 // 3148 +0000110001001101 // 3149 +0000110001001110 // 3150 +0000110001001111 // 3151 +0000110001010000 // 3152 +0000110001010001 // 3153 +0000110001010010 // 3154 +0000110001010011 // 3155 +0000110001010100 // 3156 +0000110001010101 // 3157 +0000110001010110 // 3158 +0000110001010111 // 3159 +0000110001011000 // 3160 +0000110001011001 // 3161 +0000110001011010 // 3162 +0000110001011011 // 3163 +0000110001011100 // 3164 +0000110001011101 // 3165 +0000110001011110 // 3166 +0000110001011111 // 3167 +0000110001100000 // 3168 +0000110001100001 // 3169 +0000110001100010 // 3170 +0000110001100011 // 3171 +0000110001100100 // 3172 +0000110001100101 // 3173 +0000110001100110 // 3174 +0000110001100111 // 3175 +0000110001101000 // 3176 +0000110001101001 // 3177 +0000110001101010 // 3178 +0000110001101011 // 3179 +0000110001101100 // 3180 +0000110001101101 // 3181 +0000110001101110 // 3182 +0000110001101111 // 3183 +0000110001110000 // 3184 +0000110001110001 // 3185 +0000110001110010 // 3186 +0000110001110011 // 3187 +0000110001110100 // 3188 +0000110001110101 // 3189 +0000110001110110 // 3190 +0000110001110111 // 3191 +0000110001111000 // 3192 +0000110001111001 // 3193 +0000110001111010 // 3194 +0000110001111011 // 3195 +0000110001111100 // 3196 +0000110001111101 // 3197 +0000110001111110 // 3198 +0000110001111111 // 3199 +0000110010000000 // 3200 +0000110010000001 // 3201 +0000110010000010 // 3202 +0000110010000011 // 3203 +0000110010000100 // 3204 +0000110010000101 // 3205 +0000110010000110 // 3206 +0000110010000111 // 3207 +0000110010001000 // 3208 +0000110010001001 // 3209 +0000110010001010 // 3210 +0000110010001011 // 3211 +0000110010001100 // 3212 +0000110010001101 // 3213 +0000110010001110 // 3214 +0000110010001111 // 3215 +0000110010010000 // 3216 +0000110010010001 // 3217 +0000110010010010 // 3218 +0000110010010011 // 3219 +0000110010010100 // 3220 +0000110010010101 // 3221 +0000110010010110 // 3222 +0000110010010111 // 3223 +0000110010011000 // 3224 +0000110010011001 // 3225 +0000110010011010 // 3226 +0000110010011011 // 3227 +0000110010011100 // 3228 +0000110010011101 // 3229 +0000110010011110 // 3230 +0000110010011111 // 3231 +0000110010100000 // 3232 +0000110010100001 // 3233 +0000110010100010 // 3234 +0000110010100011 // 3235 +0000110010100100 // 3236 +0000110010100101 // 3237 +0000110010100110 // 3238 +0000110010100111 // 3239 +0000110010101000 // 3240 +0000110010101001 // 3241 +0000110010101010 // 3242 +0000110010101011 // 3243 +0000110010101100 // 3244 +0000110010101101 // 3245 +0000110010101110 // 3246 +0000110010101111 // 3247 +0000110010110000 // 3248 +0000110010110001 // 3249 +0000110010110010 // 3250 +0000110010110011 // 3251 +0000110010110100 // 3252 +0000110010110101 // 3253 +0000110010110110 // 3254 +0000110010110111 // 3255 +0000110010111000 // 3256 +0000110010111001 // 3257 +0000110010111010 // 3258 +0000110010111011 // 3259 +0000110010111100 // 3260 +0000110010111101 // 3261 +0000110010111110 // 3262 +0000110010111111 // 3263 +0000110011000000 // 3264 +0000110011000001 // 3265 +0000110011000010 // 3266 +0000110011000011 // 3267 +0000110011000100 // 3268 +0000110011000101 // 3269 +0000110011000110 // 3270 +0000110011000111 // 3271 +0000110011001000 // 3272 +0000110011001001 // 3273 +0000110011001010 // 3274 +0000110011001011 // 3275 +0000110011001100 // 3276 +0000110011001101 // 3277 +0000110011001110 // 3278 +0000110011001111 // 3279 +0000110011010000 // 3280 +0000110011010001 // 3281 +0000110011010010 // 3282 +0000110011010011 // 3283 +0000110011010100 // 3284 +0000110011010101 // 3285 +0000110011010110 // 3286 +0000110011010111 // 3287 +0000110011011000 // 3288 +0000110011011001 // 3289 +0000110011011010 // 3290 +0000110011011011 // 3291 +0000110011011100 // 3292 +0000110011011101 // 3293 +0000110011011110 // 3294 +0000110011011111 // 3295 +0000110011100000 // 3296 +0000110011100001 // 3297 +0000110011100010 // 3298 +0000110011100011 // 3299 +0000110011100100 // 3300 +0000110011100101 // 3301 +0000110011100110 // 3302 +0000110011100111 // 3303 +0000110011101000 // 3304 +0000110011101001 // 3305 +0000110011101010 // 3306 +0000110011101011 // 3307 +0000110011101100 // 3308 +0000110011101101 // 3309 +0000110011101110 // 3310 +0000110011101111 // 3311 +0000110011110000 // 3312 +0000110011110001 // 3313 +0000110011110010 // 3314 +0000110011110011 // 3315 +0000110011110100 // 3316 +0000110011110101 // 3317 +0000110011110110 // 3318 +0000110011110111 // 3319 +0000110011111000 // 3320 +0000110011111001 // 3321 +0000110011111010 // 3322 +0000110011111011 // 3323 +0000110011111100 // 3324 +0000110011111101 // 3325 +0000110011111110 // 3326 +0000110011111111 // 3327 +0000110100000000 // 3328 +0000110100000001 // 3329 +0000110100000010 // 3330 +0000110100000011 // 3331 +0000110100000100 // 3332 +0000110100000101 // 3333 +0000110100000110 // 3334 +0000110100000111 // 3335 +0000110100001000 // 3336 +0000110100001001 // 3337 +0000110100001010 // 3338 +0000110100001011 // 3339 +0000110100001100 // 3340 +0000110100001101 // 3341 +0000110100001110 // 3342 +0000110100001111 // 3343 +0000110100010000 // 3344 +0000110100010001 // 3345 +0000110100010010 // 3346 +0000110100010011 // 3347 +0000110100010100 // 3348 +0000110100010101 // 3349 +0000110100010110 // 3350 +0000110100010111 // 3351 +0000110100011000 // 3352 +0000110100011001 // 3353 +0000110100011010 // 3354 +0000110100011011 // 3355 +0000110100011100 // 3356 +0000110100011101 // 3357 +0000110100011110 // 3358 +0000110100011111 // 3359 +0000110100100000 // 3360 +0000110100100001 // 3361 +0000110100100010 // 3362 +0000110100100011 // 3363 +0000110100100100 // 3364 +0000110100100101 // 3365 +0000110100100110 // 3366 +0000110100100111 // 3367 +0000110100101000 // 3368 +0000110100101001 // 3369 +0000110100101010 // 3370 +0000110100101011 // 3371 +0000110100101100 // 3372 +0000110100101101 // 3373 +0000110100101110 // 3374 +0000110100101111 // 3375 +0000110100110000 // 3376 +0000110100110001 // 3377 +0000110100110010 // 3378 +0000110100110011 // 3379 +0000110100110100 // 3380 +0000110100110101 // 3381 +0000110100110110 // 3382 +0000110100110111 // 3383 +0000110100111000 // 3384 +0000110100111001 // 3385 +0000110100111010 // 3386 +0000110100111011 // 3387 +0000110100111100 // 3388 +0000110100111101 // 3389 +0000110100111110 // 3390 +0000110100111111 // 3391 +0000110101000000 // 3392 +0000110101000001 // 3393 +0000110101000010 // 3394 +0000110101000011 // 3395 +0000110101000100 // 3396 +0000110101000101 // 3397 +0000110101000110 // 3398 +0000110101000111 // 3399 +0000110101001000 // 3400 +0000110101001001 // 3401 +0000110101001010 // 3402 +0000110101001011 // 3403 +0000110101001100 // 3404 +0000110101001101 // 3405 +0000110101001110 // 3406 +0000110101001111 // 3407 +0000110101010000 // 3408 +0000110101010001 // 3409 +0000110101010010 // 3410 +0000110101010011 // 3411 +0000110101010100 // 3412 +0000110101010101 // 3413 +0000110101010110 // 3414 +0000110101010111 // 3415 +0000110101011000 // 3416 +0000110101011001 // 3417 +0000110101011010 // 3418 +0000110101011011 // 3419 +0000110101011100 // 3420 +0000110101011101 // 3421 +0000110101011110 // 3422 +0000110101011111 // 3423 +0000110101100000 // 3424 +0000110101100001 // 3425 +0000110101100010 // 3426 +0000110101100011 // 3427 +0000110101100100 // 3428 +0000110101100101 // 3429 +0000110101100110 // 3430 +0000110101100111 // 3431 +0000110101101000 // 3432 +0000110101101001 // 3433 +0000110101101010 // 3434 +0000110101101011 // 3435 +0000110101101100 // 3436 +0000110101101101 // 3437 +0000110101101110 // 3438 +0000110101101111 // 3439 +0000110101110000 // 3440 +0000110101110001 // 3441 +0000110101110010 // 3442 +0000110101110011 // 3443 +0000110101110100 // 3444 +0000110101110101 // 3445 +0000110101110110 // 3446 +0000110101110111 // 3447 +0000110101111000 // 3448 +0000110101111001 // 3449 +0000110101111010 // 3450 +0000110101111011 // 3451 +0000110101111100 // 3452 +0000110101111101 // 3453 +0000110101111110 // 3454 +0000110101111111 // 3455 +0000110110000000 // 3456 +0000110110000001 // 3457 +0000110110000010 // 3458 +0000110110000011 // 3459 +0000110110000100 // 3460 +0000110110000101 // 3461 +0000110110000110 // 3462 +0000110110000111 // 3463 +0000110110001000 // 3464 +0000110110001001 // 3465 +0000110110001010 // 3466 +0000110110001011 // 3467 +0000110110001100 // 3468 +0000110110001101 // 3469 +0000110110001110 // 3470 +0000110110001111 // 3471 +0000110110010000 // 3472 +0000110110010001 // 3473 +0000110110010010 // 3474 +0000110110010011 // 3475 +0000110110010100 // 3476 +0000110110010101 // 3477 +0000110110010110 // 3478 +0000110110010111 // 3479 +0000110110011000 // 3480 +0000110110011001 // 3481 +0000110110011010 // 3482 +0000110110011011 // 3483 +0000110110011100 // 3484 +0000110110011101 // 3485 +0000110110011110 // 3486 +0000110110011111 // 3487 +0000110110100000 // 3488 +0000110110100001 // 3489 +0000110110100010 // 3490 +0000110110100011 // 3491 +0000110110100100 // 3492 +0000110110100101 // 3493 +0000110110100110 // 3494 +0000110110100111 // 3495 +0000110110101000 // 3496 +0000110110101001 // 3497 +0000110110101010 // 3498 +0000110110101011 // 3499 +0000110110101100 // 3500 +0000110110101101 // 3501 +0000110110101110 // 3502 +0000110110101111 // 3503 +0000110110110000 // 3504 +0000110110110001 // 3505 +0000110110110010 // 3506 +0000110110110011 // 3507 +0000110110110100 // 3508 +0000110110110101 // 3509 +0000110110110110 // 3510 +0000110110110111 // 3511 +0000110110111000 // 3512 +0000110110111001 // 3513 +0000110110111010 // 3514 +0000110110111011 // 3515 +0000110110111100 // 3516 +0000110110111101 // 3517 +0000110110111110 // 3518 +0000110110111111 // 3519 +0000110111000000 // 3520 +0000110111000001 // 3521 +0000110111000010 // 3522 +0000110111000011 // 3523 +0000110111000100 // 3524 +0000110111000101 // 3525 +0000110111000110 // 3526 +0000110111000111 // 3527 +0000110111001000 // 3528 +0000110111001001 // 3529 +0000110111001010 // 3530 +0000110111001011 // 3531 +0000110111001100 // 3532 +0000110111001101 // 3533 +0000110111001110 // 3534 +0000110111001111 // 3535 +0000110111010000 // 3536 +0000110111010001 // 3537 +0000110111010010 // 3538 +0000110111010011 // 3539 +0000110111010100 // 3540 +0000110111010101 // 3541 +0000110111010110 // 3542 +0000110111010111 // 3543 +0000110111011000 // 3544 +0000110111011001 // 3545 +0000110111011010 // 3546 +0000110111011011 // 3547 +0000110111011100 // 3548 +0000110111011101 // 3549 +0000110111011110 // 3550 +0000110111011111 // 3551 +0000110111100000 // 3552 +0000110111100001 // 3553 +0000110111100010 // 3554 +0000110111100011 // 3555 +0000110111100100 // 3556 +0000110111100101 // 3557 +0000110111100110 // 3558 +0000110111100111 // 3559 +0000110111101000 // 3560 +0000110111101001 // 3561 +0000110111101010 // 3562 +0000110111101011 // 3563 +0000110111101100 // 3564 +0000110111101101 // 3565 +0000110111101110 // 3566 +0000110111101111 // 3567 +0000110111110000 // 3568 +0000110111110001 // 3569 +0000110111110010 // 3570 +0000110111110011 // 3571 +0000110111110100 // 3572 +0000110111110101 // 3573 +0000110111110110 // 3574 +0000110111110111 // 3575 +0000110111111000 // 3576 +0000110111111001 // 3577 +0000110111111010 // 3578 +0000110111111011 // 3579 +0000110111111100 // 3580 +0000110111111101 // 3581 +0000110111111110 // 3582 +0000110111111111 // 3583 +0000111000000000 // 3584 +0000111000000001 // 3585 +0000111000000010 // 3586 +0000111000000011 // 3587 +0000111000000100 // 3588 +0000111000000101 // 3589 +0000111000000110 // 3590 +0000111000000111 // 3591 +0000111000001000 // 3592 +0000111000001001 // 3593 +0000111000001010 // 3594 +0000111000001011 // 3595 +0000111000001100 // 3596 +0000111000001101 // 3597 +0000111000001110 // 3598 +0000111000001111 // 3599 +0000111000010000 // 3600 +0000111000010001 // 3601 +0000111000010010 // 3602 +0000111000010011 // 3603 +0000111000010100 // 3604 +0000111000010101 // 3605 +0000111000010110 // 3606 +0000111000010111 // 3607 +0000111000011000 // 3608 +0000111000011001 // 3609 +0000111000011010 // 3610 +0000111000011011 // 3611 +0000111000011100 // 3612 +0000111000011101 // 3613 +0000111000011110 // 3614 +0000111000011111 // 3615 +0000111000100000 // 3616 +0000111000100001 // 3617 +0000111000100010 // 3618 +0000111000100011 // 3619 +0000111000100100 // 3620 +0000111000100101 // 3621 +0000111000100110 // 3622 +0000111000100111 // 3623 +0000111000101000 // 3624 +0000111000101001 // 3625 +0000111000101010 // 3626 +0000111000101011 // 3627 +0000111000101100 // 3628 +0000111000101101 // 3629 +0000111000101110 // 3630 +0000111000101111 // 3631 +0000111000110000 // 3632 +0000111000110001 // 3633 +0000111000110010 // 3634 +0000111000110011 // 3635 +0000111000110100 // 3636 +0000111000110101 // 3637 +0000111000110110 // 3638 +0000111000110111 // 3639 +0000111000111000 // 3640 +0000111000111001 // 3641 +0000111000111010 // 3642 +0000111000111011 // 3643 +0000111000111100 // 3644 +0000111000111101 // 3645 +0000111000111110 // 3646 +0000111000111111 // 3647 +0000111001000000 // 3648 +0000111001000001 // 3649 +0000111001000010 // 3650 +0000111001000011 // 3651 +0000111001000100 // 3652 +0000111001000101 // 3653 +0000111001000110 // 3654 +0000111001000111 // 3655 +0000111001001000 // 3656 +0000111001001001 // 3657 +0000111001001010 // 3658 +0000111001001011 // 3659 +0000111001001100 // 3660 +0000111001001101 // 3661 +0000111001001110 // 3662 +0000111001001111 // 3663 +0000111001010000 // 3664 +0000111001010001 // 3665 +0000111001010010 // 3666 +0000111001010011 // 3667 +0000111001010100 // 3668 +0000111001010101 // 3669 +0000111001010110 // 3670 +0000111001010111 // 3671 +0000111001011000 // 3672 +0000111001011001 // 3673 +0000111001011010 // 3674 +0000111001011011 // 3675 +0000111001011100 // 3676 +0000111001011101 // 3677 +0000111001011110 // 3678 +0000111001011111 // 3679 +0000111001100000 // 3680 +0000111001100001 // 3681 +0000111001100010 // 3682 +0000111001100011 // 3683 +0000111001100100 // 3684 +0000111001100101 // 3685 +0000111001100110 // 3686 +0000111001100111 // 3687 +0000111001101000 // 3688 +0000111001101001 // 3689 +0000111001101010 // 3690 +0000111001101011 // 3691 +0000111001101100 // 3692 +0000111001101101 // 3693 +0000111001101110 // 3694 +0000111001101111 // 3695 +0000111001110000 // 3696 +0000111001110001 // 3697 +0000111001110010 // 3698 +0000111001110011 // 3699 +0000111001110100 // 3700 +0000111001110101 // 3701 +0000111001110110 // 3702 +0000111001110111 // 3703 +0000111001111000 // 3704 +0000111001111001 // 3705 +0000111001111010 // 3706 +0000111001111011 // 3707 +0000111001111100 // 3708 +0000111001111101 // 3709 +0000111001111110 // 3710 +0000111001111111 // 3711 +0000111010000000 // 3712 +0000111010000001 // 3713 +0000111010000010 // 3714 +0000111010000011 // 3715 +0000111010000100 // 3716 +0000111010000101 // 3717 +0000111010000110 // 3718 +0000111010000111 // 3719 +0000111010001000 // 3720 +0000111010001001 // 3721 +0000111010001010 // 3722 +0000111010001011 // 3723 +0000111010001100 // 3724 +0000111010001101 // 3725 +0000111010001110 // 3726 +0000111010001111 // 3727 +0000111010010000 // 3728 +0000111010010001 // 3729 +0000111010010010 // 3730 +0000111010010011 // 3731 +0000111010010100 // 3732 +0000111010010101 // 3733 +0000111010010110 // 3734 +0000111010010111 // 3735 +0000111010011000 // 3736 +0000111010011001 // 3737 +0000111010011010 // 3738 +0000111010011011 // 3739 +0000111010011100 // 3740 +0000111010011101 // 3741 +0000111010011110 // 3742 +0000111010011111 // 3743 +0000111010100000 // 3744 +0000111010100001 // 3745 +0000111010100010 // 3746 +0000111010100011 // 3747 +0000111010100100 // 3748 +0000111010100101 // 3749 +0000111010100110 // 3750 +0000111010100111 // 3751 +0000111010101000 // 3752 +0000111010101001 // 3753 +0000111010101010 // 3754 +0000111010101011 // 3755 +0000111010101100 // 3756 +0000111010101101 // 3757 +0000111010101110 // 3758 +0000111010101111 // 3759 +0000111010110000 // 3760 +0000111010110001 // 3761 +0000111010110010 // 3762 +0000111010110011 // 3763 +0000111010110100 // 3764 +0000111010110101 // 3765 +0000111010110110 // 3766 +0000111010110111 // 3767 +0000111010111000 // 3768 +0000111010111001 // 3769 +0000111010111010 // 3770 +0000111010111011 // 3771 +0000111010111100 // 3772 +0000111010111101 // 3773 +0000111010111110 // 3774 +0000111010111111 // 3775 +0000111011000000 // 3776 +0000111011000001 // 3777 +0000111011000010 // 3778 +0000111011000011 // 3779 +0000111011000100 // 3780 +0000111011000101 // 3781 +0000111011000110 // 3782 +0000111011000111 // 3783 +0000111011001000 // 3784 +0000111011001001 // 3785 +0000111011001010 // 3786 +0000111011001011 // 3787 +0000111011001100 // 3788 +0000111011001101 // 3789 +0000111011001110 // 3790 +0000111011001111 // 3791 +0000111011010000 // 3792 +0000111011010001 // 3793 +0000111011010010 // 3794 +0000111011010011 // 3795 +0000111011010100 // 3796 +0000111011010101 // 3797 +0000111011010110 // 3798 +0000111011010111 // 3799 +0000111011011000 // 3800 +0000111011011001 // 3801 +0000111011011010 // 3802 +0000111011011011 // 3803 +0000111011011100 // 3804 +0000111011011101 // 3805 +0000111011011110 // 3806 +0000111011011111 // 3807 +0000111011100000 // 3808 +0000111011100001 // 3809 +0000111011100010 // 3810 +0000111011100011 // 3811 +0000111011100100 // 3812 +0000111011100101 // 3813 +0000111011100110 // 3814 +0000111011100111 // 3815 +0000111011101000 // 3816 +0000111011101001 // 3817 +0000111011101010 // 3818 +0000111011101011 // 3819 +0000111011101100 // 3820 +0000111011101101 // 3821 +0000111011101110 // 3822 +0000111011101111 // 3823 +0000111011110000 // 3824 +0000111011110001 // 3825 +0000111011110010 // 3826 +0000111011110011 // 3827 +0000111011110100 // 3828 +0000111011110101 // 3829 +0000111011110110 // 3830 +0000111011110111 // 3831 +0000111011111000 // 3832 +0000111011111001 // 3833 +0000111011111010 // 3834 +0000111011111011 // 3835 +0000111011111100 // 3836 +0000111011111101 // 3837 +0000111011111110 // 3838 +0000111011111111 // 3839 +0000111100000000 // 3840 +0000111100000001 // 3841 +0000111100000010 // 3842 +0000111100000011 // 3843 +0000111100000100 // 3844 +0000111100000101 // 3845 +0000111100000110 // 3846 +0000111100000111 // 3847 +0000111100001000 // 3848 +0000111100001001 // 3849 +0000111100001010 // 3850 +0000111100001011 // 3851 +0000111100001100 // 3852 +0000111100001101 // 3853 +0000111100001110 // 3854 +0000111100001111 // 3855 +0000111100010000 // 3856 +0000111100010001 // 3857 +0000111100010010 // 3858 +0000111100010011 // 3859 +0000111100010100 // 3860 +0000111100010101 // 3861 +0000111100010110 // 3862 +0000111100010111 // 3863 +0000111100011000 // 3864 +0000111100011001 // 3865 +0000111100011010 // 3866 +0000111100011011 // 3867 +0000111100011100 // 3868 +0000111100011101 // 3869 +0000111100011110 // 3870 +0000111100011111 // 3871 +0000111100100000 // 3872 +0000111100100001 // 3873 +0000111100100010 // 3874 +0000111100100011 // 3875 +0000111100100100 // 3876 +0000111100100101 // 3877 +0000111100100110 // 3878 +0000111100100111 // 3879 +0000111100101000 // 3880 +0000111100101001 // 3881 +0000111100101010 // 3882 +0000111100101011 // 3883 +0000111100101100 // 3884 +0000111100101101 // 3885 +0000111100101110 // 3886 +0000111100101111 // 3887 +0000111100110000 // 3888 +0000111100110001 // 3889 +0000111100110010 // 3890 +0000111100110011 // 3891 +0000111100110100 // 3892 +0000111100110101 // 3893 +0000111100110110 // 3894 +0000111100110111 // 3895 +0000111100111000 // 3896 +0000111100111001 // 3897 +0000111100111010 // 3898 +0000111100111011 // 3899 +0000111100111100 // 3900 +0000111100111101 // 3901 +0000111100111110 // 3902 +0000111100111111 // 3903 +0000111101000000 // 3904 +0000111101000001 // 3905 +0000111101000010 // 3906 +0000111101000011 // 3907 +0000111101000100 // 3908 +0000111101000101 // 3909 +0000111101000110 // 3910 +0000111101000111 // 3911 +0000111101001000 // 3912 +0000111101001001 // 3913 +0000111101001010 // 3914 +0000111101001011 // 3915 +0000111101001100 // 3916 +0000111101001101 // 3917 +0000111101001110 // 3918 +0000111101001111 // 3919 +0000111101010000 // 3920 +0000111101010001 // 3921 +0000111101010010 // 3922 +0000111101010011 // 3923 +0000111101010100 // 3924 +0000111101010101 // 3925 +0000111101010110 // 3926 +0000111101010111 // 3927 +0000111101011000 // 3928 +0000111101011001 // 3929 +0000111101011010 // 3930 +0000111101011011 // 3931 +0000111101011100 // 3932 +0000111101011101 // 3933 +0000111101011110 // 3934 +0000111101011111 // 3935 +0000111101100000 // 3936 +0000111101100001 // 3937 +0000111101100010 // 3938 +0000111101100011 // 3939 +0000111101100100 // 3940 +0000111101100101 // 3941 +0000111101100110 // 3942 +0000111101100111 // 3943 +0000111101101000 // 3944 +0000111101101001 // 3945 +0000111101101010 // 3946 +0000111101101011 // 3947 +0000111101101100 // 3948 +0000111101101101 // 3949 +0000111101101110 // 3950 +0000111101101111 // 3951 +0000111101110000 // 3952 +0000111101110001 // 3953 +0000111101110010 // 3954 +0000111101110011 // 3955 +0000111101110100 // 3956 +0000111101110101 // 3957 +0000111101110110 // 3958 +0000111101110111 // 3959 +0000111101111000 // 3960 +0000111101111001 // 3961 +0000111101111010 // 3962 +0000111101111011 // 3963 +0000111101111100 // 3964 +0000111101111101 // 3965 +0000111101111110 // 3966 +0000111101111111 // 3967 +0000111110000000 // 3968 +0000111110000001 // 3969 +0000111110000010 // 3970 +0000111110000011 // 3971 +0000111110000100 // 3972 +0000111110000101 // 3973 +0000111110000110 // 3974 +0000111110000111 // 3975 +0000111110001000 // 3976 +0000111110001001 // 3977 +0000111110001010 // 3978 +0000111110001011 // 3979 +0000111110001100 // 3980 +0000111110001101 // 3981 +0000111110001110 // 3982 +0000111110001111 // 3983 +0000111110010000 // 3984 +0000111110010001 // 3985 +0000111110010010 // 3986 +0000111110010011 // 3987 +0000111110010100 // 3988 +0000111110010101 // 3989 +0000111110010110 // 3990 +0000111110010111 // 3991 +0000111110011000 // 3992 +0000111110011001 // 3993 +0000111110011010 // 3994 +0000111110011011 // 3995 +0000111110011100 // 3996 +0000111110011101 // 3997 +0000111110011110 // 3998 +0000111110011111 // 3999 +0000111110100000 // 4000 +0000111110100001 // 4001 +0000111110100010 // 4002 +0000111110100011 // 4003 +0000111110100100 // 4004 +0000111110100101 // 4005 +0000111110100110 // 4006 +0000111110100111 // 4007 +0000111110101000 // 4008 +0000111110101001 // 4009 +0000111110101010 // 4010 +0000111110101011 // 4011 +0000111110101100 // 4012 +0000111110101101 // 4013 +0000111110101110 // 4014 +0000111110101111 // 4015 +0000111110110000 // 4016 +0000111110110001 // 4017 +0000111110110010 // 4018 +0000111110110011 // 4019 +0000111110110100 // 4020 +0000111110110101 // 4021 +0000111110110110 // 4022 +0000111110110111 // 4023 +0000111110111000 // 4024 +0000111110111001 // 4025 +0000111110111010 // 4026 +0000111110111011 // 4027 +0000111110111100 // 4028 +0000111110111101 // 4029 +0000111110111110 // 4030 +0000111110111111 // 4031 +0000111111000000 // 4032 +0000111111000001 // 4033 +0000111111000010 // 4034 +0000111111000011 // 4035 +0000111111000100 // 4036 +0000111111000101 // 4037 +0000111111000110 // 4038 +0000111111000111 // 4039 +0000111111001000 // 4040 +0000111111001001 // 4041 +0000111111001010 // 4042 +0000111111001011 // 4043 +0000111111001100 // 4044 +0000111111001101 // 4045 +0000111111001110 // 4046 +0000111111001111 // 4047 +0000111111010000 // 4048 +0000111111010001 // 4049 +0000111111010010 // 4050 +0000111111010011 // 4051 +0000111111010100 // 4052 +0000111111010101 // 4053 +0000111111010110 // 4054 +0000111111010111 // 4055 +0000111111011000 // 4056 +0000111111011001 // 4057 +0000111111011010 // 4058 +0000111111011011 // 4059 +0000111111011100 // 4060 +0000111111011101 // 4061 +0000111111011110 // 4062 +0000111111011111 // 4063 +0000111111100000 // 4064 +0000111111100001 // 4065 +0000111111100010 // 4066 +0000111111100011 // 4067 +0000111111100100 // 4068 +0000111111100101 // 4069 +0000111111100110 // 4070 +0000111111100111 // 4071 +0000111111101000 // 4072 +0000111111101001 // 4073 +0000111111101010 // 4074 +0000111111101011 // 4075 +0000111111101100 // 4076 +0000111111101101 // 4077 +0000111111101110 // 4078 +0000111111101111 // 4079 +0000111111110000 // 4080 +0000111111110001 // 4081 +0000111111110010 // 4082 +0000111111110011 // 4083 +0000111111110100 // 4084 +0000111111110101 // 4085 +0000111111110110 // 4086 +0000111111110111 // 4087 +0000111111111000 // 4088 +0000111111111001 // 4089 +0000111111111010 // 4090 +0000111111111011 // 4091 +0000111111111100 // 4092 +0000111111111101 // 4093 +0000111111111110 // 4094 +0000111111111111 // 4095 diff --git a/hw/efinix_fpga/ip/bram/init_hex.mem b/hw/efinix_fpga/ip/bram/init_hex.mem new file mode 100644 index 0000000..0afe336 --- /dev/null +++ b/hw/efinix_fpga/ip/bram/init_hex.mem @@ -0,0 +1,256 @@ +ea +4c +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 \ No newline at end of file diff --git a/hw/efinix_fpga/ip/bram/mem_config.txt b/hw/efinix_fpga/ip/bram/mem_config.txt new file mode 100644 index 0000000..f809bd5 --- /dev/null +++ b/hw/efinix_fpga/ip/bram/mem_config.txt @@ -0,0 +1 @@ +[0, 8, 8, 8, 8, 256, 256, 1, 8, 1, 1, [[8, 20, 2, 0, 0], [9, 10, 1, 0, 0], [10, 5, 1, 0, 0], [8, 16, 2, 0, 1], [9, 8, 1, 0, 1], [10, 4, 1, 0, 1], [11, 2, 1, 0, 1], [12, 1, 1, 0, 1]], 1, [[0, 0, 1, 0, 0]], [[0, 0, 7, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 8, 20, 8, 20]], [], [], [], [], [], [], [], []] \ No newline at end of file diff --git a/hw/efinix_fpga/super6502.peri.xml b/hw/efinix_fpga/super6502.peri.xml index 8f29f94..f375343 100644 --- a/hw/efinix_fpga/super6502.peri.xml +++ b/hw/efinix_fpga/super6502.peri.xml @@ -1,5 +1,5 @@ - + @@ -69,8 +69,8 @@ - - + + diff --git a/hw/efinix_fpga/super6502.sv b/hw/efinix_fpga/super6502.sv index 6cc9158..6cccb0a 100644 --- a/hw/efinix_fpga/super6502.sv +++ b/hw/efinix_fpga/super6502.sv @@ -15,16 +15,21 @@ module super6502 output logic cpu_nmib, output logic cpu_rdy, output logic cpu_resb, - output logic pll_cpu_reset + output logic pll_cpu_reset, + output logic cpu_phi2 ); assign pll_cpu_reset = '1; -assign cpu_data_oe = '0; +assign cpu_data_oe = {8{cpu_rwb}}; assign cpu_rdy = '1; assign cpu_irqb = '1; assign cpu_nmib = '1; +always @(posedge clk_2) begin + cpu_phi2 <= ~cpu_phi2; +end + always @(posedge clk_2) begin if (button_reset == '0) begin cpu_resb <= '0; @@ -36,4 +41,15 @@ always @(posedge clk_2) begin end end +efx_single_port_ram boot_rom( + .clk(clk_2), // clock input for one clock mode + .addr(cpu_addr[7:0]), // address input + .wclke('0), // Write clock-enable input + .byteen('0), // Byteen input + .we('0), // Write-enable input + + .re(cpu_rwb), // Read-enable input + .rdata(cpu_data_out) // Read data output +); + endmodule diff --git a/hw/efinix_fpga/super6502.xml b/hw/efinix_fpga/super6502.xml index c7dd20e..82a8b09 100644 --- a/hw/efinix_fpga/super6502.xml +++ b/hw/efinix_fpga/super6502.xml @@ -1,5 +1,5 @@ - + @@ -8,6 +8,11 @@ + + + + +