URL
https://opencores.org/ocsvn/popcount_gen/popcount_gen/trunk
Subversion Repositories popcount_gen
Compare Revisions
- This comparison shows the changes necessary to convert path
/popcount_gen
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/trunk/FPGA_MaxPars_Gen.c
0,0 → 1,933
/* FPGA_MaxPars (version 1.0) A program to generate VHDL wrapper files |
* for the computational kernel of the Maximum Parsinomy FPGA Architecture. |
* |
* Copyright March 2011 by Nikolaos Ch. Alachiotis |
* |
* This program is free software; you may redistribute it and/or modify its |
* under the terms of the GNU General Public License as published by the Free |
* Software Foundation; either version 2 of the License, or (at your option) |
* any later version. |
* |
* This program is distributed in the hope that it will be useful, but |
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
* for more details. |
* |
* The wrapper files generated by the FPGA_MaxPars as well as all the other |
* VHDL files that form the implementation of the Maximum Parsimony FPGA |
* Architecture can be used under the terms of the GNU General Public License. |
* |
* Furthermore, the POPCOUNT component, which solves the population count problem |
* by generating a pipelined tree of adders, might as well be used outside the |
* context of the Maximum Parsimony FPGA Architecture under the terms of the |
* GNU Lesser General Public License. |
* |
* The POPCOUNT module is vendor and device independent. |
* |
* For any other enquiries send an Email to Nikolaos Alachiotis |
* n.alachiotis@gmail.com |
*/ |
|
|
#include<stdio.h> |
#include<stdlib.h> |
|
#define SIZE_MODE 0 |
#define CONFIG_MODE 1 |
#define CREATE_MODE 2 |
|
FILE * ADDER_FP; |
FILE * MPPRU_FP; |
FILE * TOP_FP; |
|
int INPUT_LOAD; |
int ADDER_LOAD; |
int SIGNAL_LOAD; |
int MAX_CODE; |
int PPC_SIZE; |
int LATENCY; |
|
int BITVEC_INDEX; |
int inputbitvector[16]; |
int * registerpositions; |
|
typedef struct{ |
|
int inst_sz; |
int inst_ind; |
int inpA_num; |
int inpB_num; |
int outC_num; |
|
}adder_config; |
|
adder_config * ADD_CONFIG; |
int ADD_CONFIG_IND; |
|
typedef struct{ |
|
int type; |
int code; |
int size; |
|
}signal_config; |
|
void getbitvector(int input) |
{ |
int i=0; |
int div=0; |
int mod=0; |
|
for(i=0;i<16;i++) |
{ |
inputbitvector[i]=0; |
} |
|
div = input; |
|
i=15; |
|
while(div!=0) |
{ |
mod = div%2; |
div = div/2; |
inputbitvector[i--]=mod; |
|
} |
|
fprintf(TOP_FP,"\ncurSIZE <= \""); |
for(i=0;i<16;i++) |
{ |
fprintf(TOP_FP, "%d",inputbitvector[i]); |
} |
fprintf(TOP_FP,"\";\n"); |
} |
|
signal_config * SIG_CONFIG; |
int SIG_CONFIG_IND; |
|
int connect_input(int load, int MODE) |
{ |
int i; |
|
for(i=load-1;i>-1;i--) |
{ |
if(MODE==SIZE_MODE) |
{ |
SIGNAL_LOAD+=2; |
} |
if(MODE==CONFIG_MODE) |
{ |
SIG_CONFIG[SIG_CONFIG_IND].type=1; |
SIG_CONFIG[SIG_CONFIG_IND].code=1; |
SIG_CONFIG[SIG_CONFIG_IND].size=i; |
SIG_CONFIG_IND++; |
SIG_CONFIG[SIG_CONFIG_IND].type=3; |
SIG_CONFIG[SIG_CONFIG_IND].code=1; |
SIG_CONFIG[SIG_CONFIG_IND].size=i; |
SIG_CONFIG_IND++; |
} |
} |
return load; |
} |
|
int connect_output_to_input_next(int pos, int load, int MODE) |
{ |
int i; |
for(i=load-1;i>-1;i--) |
{ |
if(MODE==SIZE_MODE) |
{ |
SIGNAL_LOAD += 3; |
} |
if(MODE==CONFIG_MODE) |
{ |
SIG_CONFIG[SIG_CONFIG_IND].type=1; |
SIG_CONFIG[SIG_CONFIG_IND].code=pos; |
SIG_CONFIG[SIG_CONFIG_IND].size=i; |
SIG_CONFIG_IND++; |
SIG_CONFIG[SIG_CONFIG_IND].type=2; |
SIG_CONFIG[SIG_CONFIG_IND].code=pos-1; |
SIG_CONFIG[SIG_CONFIG_IND].size=i; |
SIG_CONFIG_IND++; |
SIG_CONFIG[SIG_CONFIG_IND].type=4; |
SIG_CONFIG[SIG_CONFIG_IND].code=pos; |
SIG_CONFIG[SIG_CONFIG_IND].size=i; |
SIG_CONFIG_IND++; |
|
} |
if(MODE==CREATE_MODE) |
{ |
fprintf(ADDER_FP,"INPUT_%d_%d <= OUTPUT_%d_%d;\n",pos,i,pos-1,i); |
} |
|
} |
} |
|
int adder_line(int line_pos, int load, int arg, int MODE) |
{ |
int next_load=0, i, i_init, i_last, sig_arg_ind; |
|
if(arg==1) |
{ |
sig_arg_ind = load * 2; |
i_init = load; |
i_last = 0; |
} |
else |
{ |
sig_arg_ind = load * 2-1; |
i_init = load-1; |
i_last = -1; |
} |
|
for(i=i_init;i>i_last;i--) |
{ |
if(MODE==SIZE_MODE) |
{ |
ADDER_LOAD++; |
} |
if(MODE==CONFIG_MODE) |
{ |
ADD_CONFIG[ADD_CONFIG_IND].inst_sz=line_pos; |
if(ADD_CONFIG[ADD_CONFIG_IND].inst_sz>MAX_CODE) |
{ |
MAX_CODE = ADD_CONFIG[ADD_CONFIG_IND].inst_sz; |
} |
ADD_CONFIG[ADD_CONFIG_IND].inst_ind=i; |
ADD_CONFIG[ADD_CONFIG_IND].inpA_num=sig_arg_ind--; |
ADD_CONFIG[ADD_CONFIG_IND].inpB_num=sig_arg_ind--; |
ADD_CONFIG[ADD_CONFIG_IND].outC_num=i; |
ADD_CONFIG_IND++; |
|
|
} |
if(MODE==CREATE_MODE) |
{ |
fprintf(ADDER_FP,"ADD_%d_INST_%d: ADD_%d Port Map\n",line_pos,i,line_pos); |
fprintf(ADDER_FP,"(\n"); |
fprintf(ADDER_FP," ADD_%d_IN_A => INPUT_%d_%d,\n",line_pos,line_pos,sig_arg_ind--); |
fprintf(ADDER_FP," ADD_%d_IN_B => INPUT_%d_%d,\n",line_pos,line_pos,sig_arg_ind--); |
fprintf(ADDER_FP," ADD_%d_OUT => OUTPUT_%d_%d\n",line_pos,line_pos,i); |
fprintf(ADDER_FP,");\n"); |
} |
next_load++; |
} |
|
if(arg==1) |
{ |
if(MODE==SIZE_MODE) |
{ |
SIGNAL_LOAD++; |
} |
if(MODE==CONFIG_MODE) |
{ |
SIG_CONFIG[SIG_CONFIG_IND].type=5; |
SIG_CONFIG[SIG_CONFIG_IND].code=line_pos; |
SIG_CONFIG[SIG_CONFIG_IND].size=0; |
SIG_CONFIG_IND++; |
|
|
} |
if(MODE==CREATE_MODE) |
{ |
fprintf(ADDER_FP,"OUTPUT_%d_0 <= INPUT_%d_0;\n",line_pos,line_pos); |
} |
|
next_load++; |
|
} |
return next_load; |
} |
|
int calc_line_load(int load) |
{ |
return load/2; |
} |
int calc_line_arrangement(int load) |
{ |
if((load%2)==0) |
{ |
return 2; |
} |
else |
{ |
return 1; |
} |
} |
|
void connect_toplevel_input() |
{ |
int i; |
for (i=0;i<SIGNAL_LOAD;i++) |
{ |
if(SIG_CONFIG[i].type==3) |
{ |
fprintf(ADDER_FP,"INPUT_%d_%d(0) <= invec(%d);\n",SIG_CONFIG[i].code,SIG_CONFIG[i].size,SIG_CONFIG[i].size); |
} |
} |
} |
|
void create_signals() |
{ |
int i; |
fprintf(ADDER_FP,"\n\n"); |
for (i=0;i<SIGNAL_LOAD;i++) |
{ |
if(SIG_CONFIG[i].type==1 && SIG_CONFIG[i].code<=MAX_CODE) |
{ |
fprintf(ADDER_FP,"signal INPUT_%d_%d : std_logic_vector(%d downto 0);\n",SIG_CONFIG[i].code,SIG_CONFIG[i].size,SIG_CONFIG[i].code-1); |
} |
if(SIG_CONFIG[i].type==2 && SIG_CONFIG[i].code<=MAX_CODE) |
{ |
fprintf(ADDER_FP,"signal OUTPUT_%d_%d : std_logic_vector(%d downto 0);\n",SIG_CONFIG[i].code,SIG_CONFIG[i].size,SIG_CONFIG[i].code); |
} |
} |
} |
|
void instantiate_adders() |
{ |
int i; |
fprintf(ADDER_FP,"\n\n"); |
for (i=0;i<ADDER_LOAD;i++) |
{ |
fprintf(ADDER_FP,"ADD_%d_INST_%d: ADD_%d Port Map\n",ADD_CONFIG[i].inst_sz,ADD_CONFIG[i].inst_ind,ADD_CONFIG[i].inst_sz); |
fprintf(ADDER_FP,"(\n"); |
fprintf(ADDER_FP," ADD_%d_IN_A => INPUT_%d_%d,\n",ADD_CONFIG[i].inst_sz,ADD_CONFIG[i].inst_sz,ADD_CONFIG[i].inpA_num); |
fprintf(ADDER_FP," ADD_%d_IN_B => INPUT_%d_%d,\n",ADD_CONFIG[i].inst_sz,ADD_CONFIG[i].inst_sz,ADD_CONFIG[i].inpB_num); |
fprintf(ADDER_FP," ADD_%d_OUT => OUTPUT_%d_%d\n",ADD_CONFIG[i].inst_sz,ADD_CONFIG[i].inst_sz,ADD_CONFIG[i].outC_num); |
fprintf(ADDER_FP,");\n"); |
} |
for(i=0;i<SIGNAL_LOAD;i++) |
{ |
if(SIG_CONFIG[i].type==5) |
{ |
fprintf(ADDER_FP,"OUTPUT_%d_0(%d) <= '0';\n",SIG_CONFIG[i].code,SIG_CONFIG[i].code); |
fprintf(ADDER_FP,"OUTPUT_%d_0(%d downto 0) <= INPUT_%d_0;\n",SIG_CONFIG[i].code,SIG_CONFIG[i].code-1,SIG_CONFIG[i].code); |
} |
} |
} |
|
void make_interconnections() |
{ |
int i, registered, regindex; |
fprintf(ADDER_FP,"\n\n"); |
registered=0; |
regindex=0; |
|
for (i=0;i<SIGNAL_LOAD;i++) |
{ |
if(SIG_CONFIG[i].type==4) |
{ |
if(SIG_CONFIG[i].code!=MAX_CODE+1) |
{ |
if(SIG_CONFIG[i].code==registerpositions[regindex]+1) |
{ |
if (registered==0) |
{ |
fprintf(ADDER_FP,"\nprocess(clk)\nbegin\nif clk'event and clk='1' then\n\n"); |
registered=1; |
} |
} |
|
if(SIG_CONFIG[i].code!=registerpositions[regindex]+1) |
{ |
if(registered==1) |
{ |
fprintf(ADDER_FP,"\nend if;\nend process;\n\n"); |
registered=0; |
regindex++; |
} |
} |
|
if(registered==1) |
{ |
fprintf(ADDER_FP,"\t"); |
} |
|
fprintf(ADDER_FP,"INPUT_%d_%d <= OUTPUT_%d_%d;\n",SIG_CONFIG[i].code,SIG_CONFIG[i].size,SIG_CONFIG[i].code-1,SIG_CONFIG[i].size); |
|
if((SIG_CONFIG[i].code==registerpositions[regindex]+1) && SIG_CONFIG[i].size==0) |
{ |
if(registered==1) |
{ |
fprintf(ADDER_FP,"\nend if;\nend process;\n\n"); |
registered=0; |
regindex++; |
} |
} |
} |
else |
{ |
fprintf(ADDER_FP,"\n\n"); |
fprintf(ADDER_FP,"process(clk)\nbegin\nif clk'event and clk='1' then\n",SIG_CONFIG[i].code); |
fprintf(ADDER_FP," value(31 downto %d)<= (others=>'0');\n",SIG_CONFIG[i].code); |
fprintf(ADDER_FP," value(%d downto 0)<= OUTPUT_%d_%d;\nend if;\nend process;",SIG_CONFIG[i].code-1,SIG_CONFIG[i].code-1,SIG_CONFIG[i].size); |
fprintf(ADDER_FP,"\n\nend Behavioral;"); |
} |
} |
} |
} |
|
void component_short_ADDER(int size, FILE * fp) |
{ |
fprintf(ADDER_FP,"\n\n"); |
fprintf(ADDER_FP,"component ADD_%d is\n",size); |
fprintf(ADDER_FP,"Port ( ADD_%d_IN_A: in STD_LOGIC_VECTOR(%d downto 0);\n",size,size-1); |
fprintf(ADDER_FP," ADD_%d_IN_B: in STD_LOGIC_VECTOR(%d downto 0);\n",size,size-1); |
fprintf(ADDER_FP," ADD_%d_OUT : out STD_LOGIC_VECTOR(%d downto 0)\n",size,size); |
fprintf(ADDER_FP,");\n"); |
fprintf(ADDER_FP,"end component;\n"); |
} |
|
void processADDER(int MODE) |
{ |
int line_load, line_load_next, line_arg, line_pos=0, i; |
|
if(MODE==SIZE_MODE) |
{ |
ADDER_LOAD=0; |
SIGNAL_LOAD=0; |
MAX_CODE = -1; |
} |
|
if(MODE==SIZE_MODE || MODE==CONFIG_MODE) |
{ |
connect_input(INPUT_LOAD,MODE); |
|
line_load_next = INPUT_LOAD; |
|
while(line_load_next!=1) |
{ |
line_pos ++; |
line_load=calc_line_load(line_load_next); |
line_arg= calc_line_arrangement(line_load_next); |
line_load_next = adder_line(line_pos,line_load, line_arg, MODE); |
connect_output_to_input_next(line_pos+1, line_load_next,MODE); |
} |
} |
else |
{ |
create_signals(); |
|
for(i=1;i<MAX_CODE+1;i++) |
{ |
component_short_ADDER(i, ADDER_FP); |
} |
|
fprintf(ADDER_FP,"\n\nbegin\n\n"); |
|
connect_toplevel_input(); |
|
instantiate_adders(); |
|
make_interconnections(); |
|
} |
} |
|
void preliminary_input(FILE *fp) |
{ |
fprintf(fp,"------------------------------------------------\n"); |
fprintf(fp,"-- Copyright (C) 2010 Nikolaos Ch. Alachiotis --\n"); |
fprintf(fp,"-- Contact: n.alachiotis@gmail.com --\n"); |
fprintf(fp,"-- Details: This file has been generated by --\n"); |
fprintf(fp,"-- the FPGA_MaxPars program. --\n"); |
fprintf(fp,"------------------------------------------------\n"); |
} |
|
void libraries(FILE * fp) |
{ |
fprintf(fp,"\n\n"); |
fprintf(fp,"library IEEE;\n"); |
fprintf(fp,"use IEEE.STD_LOGIC_1164.ALL;\n"); |
fprintf(fp,"use IEEE.STD_LOGIC_ARITH.ALL;\n"); |
fprintf(fp,"use IEEE.STD_LOGIC_UNSIGNED.ALL;\n"); |
|
} |
|
void entityADDER() |
{ |
fprintf(ADDER_FP,"\n\n"); |
fprintf(ADDER_FP,"entity POPCOUNT is\n"); |
fprintf(ADDER_FP,"Port ( clk : in STD_LOGIC;\n"); |
fprintf(ADDER_FP," invec : in STD_LOGIC_VECTOR(%d downto 0);\n",INPUT_LOAD-1); |
fprintf(ADDER_FP," value : out STD_LOGIC_VECTOR(31 downto 0)\n"); |
fprintf(ADDER_FP,");\n"); |
fprintf(ADDER_FP,"end POPCOUNT;\n"); |
|
} |
|
void start_architectureADDER() |
{ |
fprintf(ADDER_FP,"\n\n"); |
fprintf(ADDER_FP,"architecture Behavioral of POPCOUNT is\n"); |
} |
|
void entity_short_ADDER(int size, FILE *fp) |
{ |
fprintf(ADDER_FP,"\n\n"); |
fprintf(ADDER_FP,"entity ADD_%d is\n",size); |
fprintf(ADDER_FP,"Port ( ADD_%d_IN_A: in STD_LOGIC_VECTOR(%d downto 0);\n",size,size-1); |
fprintf(ADDER_FP," ADD_%d_IN_B: in STD_LOGIC_VECTOR(%d downto 0);\n",size,size-1); |
fprintf(ADDER_FP," ADD_%d_OUT : out STD_LOGIC_VECTOR(%d downto 0)\n",size,size); |
fprintf(ADDER_FP,");\n"); |
fprintf(ADDER_FP,"end ADD_%d;\n",size); |
|
|
} |
|
void start_architecture_short_ADDER(int size, FILE *fp) |
{ |
fprintf(fp,"\n\n"); |
fprintf(fp,"architecture Behavioral of ADD_%d is\n",size); |
} |
void finish_architecture_short_ADDER(int size, FILE * fp) |
{ |
fprintf(fp,"\nsignal tinput_A : std_logic_vector(%d downto 0);\n",size); |
fprintf(fp,"signal tinput_B : std_logic_vector(%d downto 0);\n",size); |
fprintf(fp,"signal toutput : std_logic_vector(%d downto 0);\n",size); |
|
fprintf(fp,"\nbegin\n\n"); |
|
fprintf(fp,"tinput_A(%d)<='0';\ntinput_A(%d downto 0) <= ADD_%d_IN_A;\n",size,size-1,size); |
fprintf(fp,"tinput_B(%d)<='0';\ntinput_B(%d downto 0) <= ADD_%d_IN_B;\n",size,size-1,size); |
fprintf(fp,"toutput <= tinput_A + tinput_B;\n",size); |
|
fprintf(fp,"ADD_%d_OUT <= toutput;\n",size); |
fprintf(fp,"\nend Behavioral;\n"); |
|
} |
|
void create_short_adder(int size, FILE * fp) |
{ |
libraries(fp); |
entity_short_ADDER(size,fp); |
start_architecture_short_ADDER(size,fp); |
finish_architecture_short_ADDER(size,fp); |
} |
|
|
void entityPPC() |
{ |
fprintf(MPPRU_FP,"\n\n"); |
fprintf(MPPRU_FP,"entity PPC is\n"); |
fprintf(MPPRU_FP,"Port ( clk : in STD_LOGIC;\n\n"); |
|
fprintf(MPPRU_FP," tip_addr : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(MPPRU_FP," tip_we : in STD_LOGIC_VECTOR(0 downto 0);\n"); |
fprintf(MPPRU_FP," tip_din : in STD_LOGIC_VECTOR(7 downto 0);\n"); |
fprintf(MPPRU_FP," tip_we_nxt : out STD_LOGIC_VECTOR(0 downto 0);\n\n"); |
|
fprintf(MPPRU_FP," sel_vec : in STD_LOGIC_VECTOR(2 downto 0);\n"); |
fprintf(MPPRU_FP," addrA : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(MPPRU_FP," addrB : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(MPPRU_FP," addrC : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(MPPRU_FP," addrD : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(MPPRU_FP," WRCNTRL : in STD_LOGIC_VECTOR(13 downto 0);\n"); |
fprintf(MPPRU_FP," POPCOUNTvector : out STD_LOGIC_VECTOR(%d downto 0)\n",INPUT_LOAD-1); |
fprintf(MPPRU_FP,");\n"); |
fprintf(MPPRU_FP,"end PPC;\n"); |
} |
|
void start_architecturePPC() |
{ |
fprintf(MPPRU_FP,"\n\n"); |
fprintf(MPPRU_FP,"architecture Behavioral of PPC is\n"); |
} |
|
void componentPRU() |
{ |
fprintf(MPPRU_FP,"\n\n"); |
fprintf(MPPRU_FP,"component PRU_TOP is\n"); |
fprintf(MPPRU_FP," port (\n"); |
fprintf(MPPRU_FP," clk : in STD_LOGIC;\n"); |
fprintf(MPPRU_FP," tip_addr : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(MPPRU_FP," tip_we : in STD_LOGIC_VECTOR(0 downto 0);\n"); |
fprintf(MPPRU_FP," tip_din : in STD_LOGIC_VECTOR(7 downto 0);\n"); |
fprintf(MPPRU_FP," tip_we_nxt : out STD_LOGIC_VECTOR(0 downto 0);\n"); |
fprintf(MPPRU_FP," sel_vec : in STD_LOGIC_VECTOR(2 downto 0);\n"); |
fprintf(MPPRU_FP," addrA : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(MPPRU_FP," addrB : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(MPPRU_FP," addrC : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(MPPRU_FP," addrD : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(MPPRU_FP," WRCNTRL : in STD_LOGIC_VECTOR(13 downto 0);\n"); |
fprintf(MPPRU_FP," countBITs : out STD_LOGIC_VECTOR(1 downto 0)\n"); |
fprintf(MPPRU_FP," );\n"); |
fprintf(MPPRU_FP,"end component;\n"); |
|
} |
|
void instantiatePRU(int index) |
{ |
fprintf(MPPRU_FP,"\n-----------------------\n"); |
fprintf(MPPRU_FP,"-- Processing Unit %d --\n",index); |
fprintf(MPPRU_FP,"-----------------------\n"); |
fprintf(MPPRU_FP,"PRU_INST_%d: PRU_TOP Port Map\n", index); |
fprintf(MPPRU_FP,"(\n"); |
fprintf(MPPRU_FP," clk => clk,\n"); |
fprintf(MPPRU_FP," tip_addr => tip_addr,\n"); |
fprintf(MPPRU_FP," tip_we => tip_we_%d,\n",index); |
fprintf(MPPRU_FP," tip_din => tip_din,\n"); |
if(index==PPC_SIZE) |
{ |
fprintf(MPPRU_FP," tip_we_nxt => open,\n"); |
} |
else |
{ |
fprintf(MPPRU_FP," tip_we_nxt => tip_we_%d,\n",index+1); |
} |
fprintf(MPPRU_FP," sel_vec => sel_vec,\n"); |
fprintf(MPPRU_FP," addrA => addrA,\n"); |
fprintf(MPPRU_FP," addrB => addrB,\n"); |
fprintf(MPPRU_FP," addrC => addrC,\n"); |
fprintf(MPPRU_FP," addrD => addrD,\n"); |
fprintf(MPPRU_FP," WRCNTRL => WRCNTRL,\n"); |
fprintf(MPPRU_FP," countBITs => POPCOUNTvector(%d downto %d)\n", BITVEC_INDEX, BITVEC_INDEX-1); |
fprintf(MPPRU_FP,");\n"); |
|
BITVEC_INDEX = BITVEC_INDEX - 2; |
} |
|
void signalsPPC() |
{ |
int i=0; |
|
fprintf(MPPRU_FP,"\n"); |
|
for(i=1;i<=PPC_SIZE;i++) |
{ |
fprintf(MPPRU_FP,"signal tip_we_%d: std_logic_vector(0 downto 0);\n",i); |
} |
|
fprintf(MPPRU_FP,"\nbegin\n"); |
|
fprintf(MPPRU_FP,"\ntip_we_1 <= tip_we;\n"); |
|
} |
|
void end_file(FILE *fp) |
{ |
fprintf(fp,"\n\nend Behavioral;\n"); |
} |
|
|
void entityMPEXT() |
{ |
fprintf(TOP_FP,"\n\n"); |
fprintf(TOP_FP,"entity MPEXT is\n"); |
fprintf(TOP_FP,"Port ( clk : in STD_LOGIC;\n\n"); |
fprintf(TOP_FP," curSIZE : out STD_LOGIC_VECTOR(15 downto 0);\n\n"); |
|
fprintf(TOP_FP," tip_addr : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(TOP_FP," tip_we : in STD_LOGIC_VECTOR(0 downto 0);\n"); |
fprintf(TOP_FP," tip_din : in STD_LOGIC_VECTOR(7 downto 0);\n"); |
fprintf(TOP_FP," sel_vec : in STD_LOGIC_VECTOR(2 downto 0);\n"); |
fprintf(TOP_FP," addrA : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(TOP_FP," addrB : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(TOP_FP," addrC : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(TOP_FP," addrD : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(TOP_FP," WRCNTRL : in STD_LOGIC_VECTOR(13 downto 0);\n"); |
fprintf(TOP_FP," POPCOUNT_val : out STD_LOGIC_VECTOR(31 downto 0);\n\n"); |
fprintf(TOP_FP," score_rdaddr : in STD_LOGIC_VECTOR(15 downto 0);\n"); |
fprintf(TOP_FP," score_rddout : out STD_LOGIC_VECTOR(31 downto 0);\n"); |
fprintf(TOP_FP," score3_we : in STD_LOGIC_VECTOR(0 downto 0);\n"); |
fprintf(TOP_FP," score3_addr : in STD_LOGIC_VECTOR(15 downto 0);\n"); |
fprintf(TOP_FP," score3_din : in STD_LOGIC_VECTOR(31 downto 0);\n\n"); |
fprintf(TOP_FP," sync_in : in STD_LOGIC;\n"); |
fprintf(TOP_FP," sync_out : out STD_LOGIC\n"); |
fprintf(TOP_FP,");\n"); |
fprintf(TOP_FP,"end MPEXT;\n"); |
|
} |
|
void start_architectureMPEXT() |
{ |
fprintf(TOP_FP,"\n\n"); |
fprintf(TOP_FP,"architecture Behavioral of MPEXT is\n"); |
} |
|
void componentPPC() |
{ |
fprintf(TOP_FP,"\n\n"); |
fprintf(TOP_FP,"component PPC is\n"); |
fprintf(TOP_FP,"Port ( clk : in STD_LOGIC;\n\n"); |
|
fprintf(TOP_FP," tip_addr : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(TOP_FP," tip_we : in STD_LOGIC_VECTOR(0 downto 0);\n"); |
fprintf(TOP_FP," tip_din : in STD_LOGIC_VECTOR(7 downto 0);\n"); |
|
fprintf(TOP_FP," sel_vec : in STD_LOGIC_VECTOR(2 downto 0);\n"); |
fprintf(TOP_FP," addrA : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(TOP_FP," addrB : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(TOP_FP," addrC : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(TOP_FP," addrD : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(TOP_FP," WRCNTRL : in STD_LOGIC_VECTOR(13 downto 0);\n"); |
fprintf(TOP_FP," POPCOUNTvector : out STD_LOGIC_VECTOR(%d downto 0)\n",INPUT_LOAD-1); |
fprintf(TOP_FP," );\n"); |
fprintf(TOP_FP,"end component;\n"); |
} |
|
void componentPOPCOUNT() |
{ |
fprintf(TOP_FP,"\n"); |
fprintf(TOP_FP,"component POPCOUNT is\n"); |
fprintf(TOP_FP,"Port ( clk : in STD_LOGIC;\n"); |
fprintf(TOP_FP," invec : in STD_LOGIC_VECTOR(%d downto 0);\n",INPUT_LOAD-1); |
fprintf(TOP_FP," value : out STD_LOGIC_VECTOR(31 downto 0)\n"); |
fprintf(TOP_FP,");\n"); |
fprintf(TOP_FP,"end component;\n"); |
} |
|
void componentSCOREMEM() |
{ |
fprintf(TOP_FP,"\n\n"); |
fprintf(TOP_FP,"component MP_SCORE_MEM_V5 is\n"); |
fprintf(TOP_FP," port (\n"); |
fprintf(TOP_FP," ssrb : in STD_LOGIC := 'X';\n"); |
fprintf(TOP_FP," clka : in STD_LOGIC := 'X';\n"); |
fprintf(TOP_FP," clkb : in STD_LOGIC := 'X';\n"); |
fprintf(TOP_FP," wea : in STD_LOGIC_VECTOR(0 downto 0);\n"); |
fprintf(TOP_FP," addra : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(TOP_FP," addrb : in STD_LOGIC_VECTOR(10 downto 0);\n"); |
fprintf(TOP_FP," doutb : out STD_LOGIC_VECTOR(31 downto 0);\n"); |
fprintf(TOP_FP," dina : in STD_LOGIC_VECTOR(31 downto 0)\n"); |
fprintf(TOP_FP," );\n"); |
fprintf(TOP_FP,"end component;\n"); |
} |
|
|
|
void MPEXT_components() |
{ |
int i; |
|
componentPPC(); |
componentPOPCOUNT(); |
componentSCOREMEM(); |
|
|
fprintf(TOP_FP,"\n\nsignal sync_vec: std_logic_vector(%d downto 0);",LATENCY+6); |
|
fprintf(TOP_FP,"\n\nsignal bitvector_consig: std_logic_vector(%d downto 0);\n\n\nbegin\n\n",INPUT_LOAD-1); |
|
getbitvector((INPUT_LOAD/2)-2); |
} |
|
void synchronize() |
{ |
int i; |
|
fprintf(TOP_FP,"\nsync_vec(0) <= sync_in;\nsync_out<=sync_vec(%d);\n\nprocess(clk)\nbegin\nif clk'event and clk='1' then\n",LATENCY+6); |
|
for (i=1;i<=LATENCY+6;i++) |
{ |
fprintf(TOP_FP," sync_vec(%d) <= sync_vec(%d);\n",i,i-1); |
} |
fprintf(TOP_FP,"end if;\nend process;\n"); |
|
} |
|
void instantiatePPC() |
{ |
fprintf(TOP_FP,"\n\n---------\n"); |
fprintf(TOP_FP,"-- PPC --\n"); |
fprintf(TOP_FP,"---------\n"); |
fprintf(TOP_FP,"\n"); |
fprintf(TOP_FP,"PPC_U: PPC Port Map\n"); |
fprintf(TOP_FP,"(\n"); |
fprintf(TOP_FP," clk => clk,\n\n"); |
fprintf(TOP_FP," tip_addr => tip_addr,\n"); |
fprintf(TOP_FP," tip_we => tip_we,\n"); |
fprintf(TOP_FP," tip_din => tip_din,\n"); |
fprintf(TOP_FP," sel_vec => sel_vec,\n"); |
fprintf(TOP_FP," addrA => addrA,\n"); |
fprintf(TOP_FP," addrB => addrB,\n"); |
fprintf(TOP_FP," addrC => addrC,\n"); |
fprintf(TOP_FP," addrD => addrD,\n"); |
fprintf(TOP_FP," WRCNTRL => WRCNTRL,\n"); |
fprintf(TOP_FP," POPCOUNTvector => bitvector_consig\n",INPUT_LOAD-1); |
fprintf(TOP_FP,");\n"); |
} |
|
void instantiatePOPCOUNT() |
{ |
fprintf(TOP_FP,"\n\n--------------\n"); |
fprintf(TOP_FP,"-- POPCOUNT --\n"); |
fprintf(TOP_FP,"--------------\n"); |
fprintf(TOP_FP,"\n"); |
fprintf(TOP_FP,"POPCOUNT_U: POPCOUNT Port Map\n"); |
fprintf(TOP_FP,"(\n"); |
fprintf(TOP_FP," clk => clk,\n"); |
fprintf(TOP_FP," invec => bitvector_consig,\n"); |
fprintf(TOP_FP," value => POPCOUNT_val\n"); |
fprintf(TOP_FP,");\n"); |
} |
|
void instantiateSCOREMEM() |
{ |
fprintf(TOP_FP,"\n\n---------------\n"); |
fprintf(TOP_FP,"-- SCORE MEM --\n"); |
fprintf(TOP_FP,"---------------\n"); |
fprintf(TOP_FP,"\n"); |
fprintf(TOP_FP,"SCOREMEM_U: MP_SCORE_MEM_V5 Port Map\n"); |
fprintf(TOP_FP,"(\n"); |
fprintf(TOP_FP," ssrb => score_rdaddr(0),\n"); |
fprintf(TOP_FP," clka => clk,\n"); |
fprintf(TOP_FP," clkb => clk,\n"); |
fprintf(TOP_FP," wea => score3_we,\n"); |
fprintf(TOP_FP," addra => score3_addr(11 downto 1),\n"); |
fprintf(TOP_FP," addrb => score_rdaddr(11 downto 1),\n"); |
fprintf(TOP_FP," doutb => score_rddout,\n"); |
fprintf(TOP_FP," dina => score3_din\n"); |
fprintf(TOP_FP,");\n"); |
} |
|
void get_register_positions() |
{ |
int i; |
int popcountstages = MAX_CODE; |
int desiredlatency = LATENCY; |
int registerstages = MAX_CODE/LATENCY; |
int offset = MAX_CODE % LATENCY; |
int loopposition = registerstages; |
int loopoffset = offset; |
registerpositions = (int *) malloc(sizeof(int)*LATENCY-1); |
|
registerpositions[0] = loopposition; |
|
if(loopoffset!=0) |
{ |
registerpositions[0]++; |
loopoffset--; |
} |
|
for(i=1;i<LATENCY-1;i++) |
{ |
registerpositions[i] = registerpositions[i-1] + loopposition; |
if(loopoffset!=0) |
{ |
registerpositions[i]++; |
loopoffset--; |
} |
} |
} |
|
|
int main() |
{ |
int i=0; |
char temp; |
|
printf("\n1. Number of Input Bits:"); |
scanf("%d",&INPUT_LOAD); |
|
if(INPUT_LOAD<=1) |
{ |
printf("\n Minimum Number of Input Bits = 2!\n\n"); |
INPUT_LOAD = 2; |
} |
|
printf("\n2. POPCOUNT Latency (# of Cycles):"); |
scanf("%d",&LATENCY); |
|
if (LATENCY<=0) |
{ |
printf("\n Minimum POPCOUNT Latency = 1 clock cycle!\n"); |
LATENCY = 1; |
} |
|
ADDER_FP = fopen("POPCOUNT.vhd","w"); |
|
preliminary_input(ADDER_FP); |
|
libraries(ADDER_FP); |
|
entityADDER(); |
|
start_architectureADDER(); |
|
processADDER(SIZE_MODE); |
|
ADD_CONFIG = (adder_config*)malloc(sizeof(adder_config)*ADDER_LOAD); |
ADD_CONFIG_IND = 0; |
|
SIG_CONFIG = (signal_config*)malloc(sizeof(signal_config)*SIGNAL_LOAD); |
SIG_CONFIG_IND = 0; |
|
processADDER(CONFIG_MODE); |
|
get_register_positions(); |
|
processADDER(CREATE_MODE); |
|
for(i=1;i<MAX_CODE+1;i++) |
{ |
create_short_adder(i,ADDER_FP); |
} |
|
fclose(ADDER_FP); |
|
|
|
/* MPPRU_FP = fopen("PPC.vhd","w"); |
|
PPC_SIZE = INPUT_LOAD / 2; |
|
BITVEC_INDEX = INPUT_LOAD - 1; |
|
preliminary_input(MPPRU_FP); |
|
libraries(MPPRU_FP); |
|
entityPPC(); |
|
start_architecturePPC(); |
|
componentPRU(); |
|
signalsPPC(); |
|
for(i=1;i<=PPC_SIZE;i++) |
{ |
instantiatePRU(i); |
} |
|
end_file(MPPRU_FP); |
|
fclose(MPPRU_FP); |
|
|
|
|
TOP_FP = fopen("MP_EXT.vhd","w"); |
|
preliminary_input(TOP_FP); |
|
libraries(TOP_FP); |
|
entityMPEXT(); |
|
start_architectureMPEXT(); |
|
MPEXT_components(); |
|
synchronize(); |
|
instantiatePPC(); |
|
instantiatePOPCOUNT(); |
|
instantiateSCOREMEM(); |
|
end_file(TOP_FP); |
|
fclose(TOP_FP); |
*/ |
|
printf("\n\n\n A VHDL file has been successfully generated!\n\n\nPress Enter to Exit...\n"); |
scanf("%c",&temp); |
scanf("%c",&temp); |
|
return 0; |
} |
/trunk/README.txt
0,0 → 1,71
====================================== |
POPULATION COUNTER GENERATOR FOR FPGAS |
====================================== |
|
Release date: June 27th, 2011 |
|
|
Description |
----------- |
|
FPGA_MaxPars_Gen is part of a package called FPGA_MaxPars that provides an |
open-source VHDL implementation of a reconfigurable architecture for the |
phylogenetic parsimony kernel. |
The software tool FPGA_MaxPars_Gen allows for easy expansion of the size of the architecture in terms of parallel processing |
units. |
Furthermore, it can also generate a population counter with user-defined size and latency in VHDL. |
|
Additional infromation for the FGA_MaxPars_Gen software and the population counter component can be found in: |
|
N. Alachiotis, A. Stamatakis: "FPGA Acceleration of the Phylogenetic Parsimony Kernel?", FPL 2011, Chania, Greece, September 2011. |
|
|
|
Verification Details |
-------------------- |
|
The development board HTG-V5-PCIE by HiTech Global populated with a V5SX95T-1 FPGA was used to verify the correct behavior of the population counter. |
|
|
|
Authors and Contact Details |
--------------------------- |
|
Nikos Alachiotis n.alachiotis@gmail.com |
Alexandros Stamatakis alexandros.stamatakis@h-its.org |
|
|
Scientific Computing Group (Exelixis Lab) |
Heidelberg Institute for Theoretical Studies (HITS gGmbH) |
|
Schloss-Wolfsbrunnenweg 35 |
D-69118 Heidelberg |
Germany |
|
|
Copyright |
--------- |
|
This component is free. In case you use it for any purpose, particularly |
when publishing work relying on this component you must cite it as: |
|
N. Alachiotis, A. Stamatakis: "FPGA Acceleration of the Phylogenetic Parsimony Kernel?", FPL 2011, Chania, Greece, September 2011. |
|
You can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 2 of the License, or |
(at your option) any later version. |
|
This component is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
|
The population counter (POPCOUNT.vhd) generated by FPGA_MaxPars_Gen can be used under the GNU LGPL license. |
|
|
Release Notes |
------------- |
|
Release date: June 27th, 2011 |