Skip to content

Commit

Permalink
Version 1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
tuhalf committed Jan 10, 2021
1 parent 2af9a79 commit fca7035
Show file tree
Hide file tree
Showing 23 changed files with 10,154 additions and 31,302 deletions.
Binary file added Bitstreams/Release.bit
Binary file not shown.
Binary file added Docs/ScreenShots/50ColorsTest.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/ScreenShots/R.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/ScreenShots/RandomMap.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/ScreenShots/TenColorsTest.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Docs/ScreenShots/ThreeColorsTest.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 47 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,47 @@
# SOMvhdl
SOM implementation on FPGA using VHDL

![](https://img.shields.io/github/stars/tuhalf/SOMvhdl.svg) ![](https://img.shields.io/github/forks/tuhalf/SOMvhdl.md.svg)![](https://img.shields.io/github/release/tuhalf/SOMvhdl.md.svg) ![](https://img.shields.io/github/issues/tuhalf/SOMvhdl.md.svg)
# SOMVhdl - Self Organizing Map Implementation On FPGA

A simple and scaleable Self Organizing Map implementation written in VHDL. Tested on ARTYA7-35T board.

##Tests
#### Test with 10 color inputs
![](https://github.com/tuhalf/SOMvhdl/Docs/ScreenShots/TenColorsTest.png)
#### Test with 50 color inputs
![](https://github.com/tuhalf/SOMvhdl/Docs/ScreenShots/50ColorsTest.png)

##Features
- Any number of data entries via serial interface. (Limit is set to 254 but can be changed)
- Results output via serial interface.
- Flexible iteration and specification counts and map sizes.
- Non-repetitive psudo random map generation with Attiny85 extention.
- Test button to get output before training.

##How To Use
#### Installation
You can use Pre-Generated Bitstreams, which are avalible in releases or can generate from source.
##### ! To generate random map to start, you have to connect a 6 bit random bit generator to JA pins. You can use an Attiny85 or an Arduino for this. The necesary codes are in /Tools/RandomInit_attiny85 folder.
To make sure random map generation works fine, uncomment the commented lines on getMap.py and press BTN1 while running the code. Random output looks something like that:
![](https://github.com/tuhalf/SOMvhdl/Docs/ScreenShots/RandomMap.png)

#### Training
To train inputs from CSV files, you can use the Python code in /Tools/getMap.py It reads the output from Train.csv and writes outputs to map.csv.
#### Visualization
For visualization, I used the idea from [Isidroc SOMcpp Project][1] Using his R script, you can easily visualize the generated map. You can find the script in /Tools/PlotColorMartix.R
![](https://github.com/tuhalf/SOMvhdl/Docs/ScreenShots/R.png)

##Implementation Summary
#### Timing
WNS | WHS
------------- | -------------
0,21 | 0,04
#### Place Design
| LUT | FF | BRAM | DSP | I/O | BUFG |
| ------------- | ------------- | ------------- | ------------- | ------------- | ------------- |
| 19,36 | 18,14 | 34,00 | 6,67 | 8,57 | 3,13 |
## To do
- Divide map into smaller parts to do parallel processing.

###End
[1]: https://github.com/isidroc/SOMcpp "Isidroc's SOMcpp project"
Binary file added Reports/PlaceDesign.xlsx
Binary file not shown.
Binary file added Reports/Timing.xlsx
Binary file not shown.
151 changes: 3 additions & 148 deletions SOMvhdl.srcs/sources_1/new/kmap.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,6 @@ entity kmap is
end kmap;

architecture Behavioral of kmap is
--type Specs is array(specCount-1 downto 0) of std_logic_vector (7 DOWNTO 0);
--type KMapT is array(0 to (MapHeight*MapHeight)) of STD_LOGIC_VECTOR((7*specCount)+(specCount-1) downto 0); --(n_bits(MapHeight-1)*2)-1
--signal KMap : KMapT;
--attribute ram_style: string;
--attribute ram_style of KMap : signal is "block";
signal outputT: STD_LOGIC_VECTOR((7*specCount)+(specCount-1) downto 0);
signal readyDRV: STD_LOGIC;
signal bmuReadyDRV: STD_LOGIC;
Expand All @@ -78,7 +73,6 @@ architecture Behavioral of kmap is
signal bestOfCores: bestVariables;
constant cycleCount: natural := ((MapHeight*MapHeight)/coresCount);
signal coresDone: std_logic;
--constant j: integer := 0;
signal init: STD_LOGIC;

type toStates is (readyy,set,sure,go);
Expand Down Expand Up @@ -204,9 +198,6 @@ ValueCur <= outputT;

----------Init--------------
InitP: process(clk)
--variable x,y:std_logic_vector(n_bits(MapHeight-1)-1 downto 0);
--variable comb: std_logic_vector((n_bits(MapHeight-1)*2)-1 downto 0);
--variable bestX,bestY,bestDist: natural;
variable comb: natural;
variable inpTemp: STD_LOGIC_VECTOR((7*specCount)+(specCount-1) downto 0);
variable kmapTemp: std_logic_vector(17 downto 0);
Expand All @@ -221,7 +212,6 @@ begin
bmuReadyDRV<='0';

readyDRV<='0';
--kmap<= (others=>(others=>(others=>(others=>'0'))));
xCP<= 0;
yCP<= 0;
init <= '1';
Expand Down Expand Up @@ -289,10 +279,7 @@ begin

if init = '1' and RandReady = '1' then
if not(yCP = MapHeight-1) then
--set
--x:= std_logic_vector(to_unsigned(xCP,n_bits(MapHeight-1)));
--y:= std_logic_vector(to_unsigned(yCP,n_bits(MapHeight-1)));
--comb:= x&y;
--set
comb:= (xCP*MapHeight)+(yCP);
wea(0) <= '1';
addra<= std_logic_vector(to_unsigned(comb,14));
Expand All @@ -301,9 +288,7 @@ begin
yCP <= yCP + 1;
elsif ycp = MapHeight-1 and not(xCP = MapHeight-1) then
--set
--x:= std_logic_vector(to_unsigned(xCP,n_bits(MapHeight-1)));
--y:= std_logic_vector(to_unsigned(yCP,n_bits(MapHeight-1)));
--comb:= x&y;

comb:= (xCP*MapHeight)+(yCP);
wea(0) <= '1';
addra<= std_logic_vector(to_unsigned(comb,14));
Expand All @@ -313,9 +298,7 @@ begin
yCP <= 0;
elsif ycp = MapHeight-1 and xCP = MapHeight-1 then
--sth
--x:= std_logic_vector(to_unsigned(xCP,n_bits(MapHeight-1)));
--y:= std_logic_vector(to_unsigned(yCP,n_bits(MapHeight-1)));
--comb:= x&y;

comb:= (xCP*MapHeight)+(yCP);
wea(0) <= '1';
addra<= std_logic_vector(to_unsigned(comb,14));
Expand Down Expand Up @@ -441,9 +424,6 @@ begin
elsif getOut ='1' and outReadyDRV = '0' then
trainDoneM <= '0';
wea(0) <= '0';
--x:= std_logic_vector(to_unsigned(XPos_O,n_bits(MapHeight-1)));
--y:= std_logic_vector(to_unsigned(YPos_O,n_bits(MapHeight-1)));
--comb:= x&y;
case readTO is
when readyy =>
outReadyDRV<= '0';
Expand Down Expand Up @@ -557,129 +537,4 @@ ready<=readyDRV;
outReady <= outReadyDRV;
bmuReady<=bmuReadyDRV;

---------Train---------
--trainP: process(clk)
-- variable kmapTemp: std_logic_vector(17 downto 0);
-- variable kmapT: STD_LOGIC_VECTOR((7*specCount)+(specCount-1) downto 0);
-- variable kmapP: STD_LOGIC_VECTOR((7*specCount)+(specCount-1) downto 0);
-- variable x,y:std_logic_vector(n_bits(MapHeight-1)-1 downto 0);
-- variable comb: std_logic_vector((n_bits(MapHeight-1)*2)-1 downto 0);
--begin
-- if rising_edge(clk) then
-- if train = '1' and init = '0' and FindBMU ='0'then
-- kmapP:= KMap(to_integer(unsigned(comb)));
-- for k in 0 to specCount-1 loop
-- x:= std_logic_vector(to_unsigned(XPos,n_bits(MapHeight-1)));
-- y:= std_logic_vector(to_unsigned(YPos,n_bits(MapHeight-1)));
-- comb:= x&y;
-- kmapTemp:= std_logic_vector(unsigned(kmapP ((7+(k*8)) downto (0+(k*8)))) + ((LNRate*(unsigned(input((7+(k*8)) downto (0+(k*8)))) - unsigned(kmapP((7+(k*8)) downto (0+(k*8))))))/to_unsigned(rateSensetivity,n_bits(rateSensetivity))));
-- kmapT((7+(k*8)) downto (0+(k*8))) := kmapTemp(17 downto 10);
-- end loop;
-- kmap(to_integer(unsigned(comb))) <= kmapT;
-- end if;
-- end if;
--end process trainP;

------- BMU ------------
--bmuF: process(clk, rst)
-- variable bx,by: natural;
-- variable distance,best_distance: natural;
-- variable inputIn: STD_LOGIC_VECTOR((7*specCount)+(specCount-1) downto 0);
--
--begin
-- if rst = '1' then
--
-- elsif rising_edge(clk) then
-- if FindBMU ='1' then
-- best_distance := specCount * 255;
-- bx := 0;
-- by := 0;
-- inputIn:= input;
-- for cx in 0 to MapHeight-1 loop
-- for cy in 0 to MapHeight-1 loop
-- distance:= 0;
-- for cs in 0 to specCount-1 loop
-- distance := distance + abs(to_integer(unsigned(inputIn((7+(cs*8)) downto (0+(cs*8))))) - to_integer(unsigned(KMap(cx,cy) (cs))));
-- end loop;
-- if distance<best_distance then
-- best_distance := distance;
-- bx := cx;
-- by := cy;
-- end if;
-- end loop;
-- end loop;
-- bmuX <= bx;
-- bmuY <= by;
-- end if;
-- end if;
--end process bmuF;

--cores: for j in 0 to coresCount-1 generate
-- core: process(clk, rst)
-- --variable x,y:std_logic_vector(n_bits(MapHeight-1)-1 downto 0);
-- variable kmapT: STD_LOGIC_VECTOR((7*specCount)+(specCount-1) downto 0);
-- --variable comb: std_logic_vector((n_bits(MapHeight-1)*2)-1 downto 0);
-- variable comb: natural;
-- variable distance: natural;
-- begin
-- if rst = '1' then
-- bestOfCores(j)<= (others => 0);
-- coresDone(j)<='0';
-- elsif rising_edge(clk) then
-- if bmuReadyDRV = '1' then
-- coresDone(j)<= '0';
-- bestOfCores(j)<= (others => 0);
-- elsif FindBMU ='1' and train='0' and init = '0' then
-- if bestOfCores(j)(3)<cycleCount and coresDone(j) = '0' then
-- distance:= 0;
-- comb:= ((bestOfCores(j)(3)/MapHeight)*MapHeight)+((bestOfCores(j)(3) rem MapHeight));
-- kmapT:= KMap(comb);
-- for cs in 0 to specCount-1 loop
-- --x:= std_logic_vector(to_unsigned((bestOfCores(j)(3)/MapHeight),n_bits(MapHeight-1)));
-- --y:= std_logic_vector(to_unsigned((bestOfCores(j)(3) rem MapHeight),n_bits(MapHeight-1)));
-- --comb:= x&y;
-- distance := distance + abs(to_integer(unsigned(input((7+(cs*8)) downto (0+(cs*8))))) - to_integer(unsigned(kmapT((7+(cs*8)) downto (0+(cs*8))))));
-- end loop;
-- if distance<bestOfCores(j)(2) or bestOfCores(j)(3)=0 then
-- bestOfCores(j)(2) <= distance;
-- bestOfCores(j)(1) <= (bestOfCores(j)(3)/MapHeight);
-- bestOfCores(j)(0) <= (bestOfCores(j)(3) rem MapHeight);
-- end if;
-- bestOfCores(j)(3) <= bestOfCores(j)(3) +1;
-- else
-- coresDone(j)<='1';
-- end if;
-- end if;
-- end if;
-- end process core;
--end generate cores;
--
-- mestO: process(clk, rst)
-- variable bestX,bestY,bestDist: natural;
-- begin
-- if rst = '1' then
-- bestX := 0;
-- bestY := 0;
-- bestDist := 0;
-- bmuX<= 0;
-- bmuY<= 0;
-- elsif rising_edge(clk) then
-- if signed(coresDone) = to_signed(-1, coresDone'length) and FindBMU ='1' and train='0' and init = '0' then
-- bestX := 0;
-- bestY := 0;
-- bestDist := 0;
-- for o in 0 to coresCount-1 loop
-- if bestOfCores(o)(2) <= bestDist then
-- bestX:=bestOfCores(o)(0);
-- bestY:=bestOfCores(o)(1);
-- bestDist:=bestOfCores(o)(2);
-- end if;
-- end loop;
-- bmuX<=bestX;
-- bmuY<=bestY;
-- bmuReadyDRV<='1';
-- end if;
-- end if;
-- end process mestO;

end Behavioral;
3 changes: 3 additions & 0 deletions SOMvhdl.xpr
Original file line number Diff line number Diff line change
Expand Up @@ -380,14 +380,17 @@
</Gadget>
<Gadget Name="timing_1" Type="timing" Version="1" Row="0" Column="1">
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_route_report_timing_summary_0 "/>
<GadgetParam Name="VIEW.TYPE" Type="string" Value="table"/>
</Gadget>
<Gadget Name="utilization_1" Type="utilization" Version="1" Row="0" Column="0">
<GadgetParam Name="REPORTS" Type="string_list" Value="synth_1#synth_1_synth_report_utilization_0 "/>
<GadgetParam Name="RUN.STEP" Type="string" Value="synth_design"/>
<GadgetParam Name="RUN.TYPE" Type="string" Value="synthesis"/>
<GadgetParam Name="VIEW.TYPE" Type="string" Value="graph"/>
</Gadget>
<Gadget Name="utilization_2" Type="utilization" Version="1" Row="1" Column="1">
<GadgetParam Name="REPORTS" Type="string_list" Value="impl_1#impl_1_place_report_utilization_0 "/>
<GadgetParam Name="VIEW.TYPE" Type="string" Value="table"/>
</Gadget>
</Gadgets>
</Dashboard>
Expand Down
Loading

0 comments on commit fca7035

Please sign in to comment.