Merge pull request #13 from LNIS-Projects/dev

Dev
This commit is contained in:
tangxifan 2019-07-16 22:10:04 -04:00 committed by GitHub
commit 4672311aae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 369 additions and 322 deletions

View File

@ -9,8 +9,7 @@ The OpenFPGA framework is the **first open-source FPGA IP generator** supporting
## Compilation
The different ways of compiling can be found in the [**./compilation**](https://github.com/LNIS-Projects/OpenFPGA/tree/master/compilation) folder.<br />
Dependancies and help using docker can be found at [**./tutorials/building.md**](https://github.com/LNIS-Projects/OpenFPGA/blob/master/tutorials/building.md).
Dependencies and help using docker can be found at [**./tutorials/building.md**](https://github.com/LNIS-Projects/OpenFPGA/blob/master/tutorials/building.md).
**Compilation steps:**
1. git clone https://github.com/LNIS-Projects/OpenFPGA.git && cd OpenFPGA # *Clone the repository and go into it*
@ -21,7 +20,7 @@ Dependancies and help using docker can be found at [**./tutorials/building.md**]
*We currently implemented OpenFPGA for:*<br />
*1. Ubuntu 16.04*<br />
*2. Red Hat 7.5*<br />
*3. MacOS Mojiva 10.13.4*<br /><br />
*3. MacOS Mojave 10.13.4*<br /><br />
*Please note that those were the versions we tested the software for. It might work with earlier versions and other distributions.*
## Documentation

View File

@ -37,6 +37,7 @@ set_target_properties(libace PROPERTIES PREFIX "") #Avoid extra 'lib' prefix#Cre
# Specify dependency
target_link_libraries(libace
libabc
libvtrutil
${CMAKE_DL_LIBS})
add_executable(ace ${EXEC_SOURCES})

View File

@ -1,3 +1,6 @@
#include "vtr_assert.h"
#include "vtr_time.h" //For some reason this causes compilation errors if included below the std headers on with g++-5
#include "vtr_assert.h"
#include <stdio.h>
#include <inttypes.h>
@ -50,8 +53,7 @@ void print_status(Abc_Ntk_t * ntk) {
printf("%d: OLD\n", i);
break;
default:
printf("Invalid ABC object info status");
exit(1);
VTR_ASSERT_MSG(false, "Invalid ABC object info status");
}
}
}
@ -169,11 +171,11 @@ int ace_calc_activity(Abc_Ntk_t * ntk, int num_vectors, char * clk_name) {
{
info = Ace_ObjInfo(obj);
if (strcmp(Abc_ObjName(obj), clk_name) != 0) {
assert(info->static_prob >= 0 && info->static_prob <= 1.0);
assert(info->switch_prob >= 0 && info->switch_prob <= 1.0);
assert(info->switch_act >= 0 && info->switch_act <= 1.0);
assert(info->switch_prob <= 2.0 * (1.0 - info->static_prob));
assert(info->switch_prob <= 2.0 * info->static_prob);
VTR_ASSERT(info->static_prob >= 0 && info->static_prob <= 1.0);
VTR_ASSERT(info->switch_prob >= 0 && info->switch_prob <= 1.0);
VTR_ASSERT(info->switch_act >= 0 && info->switch_act <= 1.0);
VTR_ASSERT(info->switch_prob <= 2.0 * (1.0 - info->static_prob));
VTR_ASSERT(info->switch_prob <= 2.0 * info->static_prob);
}
info->status = ACE_DEF;
}
@ -233,11 +235,11 @@ int ace_calc_activity(Abc_Ntk_t * ntk, int num_vectors, char * clk_name) {
Ace_Obj_Info_t * info2 = Ace_ObjInfo(obj);
info2->switch_act = info2->switch_prob;
assert(info2->switch_act >= 0.0);
VTR_ASSERT(info2->switch_act >= 0.0);
}
Abc_NtkForEachPi(ntk, obj, i)
{
assert(Ace_ObjInfo(obj)->switch_act >= 0.0);
VTR_ASSERT(Ace_ObjInfo(obj)->switch_act >= 0.0);
}
/*------------- Calculate switching activities. ---------------------*/
@ -275,7 +277,7 @@ int ace_calc_activity(Abc_Ntk_t * ntk, int num_vectors, char * clk_name) {
Ace_Obj_Info_t * info2 = Ace_ObjInfo(obj);
//Ace_Obj_Info_t * fanin_info2;
assert(Abc_ObjType(obj) == ABC_OBJ_NODE);
VTR_ASSERT(Abc_ObjType(obj) == ABC_OBJ_NODE);
if (Abc_ObjFaninNum(obj) < 1) {
info2->switch_act = 0.0;
@ -284,7 +286,7 @@ int ace_calc_activity(Abc_Ntk_t * ntk, int num_vectors, char * clk_name) {
Vec_Ptr_t * literals = Vec_PtrAlloc(0);
Abc_Obj_t * fanin;
assert(obj->Type == ABC_OBJ_NODE);
VTR_ASSERT(obj->Type == ABC_OBJ_NODE);
Abc_ObjForEachFanin(obj, fanin, j)
{
@ -294,7 +296,7 @@ int ace_calc_activity(Abc_Ntk_t * ntk, int num_vectors, char * clk_name) {
literals);
Vec_PtrFree(literals);
}
assert(info2->switch_act >= 0);
VTR_ASSERT(info2->switch_act >= 0);
}
Vec_PtrFree(nodes_logic);
Vec_PtrFree(latches_in_cycles_vec);
@ -308,21 +310,22 @@ Ace_Obj_Info_t * Ace_ObjInfo(Abc_Obj_t * obj) {
if (st__lookup(ace_info_hash_table, (char *) obj, (char **) &info)) {
return info;
}
assert(0);
VTR_ASSERT(0);
return NULL;
}
void prob_epsilon_fix(double * d) {
if (*d < 0) {
assert(*d > 0 - EPSILON);
VTR_ASSERT(*d > 0 - EPSILON);
*d = 0;
} else if (*d > 1) {
assert(*d < 1 + EPSILON);
VTR_ASSERT(*d < 1 + EPSILON);
*d = 1.;
}
}
int main(int argc, char * argv[]) {
vtr::ScopedFinishTimer t("Ace");
FILE * BLIF = NULL;
FILE * IN_ACT = NULL;
FILE * OUT_ACT = stdout;
@ -351,7 +354,7 @@ int main(int argc, char * argv[]) {
ntk = Io_Read(blif_file_name, IO_FILE_BLIF, 1, 0);
assert(ntk);
VTR_ASSERT(ntk);
printf("Objects in network: %d\n", Abc_NtkObjNum(ntk));
printf("PIs in network: %d\n", Abc_NtkPiNum(ntk));
@ -383,7 +386,7 @@ int main(int argc, char * argv[]) {
// Check Depth
depth = ace_calc_network_depth(ntk);
printf("Max Depth: %d\n", depth);
assert(depth > 0);
VTR_ASSERT(depth > 0);
alloc_and_init_activity_info(ntk);

View File

@ -1,5 +1,7 @@
#include <inttypes.h>
#include "vtr_assert.h"
#include "ace.h"
#include "misc/vec/vecPtr.h"
#include "bdd.h"
@ -86,7 +88,7 @@ int ace_bdd_build_network_bdds(
int i;
Vec_Ptr_t * nodes;
assert(Vec_PtrSize(inputs) > 0);
VTR_ASSERT(Vec_PtrSize(inputs) > 0);
nodes = Abc_NtkDfsSeq(ntk);
@ -111,8 +113,8 @@ int ace_bdd_build_network_bdds(
switch (info->status)
{
case ACE_SIM:
assert (info->static_prob >= 0.0 && info->static_prob <= 1.0);
assert (info->switch_prob >= 0.0 && info->switch_prob <= 1.0);
VTR_ASSERT (info->static_prob >= 0.0 && info->static_prob <= 1.0);
VTR_ASSERT (info->switch_prob >= 0.0 && info->switch_prob <= 1.0);
if (!st_lookup(leaves, (char*) obj, NULL))
{
@ -128,7 +130,7 @@ int ace_bdd_build_network_bdds(
break;
case ACE_UNDEF:
assert(0);
VTR_ASSERT(0);
if (check_pi_status(obj))
{
while(1)
@ -149,14 +151,14 @@ int ace_bdd_build_network_bdds(
break;
case ACE_DEF:
assert(info->static_prob >= 0 && info->static_prob <= 1.0);
assert(info->switch_prob >= 0 && info->switch_prob <= 1.0);
VTR_ASSERT(info->static_prob >= 0 && info->static_prob <= 1.0);
VTR_ASSERT(info->switch_prob >= 0 && info->switch_prob <= 1.0);
break;
case ACE_NEW:
case ACE_OLD:
default:
assert(0);
VTR_ASSERT(0);
}
}
@ -192,7 +194,7 @@ double calc_cube_switch_prob_recur(DdManager * mgr, DdNode * bdd,
}
/* Get literal index for this bdd node. */
//assert(0);
//VTR_ASSERT(0);
i = Cudd_Regular(bdd)->index;
pi = (Abc_Obj_t*) Vec_PtrEntry((Vec_Ptr_t*) inputs, i);
@ -210,11 +212,11 @@ double calc_cube_switch_prob_recur(DdManager * mgr, DdNode * bdd,
then_prob = calc_cube_switch_prob_recur(mgr, bdd_if1, cube, inputs, visited,
phase);
assert(then_prob + EPSILON >= 0 && then_prob - EPSILON <= 1);
VTR_ASSERT(then_prob + EPSILON >= 0 && then_prob - EPSILON <= 1);
else_prob = calc_cube_switch_prob_recur(mgr, bdd_if0, cube, inputs, visited,
phase);
assert(else_prob + EPSILON >= 0 && else_prob - EPSILON <= 1);
VTR_ASSERT(else_prob + EPSILON >= 0 && else_prob - EPSILON <= 1);
switch (node_get_literal (cube->cube, i)) {
case ZERO:
@ -235,7 +237,7 @@ double calc_cube_switch_prob_recur(DdManager * mgr, DdNode * bdd,
st__insert(visited, (char *) bdd, (char *) current_prob);
assert(*current_prob + EPSILON >= 0 && *current_prob - EPSILON < 1.0);
VTR_ASSERT(*current_prob + EPSILON >= 0 && *current_prob - EPSILON < 1.0);
return (*current_prob);
}
@ -250,7 +252,7 @@ double calc_cube_switch_prob(DdManager * mgr, DdNode * bdd, ace_cube_t * cube,
st__free_table(visited);
assert(sp + EPSILON >= 0. && sp - EPSILON <= 1.0);
VTR_ASSERT(sp + EPSILON >= 0. && sp - EPSILON <= 1.0);
return (sp);
}
@ -264,9 +266,9 @@ double calc_switch_prob_recur(DdManager * mgr, DdNode * bdd_next, DdNode * bdd,
ace_cube_t * cube0, *cube1;
Ace_Obj_Info_t * info;
assert(inputs != NULL);
assert(Vec_PtrSize(inputs) > 0);
assert(P1 >= 0);
VTR_ASSERT(inputs != NULL);
VTR_ASSERT(Vec_PtrSize(inputs) > 0);
VTR_ASSERT(P1 >= 0);
if (bdd == Cudd_ReadLogicZero(mgr)) {
if (phase != 1)
@ -274,7 +276,7 @@ double calc_switch_prob_recur(DdManager * mgr, DdNode * bdd_next, DdNode * bdd,
prob = calc_cube_switch_prob(mgr, bdd_next, cube, inputs, phase);
prob *= P1;
assert(prob + EPSILON >= 0. && prob - EPSILON <= 1.);
VTR_ASSERT(prob + EPSILON >= 0. && prob - EPSILON <= 1.);
return (prob * P1);
} else if (bdd == Cudd_ReadOne(mgr)) {
if (phase != 0)
@ -282,7 +284,7 @@ double calc_switch_prob_recur(DdManager * mgr, DdNode * bdd_next, DdNode * bdd,
prob = calc_cube_switch_prob(mgr, bdd_next, cube, inputs, phase);
prob *= P1;
assert(prob + EPSILON >= 0. && prob - EPSILON <= 1.);
VTR_ASSERT(prob + EPSILON >= 0. && prob - EPSILON <= 1.);
return (prob * P1);
}
@ -315,8 +317,8 @@ double calc_switch_prob_recur(DdManager * mgr, DdNode * bdd_next, DdNode * bdd,
inputs, P1 * (1.0 - info->static_prob), phase);
ace_cube_free(cube0);
assert(switch_prob_t + EPSILON >= 0. && switch_prob_t - EPSILON <= 1.);
assert(switch_prob_e + EPSILON >= 0. && switch_prob_e - EPSILON <= 1.);
VTR_ASSERT(switch_prob_t + EPSILON >= 0. && switch_prob_t - EPSILON <= 1.);
VTR_ASSERT(switch_prob_e + EPSILON >= 0. && switch_prob_e - EPSILON <= 1.);
return (switch_prob_t + switch_prob_e);
}
@ -333,7 +335,7 @@ double ace_bdd_calc_switch_act(DdManager * mgr, Abc_Obj_t * obj,
DdNode * bdd;
d = info->depth;
assert(d > 0);
VTR_ASSERT(d > 0);
d = (int) d * 0.4;
if (d < 1) {
d = 1;
@ -361,10 +363,10 @@ double ace_bdd_calc_switch_act(DdManager * mgr, Abc_Obj_t * obj,
prob_epsilon_fix(&fanin_info->prob0to1);
prob_epsilon_fix(&fanin_info->prob1to0);
assert(
VTR_ASSERT(
fanin_info->prob0to1 + EPSILON >= 0.
&& fanin_info->prob0to1 - EPSILON <= 1.0);
assert(
VTR_ASSERT(
fanin_info->prob1to0 + EPSILON >= 0.
&& fanin_info->prob1to0 - EPSILON <= 1.0);
}

View File

@ -1,3 +1,4 @@
#include "vtr_assert.h"
#include "cube.h"
#include "bdd.h"
@ -16,8 +17,8 @@ ace_cube_t * ace_cube_dup(ace_cube_t * cube) {
int i;
ace_cube_t * cube_copy;
assert(cube != NULL);
assert(cube->num_literals > 0);
VTR_ASSERT(cube != NULL);
VTR_ASSERT(cube->num_literals > 0);
cube_copy = (ace_cube_t*) malloc(sizeof(ace_cube_t));
cube_copy->static_prob = cube->static_prob;
@ -63,8 +64,8 @@ ace_cube_t * ace_cube_new_dc(int num_literals) {
}
void ace_cube_free(ace_cube_t * cube) {
assert(cube != NULL);
assert(cube->cube != NULL);
VTR_ASSERT(cube != NULL);
VTR_ASSERT(cube->cube != NULL);
free(cube->cube);
free(cube);
}

View File

@ -1,3 +1,4 @@
#include "vtr_assert.h"
#include "cycle.h"
#include "ace.h"
@ -28,7 +29,7 @@ bool in_cycle(Abc_Ntk_t * ntk, int obj_id_to_find, Abc_Obj_t * starting_obj_ptr,
{
// Get BI of latch
fanin_ptr = Abc_ObjFanin0(Abc_ObjFanin0(starting_obj_ptr));
assert(fanin_ptr);
VTR_ASSERT(fanin_ptr);
return (in_cycle(ntk, obj_id_to_find, fanin_ptr, flag));
}

View File

@ -1,5 +1,7 @@
#include <stdlib.h>
#include "vtr_assert.h"
#include "ace.h"
#include "io_ace.h"
@ -34,7 +36,7 @@ void ace_io_print_activity(Abc_Ntk_t * ntk, FILE * fp) {
Abc_NtkForEachObj(ntk, obj, i)
{
assert(obj->pCopy);
VTR_ASSERT(obj->pCopy);
obj_new = obj->pCopy;
Ace_Obj_Info_t * info = Ace_ObjInfo(obj);
@ -69,7 +71,7 @@ void ace_io_print_activity(Abc_Ntk_t * ntk, FILE * fp) {
default:
//printf("Unkown Type: %d\n", Abc_ObjType(obj));
//assert(0);
//VTR_ASSERT(0);
break;
}
@ -235,10 +237,10 @@ int ace_io_read_activity(Abc_Ntk_t * ntk, FILE * in_file_desc,
printf("Cannot open input file\n");
error = ACE_ERROR;
} else {
assert(p >= 0.0 && p <= 1.0);
assert(d >= 0.0 && d <= 1.0);
assert(d <= 2.0 * p);
assert(d <= 2.0 * (1.0 - p));
VTR_ASSERT(p >= 0.0 && p <= 1.0);
VTR_ASSERT(d >= 0.0 && d <= 1.0);
VTR_ASSERT(d <= 2.0 * p);
VTR_ASSERT(d <= 2.0 * (1.0 - p));
Abc_NtkForEachPi(ntk, obj_ptr, i)
{
@ -269,7 +271,7 @@ int ace_io_read_activity(Abc_Ntk_t * ntk, FILE * in_file_desc,
// Read real PIs activity values from file
res = fgets(line, ACE_CHAR_BUFFER_SIZE, in_file_desc);
assert(res);
VTR_ASSERT(res);
while (!feof(in_file_desc)) {
sscanf(line, "%s %lf %lf\n", pi_name, &static_prob,
&switch_prob);
@ -283,8 +285,8 @@ int ace_io_read_activity(Abc_Ntk_t * ntk, FILE * in_file_desc,
}
pi_obj_ptr = Abc_NtkObj(ntk, pi_obj_id);
assert(static_prob >= 0.0 && static_prob <= 1.0);
assert(switch_prob >= 0.0 && switch_prob <= 1.0);
VTR_ASSERT(static_prob >= 0.0 && static_prob <= 1.0);
VTR_ASSERT(switch_prob >= 0.0 && switch_prob <= 1.0);
info = Ace_ObjInfo(pi_obj_ptr);
info->static_prob = static_prob;
@ -292,7 +294,7 @@ int ace_io_read_activity(Abc_Ntk_t * ntk, FILE * in_file_desc,
info->switch_act = switch_prob;
res = fgets(line, ACE_CHAR_BUFFER_SIZE, in_file_desc);
assert(res);
VTR_ASSERT(res);
}
} else if (pi_format == ACE_VEC) {
printf("Reading vector file...\n");
@ -305,10 +307,10 @@ int ace_io_read_activity(Abc_Ntk_t * ntk, FILE * in_file_desc,
char* res;
res = fgets(line, ACE_CHAR_BUFFER_SIZE, in_file_desc);
assert(res);
VTR_ASSERT(res);
while (!feof(in_file_desc)) {
res = fgets(line, ACE_CHAR_BUFFER_SIZE, in_file_desc);
assert(res);
VTR_ASSERT(res);
num_vec++;
}
Abc_NtkForEachPi(ntk, obj_ptr, i)
@ -325,7 +327,7 @@ int ace_io_read_activity(Abc_Ntk_t * ntk, FILE * in_file_desc,
num_vec = 0;
res = fgets(line, ACE_CHAR_BUFFER_SIZE, in_file_desc);
assert(res);
VTR_ASSERT(res);
while (!feof(in_file_desc)) {
sscanf(line, "%s\n", vector);
@ -336,7 +338,7 @@ int ace_io_read_activity(Abc_Ntk_t * ntk, FILE * in_file_desc,
error = ACE_ERROR;
break;
}
assert(strlen(vector) == num_Pi);
VTR_ASSERT(strlen(vector) == num_Pi);
if (num_vec == 0) {
Abc_NtkForEachPi(ntk, obj_ptr, i)
@ -364,14 +366,14 @@ int ace_io_read_activity(Abc_Ntk_t * ntk, FILE * in_file_desc,
}
res = fgets(line, ACE_CHAR_BUFFER_SIZE, in_file_desc);
assert(res);
VTR_ASSERT(res);
num_vec++;
}
if (!error) {
Abc_NtkForEachPi(ntk, obj_ptr, i)
{
assert(num_vec > 0);
VTR_ASSERT(num_vec > 0);
info = Ace_ObjInfo(obj_ptr);
info->static_prob = (double) high[i] / (double) num_vec;

View File

@ -1,3 +1,4 @@
#include "vtr_assert.h"
#include "ace.h"
#include "sim.h"
@ -60,7 +61,7 @@ void get_pi_values(Abc_Ntk_t * ntk, Vec_Ptr_t * /*nodes*/, int cycle) {
default:
printf("Bad Value\n");
assert(0);
VTR_ASSERT(0);
break;
}
}
@ -111,7 +112,7 @@ void get_pi_values(Abc_Ntk_t * ntk, Vec_Ptr_t * /*nodes*/, int cycle) {
default:
printf("Bad value\n");
assert(FALSE);
VTR_ASSERT(FALSE);
break;
}
}
@ -131,7 +132,7 @@ int * getFaninValues(Abc_Obj_t * obj_ptr) {
info = Ace_ObjInfo(fanin);
if (info->status == ACE_UNDEF) {
printf("Fan-in is undefined\n");
assert(FALSE);
VTR_ASSERT(FALSE);
} else if (info->status == ACE_NEW) {
break;
}
@ -210,15 +211,15 @@ void evaluate_circuit(Abc_Ntk_t * ntk, Vec_Ptr_t * node_vec, int /*cycle*/) {
case ACE_NEW:
if (Abc_ObjIsNode(obj)) {
faninValues = getFaninValues(obj);
assert(faninValues);
VTR_ASSERT(faninValues);
dd_node = Cudd_Eval((DdManager*) ntk->pManFunc, (DdNode*) obj->pData, faninValues);
assert(Cudd_IsConstant(dd_node));
VTR_ASSERT(Cudd_IsConstant(dd_node));
if (dd_node == Cudd_ReadOne((DdManager*) ntk->pManFunc)) {
value = 1;
} else if (dd_node == Cudd_ReadLogicZero((DdManager*) ntk->pManFunc)) {
value = 0;
} else {
assert(0);
VTR_ASSERT(0);
}
free(faninValues);
} else {
@ -240,12 +241,12 @@ void evaluate_circuit(Abc_Ntk_t * ntk, Vec_Ptr_t * node_vec, int /*cycle*/) {
info->num_ones += info->value;
break;
default:
assert(0);
VTR_ASSERT(0);
break;
}
break;
default:
assert(0);
VTR_ASSERT(0);
break;
}
}
@ -294,8 +295,8 @@ void ace_sim_activities(Abc_Ntk_t * ntk, Vec_Ptr_t * nodes, int max_cycles,
Ace_Obj_Info_t * info;
int i;
assert(max_cycles > 0);
assert(threshold > 0.0);
VTR_ASSERT(max_cycles > 0);
VTR_ASSERT(threshold > 0.0);
// srand((unsigned) time(NULL));
@ -326,12 +327,12 @@ void ace_sim_activities(Abc_Ntk_t * ntk, Vec_Ptr_t * nodes, int max_cycles,
{
info = Ace_ObjInfo(obj);
info->static_prob = info->num_ones / (double) max_cycles;
assert(info->static_prob >= 0.0 && info->static_prob <= 1.0);
VTR_ASSERT(info->static_prob >= 0.0 && info->static_prob <= 1.0);
info->switch_prob = info->num_toggles / (double) max_cycles;
assert(info->switch_prob >= 0.0 && info->switch_prob <= 1.0);
VTR_ASSERT(info->switch_prob >= 0.0 && info->switch_prob <= 1.0);
assert(info->switch_prob - EPSILON <= 2.0 * (1.0 - info->static_prob));
assert(info->switch_prob - EPSILON <= 2.0 * (info->static_prob));
VTR_ASSERT(info->switch_prob - EPSILON <= 2.0 * (1.0 - info->static_prob));
VTR_ASSERT(info->switch_prob - EPSILON <= 2.0 * (info->static_prob));
info->status = ACE_SIM;
}

View File

@ -1,15 +0,0 @@
Yosys
=========
*Information taken from Yosys' GitHub*
You need a C++ compiler with C++11 support (up-to-date CLANG or GCC is recommended) and some standard tools such as GNU Flex, GNU Bison, and GNU Make. TCL, readline and libffi are optional (see ENABLE_* settings in Makefile). Xdot (graphviz) is used by the show command in yosys to display schematics.
ABC
=========
ABC depends on gcc-4.9. It is precisely this version which is required. If another gcc is used, the compilation will not be finished correctly.
ACE2
=========
ACE2 only needs a compiler to work. Gcc is the one chosen in this case. No issue was ever reported with ACE2 so if you have one, raise an issue so that we can modify it here.

View File

@ -1,40 +0,0 @@
MacOS compilation
==================
*This tutorial has been tested under MacOS High Sierra 10.13.4*
Clone the [OpenFPGA git repository:](https://github.com/LNIS-Projects/OpenFPGA)
`git clone --recurse-submodules https://github.com/LNIS-Projects/OpenFPGA.git `
[//todo]: # (There is a submodule in the repository so move to the OpenFPGA directory and clone that too:)
[//]: # (`git submodule init`)
[//todo]: # (`git submodule update`)
Go to the `VPR` directory and build the tool:
`cd ./OpenFPGA/vpr7_x2p/vpr/`
Note: the graphical interface might not be usable since it requires the X11 library. In this case, open the Makefile and change the line 10 "ENABLE_GRAPHICS = true" to false.
`make `
This will generate vpr and a libvpr.a file.
Enhancements of VPR were made.
In order to see them just type:
`./vpr`
This will show the different options that can be used. Our modifications concern the options starting with fpga_spice and fpga_verilog.
A script is already prepared in the folder to test FPGA-SPICE and FPGA-Verilog
`source ./go_fpga_verilog.sh`
This script uses the enhanced version of vpr with some new options such as --fpga_verilog_print_top_testbench which automatically generates a testbench for the full FPGA and --fpga_verilog_dir which allows us to choose the destination directory for the verilog output we generate.
For more informations on how the new commands work, please visit [OpenFPGA Options FPGA-SPICE](https://openfpga.readthedocs.io/en/latest/fpga_spice/command_line_usage.html).
As a result, we get a new folder, /verilog_test, which contains the verilog code. The name_top.v contains the full FPGA we just created. Three other folders are created, *lb*, *routing* and *sub_modules*. *lb* contains the different CLBs used in the architecture. *routing* contains the different connection blocks, the switch boxes and the wires. *sub_modules* contains the different modules needed in the architecture.

View File

@ -1,40 +0,0 @@
Red Hat compilation
==================
*This tutorial has been tested under Red Hat 7.5*
Clone the [OpenFPGA git repository:](https://github.com/LNIS-Projects/OpenFPGA)
`git clone --recurse-submodules https://github.com/LNIS-Projects/OpenFPGA.git `
[//todo]: # (There is a submodule in the repository so move to the OpenFPGA directory and clone that too:)
[//]: # (`git submodule init`)
[//todo]: # (`git submodule update`)
Go to the `VPR` directory and build the tool:
`cd ./OpenFPGA/vpr7_x2p/vpr/`
Note: the graphical interface might not be usable since it requires the X11 library. In this case, open the Makefile and change the line 10 "ENABLE_GRAPHICS = true" to false.
`make `
This will generate vpr and a libvpr.a file.
Enhancements of VPR were made.
In order to see them just type:
`./vpr`
This will show the different options that can be used. Our modifications concern the options starting with fpga_spice and fpga_verilog.
A script is already prepared in the folder to test FPGA-SPICE and FPGA-Verilog
`source ./go_fpga_verilog.sh`
This script uses the enhanced version of vpr with some new options such as --fpga_verilog_print_top_testbench which automatically generates a testbench for the full FPGA and --fpga_verilog_dir which allows us to choose the destination directory for the verilog output we generate.
For more informations on how the new commands work, please visit [OpenFPGA Options FPGA-SPICE](https://openfpga.readthedocs.io/en/latest/fpga_spice/command_line_usage.html).
As a result, we get a new folder, /verilog_test, which contains the verilog code. The name_top.v contains the full FPGA we just created. Three other folders are created, *lb*, *routing* and *sub_modules*. *lb* contains the different CLBs used in the architecture. *routing* contains the different connection blocks, the switch boxes and the wires. *sub_modules* contains the different modules needed in the architecture.

View File

@ -1,37 +0,0 @@
Ubuntu compilation
==================
*This tutorial has been tested under Ubuntu 18.04*
Clone the [OpenFPGA git repository:](https://github.com/LNIS-Projects/OpenFPGA)
`git clone --recurse-submodules https://github.com/LNIS-Projects/OpenFPGA.git `
[//todo]: # (There is a submodule in the repository so move to the OpenFPGA directory and clone that too:)
[//]: # (`git submodule init`)
[//todo]: # (`git submodule update`)
Go to the `VPR` directory and build the tool:
`cd ./OpenFPGA/vpr7_x2p/vpr/`
`make `
This will generate vpr and a libvpr.a file.
Enhancements of VPR were made.
In order to see them just type:
`./vpr`
This will show the different options that can be used. Our modifications concern the options starting with fpga_spice and fpga_verilog.
A script is already prepared in the folder to test FPGA-SPICE and FPGA-Verilog
`source ./go_fpga_verilog.sh`
This script uses the enhanced version of vpr with some new options such as --fpga_verilog_print_top_testbench which automatically generates a testbench for the full FPGA and --fpga_verilog_dir which allows us to choose the destination directory for the verilog output we generate.
For more informations on how the new commands work, please visit [OpenFPGA Options FPGA-SPICE](https://openfpga.readthedocs.io/en/latest/fpga_spice/command_line_usage.html).
As a result, we get a new folder, /verilog_test, which contains the verilog code. The name_top.v contains the full FPGA we just created. Three other folders are created, *lb*, *routing* and *sub_modules*. *lb* contains the different CLBs used in the architecture. *routing* contains the different connection blocks, the switch boxes and the wires. *sub_modules* contains the different modules needed in the architecture.

View File

@ -397,7 +397,7 @@
<port type="output" prefix="inpad" size="1"/>
</circuit_model>
<!-- Hard logic definition for heterogenous blocks -->
<circuit_model type="hard_logic" name="adder" prefix="adder" dump_explicit_port_map="true" spice_netlist="OPENFPGAPATHKEYWORD/vpr7_x2p/vpr/SpiceNetlists/adder.sp" verilog_netlist="OPENFPGAPATHKEYWORD/vpr7_x2p/vpr/VerilogNetlists/adder.v">
<circuit_model type="hard_logic" name="adder" prefix="adder" dump_explicit_port_map="false" spice_netlist="OPENFPGAPATHKEYWORD/vpr7_x2p/vpr/SpiceNetlists/adder.sp" verilog_netlist="OPENFPGAPATHKEYWORD/vpr7_x2p/vpr/VerilogNetlists/adder.v">
<design_technology type="cmos"/>
<input_buffer exist="on" circuit_model_name="INV1X"/>
<output_buffer exist="on" circuit_model_name="INV1X"/>

View File

@ -18,7 +18,7 @@ dir_keyword="GENERATED_DIR_KEYWORD"
rm -rf ${pwd_path}/results_OpenPithon
cd ${pwd_path}/arch
mkdir generated # create folder to save rewritten architecture
mkdir -p generated # create folder to save rewritten architecture
cd ${pwd_path}/scripts
# Replace keyword in config and architecture files

View File

@ -93,4 +93,4 @@ Once dependancies are understood, we can modify the flow by changing the archite
### Explanation
With this last experiment we replace the [**K6 architecture**](https://github.com/LNIS-Projects/OpenFPGA/blob/master/tutorials/image/architectures_schematics/frac_lut6.pdf) with a [**K8 architecture**](https://github.com/LNIS-Projects/OpenFPGA/blob/master/tutorials/image/architectures_schematics/frac_lut8.pdf), which means a 8-inputs fracturable LUT (implemented by LUT6 and LUT4 with 2 shared inputs). This architecture provides more modes for the CLB and the crossbar changed from a half-connected to a fully connected, implying bigger multiplexor between the CLB and LUT inputs. These requirement in term of interconnection will lead to the increase in routing channel width. Indeed, if the routing channel is to low, it could be impossible to route a benchmark or the FPGA output can be delayed.
With this last experiment we replace the [**K6 architecture**](https://github.com/LNIS-Projects/OpenFPGA/blob/master/tutorials/images/architectures_schematics/frac_lut6.pdf) with a [**K8 architecture**](https://github.com/LNIS-Projects/OpenFPGA/blob/master/tutorials/images/architectures_schematics/frac_lut8.pdf), which means a 8-inputs fracturable LUT (implemented by LUT6 and LUT4 with 2 shared inputs). This architecture provides more modes for the CLB and the crossbar changed from a half-connected to a fully connected, implying bigger multiplexor between the CLB and LUT inputs. These requirement in term of interconnection will lead to the increase in routing channel width. Indeed, if the routing channel is to low, it could be impossible to route a benchmark or the FPGA output can be delayed.

View File

@ -273,7 +273,7 @@
<port type="input" prefix="Set" size="1" is_global="true" default_val="0" is_set="true"/>
<port type="input" prefix="Reset" size="1" is_global="true" default_val="1" is_reset="true"/>
<port type="output" prefix="Q" size="1"/>
<port type="clock" prefix="clk" size="1" is_global="true" default_val="0" />
<port type="clock" prefix="CK" size="1" is_global="true" default_val="0" />
</circuit_model>
<circuit_model type="lut" name="frac_lut6" prefix="frac_lut6" dump_structural_verilog="true">
<design_technology type="cmos" fracturable_lut="true"/>
@ -300,7 +300,7 @@
<port type="input" prefix="D" size="1"/>
<port type="output" prefix="Q" size="1"/>
<port type="output" prefix="Qb" size="1"/>
<port type="clock" prefix="prog_clk" size="1" is_global="true" default_val="0" is_prog="true"/>
<port type="clock" prefix="prog_CK" size="1" is_global="true" default_val="0" is_prog="true"/>
</circuit_model>
<circuit_model type="iopad" name="iopad" prefix="iopad" spice_netlist="/research/ece/lnis/USERS/alacchi/Current_release/OpenFPGA/vpr7_x2p/vpr/SpiceNetlists/io.sp" verilog_netlist="/research/ece/lnis/USERS/alacchi/Current_release/OpenFPGA/vpr7_x2p/vpr/VerilogNetlists/io.v">
<design_technology type="cmos"/>
@ -515,7 +515,7 @@
<input name="cin" num_pins="1"/>
<output name="O" num_pins="20" equivalent="false"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<clock name="CK" num_pins="1"/>
<!-- Describe fracturable logic element.
Each fracturable logic element has a 6-LUT that can alternatively operate as two 5-LUTs with shared inputs.
@ -526,7 +526,7 @@
<input name="cin" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<clock name="CK" num_pins="1"/>
<mode name="fle_phy" disabled_in_packing="true">
<pb_type name="frac_logic" num_pb="1">
@ -571,12 +571,12 @@
<pb_type name="ff_phy" blif_model=".latch" num_pb="2" class="flipflop" circuit_model_name="static_dff">
<input name="D" num_pins="1" port_class="D"/>
<output name="Q" num_pins="1" port_class="Q"/>
<clock name="clk" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff_phy.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff_phy.Q" clock="clk"/>
<clock name="CK" num_pins="1" port_class="clock"/>
<T_setup value="66e-12" port="ff_phy.D" clock="CK"/>
<T_clock_to_Q max="124e-12" port="ff_phy.Q" clock="CK"/>
</pb_type>
<interconnect>
<complete name="direct_clk" input="fle.clk" output="ff_phy[1:0].clk"/>
<complete name="direct_CK" input="fle.CK" output="ff_phy[1:0].CK"/>
<direct name="direct_in" input="fle.in[5:0]" output="frac_logic.in[5:0]"/>
<direct name="direct_cin" input="fle.cin" output="frac_logic.cin"/>
<direct name="direct_cout" input="frac_logic.cout" output="fle.cout"/>
@ -595,18 +595,18 @@
<input name="cin" num_pins="1"/>
<output name="out" num_pins="2"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<clock name="CK" num_pins="1"/>
<pb_type name="ble5" num_pb="2" idle_mode_name="blut5">
<input name="in" num_pins="5"/>
<input name="cin" num_pins="1"/>
<output name="out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<clock name="CK" num_pins="1"/>
<mode name="blut5">
<pb_type name="flut5" num_pb="1">
<input name="in" num_pins="5"/>
<output name="out" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<clock name="CK" num_pins="1"/>
<!-- Regular LUT mode -->
<pb_type name="lut5" blif_model=".names" num_pb="1" class="lut" mode_bits="01" physical_pb_type_name="frac_lut6" physical_pb_type_index_factor="0.5">
<input name="in" num_pins="5" port_class="lut_in" physical_mode_pin="in[5:0]"/>
@ -632,16 +632,16 @@
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop" physical_pb_type_name="ff_phy">
<input name="D" num_pins="1" port_class="D" physical_mode_pin="D"/>
<output name="Q" num_pins="1" port_class="Q" physical_mode_pin="Q"/>
<clock name="clk" num_pins="1" port_class="clock" physical_mode_pin="clk"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
<clock name="CK" num_pins="1" port_class="clock" physical_mode_pin="CK"/>
<T_setup value="66e-12" port="ff.D" clock="CK"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="CK"/>
</pb_type>
<interconnect>
<direct name="direct1" input="flut5.in" output="lut5.in"/>
<direct name="direct2" input="lut5.out" output="ff.D">
<pack_pattern name="ble5" in_port="lut5.out" out_port="ff.D"/>
</direct>
<direct name="direct3" input="flut5.clk" output="ff.clk"/>
<direct name="direct3" input="flut5.CK" output="ff.CK"/>
<mux name="mux1" input="ff.Q lut5.out" output="flut5.out" spice_model_sram_offset="0">
<delay_constant max="25e-12" in_port="lut5.out" out_port="flut5.out" />
<delay_constant max="45e-12" in_port="ff.Q" out_port="flut5.out" />
@ -650,7 +650,7 @@
</pb_type>
<interconnect>
<direct name="direct1" input="ble5.in" output="flut5.in"/>
<direct name="direct2" input="ble5.clk" output="flut5.clk"/>
<direct name="direct2" input="ble5.CK" output="flut5.CK"/>
<direct name="direct3" input="flut5.out" output="ble5.out"/>
</interconnect>
</mode>
@ -660,7 +660,7 @@
<input name="cin" num_pins="1"/>
<output name="out" num_pins="1"/>
<output name="cout" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<clock name="CK" num_pins="1"/>
<!-- Special dual-LUT mode that drives adder only -->
<pb_type name="lut4" blif_model=".names" num_pb="2" class="lut" mode_bits="11" physical_pb_type_name="frac_lut6" physical_pb_type_index_factor="0.25">
<input name="in" num_pins="4" port_class="lut_in" physical_mode_pin="in[4:0]"/>
@ -696,12 +696,12 @@
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop" physical_pb_type_name="ff_phy">
<input name="D" num_pins="1" port_class="D" physical_mode_pin="D"/>
<output name="Q" num_pins="1" port_class="Q" physical_mode_pin="Q"/>
<clock name="clk" num_pins="1" port_class="clock" physical_mode_pin="clk"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
<clock name="CK" num_pins="1" port_class="clock" physical_mode_pin="CK"/>
<T_setup value="66e-12" port="ff.D" clock="CK"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="CK"/>
</pb_type>
<interconnect>
<direct name="clock" input="arithmetic.clk" output="ff.clk"/>
<direct name="clock" input="arithmetic.CK" output="ff.CK"/>
<direct name="lut_in1" input="arithmetic.in[3:0]" output="lut4[0:0].in[3:0]"/>
<direct name="lut_in2" input="arithmetic.in[3:0]" output="lut4[1:1].in[3:0]"/>
<direct name="lut_to_add1" input="lut4[0:0].out" output="adder.a">
@ -732,7 +732,7 @@
<direct name="carry_out" input="arithmetic.cout" output="ble5.cout">
<pack_pattern name="chain" in_port="arithmetic.cout" out_port="ble5.cout"/>
</direct>
<direct name="direct2" input="ble5.clk" output="arithmetic.clk"/>
<direct name="direct2" input="ble5.CK" output="arithmetic.CK"/>
<direct name="direct3" input="arithmetic.out" output="ble5.out"/>
</interconnect>
</mode>
@ -750,13 +750,13 @@
<direct name="carry_link" input="ble5[0:0].cout" output="ble5[1:1].cin">
<pack_pattern name="chain" in_port="ble5[0:0].cout" out_port="ble5[1:1].cout"/>
</direct>
<complete name="complete1" input="lut5inter.clk" output="ble5[1:0].clk"/>
<complete name="complete1" input="lut5inter.CK" output="ble5[1:0].CK"/>
</interconnect>
</pb_type>
<interconnect>
<direct name="direct1" input="fle.in[4:0]" output="lut5inter.in"/>
<direct name="direct2" input="lut5inter.out" output="fle.out"/>
<direct name="direct3" input="fle.clk" output="lut5inter.clk"/>
<direct name="direct3" input="fle.CK" output="lut5inter.CK"/>
<direct name="carry_in" input="fle.cin" output="lut5inter.cin">
<pack_pattern name="chain" in_port="fle.cin" out_port="lut5inter.cin"/>
</direct>
@ -769,7 +769,7 @@
<pb_type name="ble6" num_pb="1">
<input name="in" num_pins="6"/>
<output name="out" num_pins="1"/>
<clock name="clk" num_pins="1"/>
<clock name="CK" num_pins="1"/>
<pb_type name="lut6" blif_model=".names" num_pb="1" class="lut" mode_bits="00" physical_pb_type_name="frac_lut6" spice_model_sram_offset="0">
<input name="in" num_pins="6" port_class="lut_in" physical_mode_pin="in[5:0]"/>
<output name="out" num_pins="1" port_class="lut_out" physical_mode_pin="lut6_out[0]"/>
@ -795,9 +795,9 @@
<pb_type name="ff" blif_model=".latch" num_pb="1" class="flipflop" physical_pb_type_name="ff_phy" physical_pb_type_index_factor="2" physical_pb_type_index_offset="1">
<input name="D" num_pins="1" port_class="D" physical_mode_pin="D"/>
<output name="Q" num_pins="1" port_class="Q" physical_mode_pin="Q"/>
<clock name="clk" num_pins="1" port_class="clock" physical_mode_pin="clk"/>
<T_setup value="66e-12" port="ff.D" clock="clk"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="clk"/>
<clock name="CK" num_pins="1" port_class="clock" physical_mode_pin="CK"/>
<T_setup value="66e-12" port="ff.D" clock="CK"/>
<T_clock_to_Q max="124e-12" port="ff.Q" clock="CK"/>
</pb_type>
<interconnect>
@ -805,7 +805,7 @@
<direct name="direct2" input="lut6.out" output="ff.D">
<pack_pattern name="ble6" in_port="lut6.out" out_port="ff.D"/>
</direct>
<direct name="direct3" input="ble6.clk" output="ff.clk"/>
<direct name="direct3" input="ble6.CK" output="ff.CK"/>
<mux name="mux1" input="ff.Q lut6.out" output="ble6.out">
<delay_constant max="25e-12" in_port="lut6.out" out_port="ble6.out" />
<delay_constant max="45e-12" in_port="ff.Q" out_port="ble6.out" />
@ -815,7 +815,7 @@
<interconnect>
<direct name="direct1" input="fle.in" output="ble6.in"/>
<direct name="direct2" input="ble6.out" output="fle.out[1:1]"/>
<direct name="direct3" input="fle.clk" output="ble6.clk"/>
<direct name="direct3" input="fle.CK" output="ble6.CK"/>
</interconnect>
</mode> <!-- n1_lut6 -->
</pb_type>
@ -833,7 +833,7 @@
<delay_constant max="95e-12" in_port="clb.I" out_port="fle[9:0].in" />
<delay_constant max="75e-12" in_port="fle[9:0].out" out_port="fle[9:0].in" />
</complete>
<complete name="clks" input="clb.clk" output="fle[9:0].clk">
<complete name="CKs" input="clb.CK" output="fle[9:0].CK">
</complete>
<!-- This way of specifying direct connection to clb outputs is important because this architecture uses automatic spreading of opins.

View File

@ -1143,17 +1143,26 @@ void sort_rr_gsb_one_ipin_node_drive_rr_nodes(const RRGSB& rr_gsb,
/* Create a copy of the edges and switches of this node */
std::vector<t_rr_node*> sorted_drive_nodes;
std::vector<int> sorted_drive_switches;
std::vector<int> sorted_drive_nodes_chan_node_index;
/* Ensure a clean start */
sorted_drive_nodes.clear();
sorted_drive_switches.clear();
/* Ensure a clean start and avoid frequent realloc */
sorted_drive_nodes.reserve(ipin_node->num_drive_rr_nodes);
sorted_drive_switches.reserve(ipin_node->num_drive_rr_nodes);
sorted_drive_nodes_chan_node_index.reserve(ipin_node->num_drive_rr_nodes);
/* Build the vectors w.r.t. to the order of node_type and ptc_num */
for (int i_from_node = 0; i_from_node < ipin_node->num_drive_rr_nodes; ++i_from_node) {
int i_from_node_track_index = rr_gsb.get_chan_node_index(ipin_chan_side, ipin_node->drive_rr_nodes[i_from_node]);
/* We must have a valide node index for CHANX and CHANY */
if ( (CHANX == ipin_node->drive_rr_nodes[i_from_node]->type)
|| (CHANY == ipin_node->drive_rr_nodes[i_from_node]->type) ) {
assert (-1 != i_from_node_track_index);
}
/* For blank edges: directly push_back */
if (0 == sorted_drive_nodes.size()) {
sorted_drive_nodes.push_back(ipin_node->drive_rr_nodes[i_from_node]);
sorted_drive_switches.push_back(ipin_node->drive_switches[i_from_node]);
sorted_drive_nodes_chan_node_index.push_back(i_from_node_track_index);
continue;
}
@ -1167,12 +1176,8 @@ void sort_rr_gsb_one_ipin_node_drive_rr_nodes(const RRGSB& rr_gsb,
break; /* least type should stay in the front of the vector */
} else if (ipin_node->drive_rr_nodes[i_from_node]->type
== sorted_drive_nodes[j_from_node]->type) {
int i_from_node_track_index = rr_gsb.get_chan_node_index(ipin_chan_side, ipin_node->drive_rr_nodes[i_from_node]);
int j_from_node_track_index = rr_gsb.get_chan_node_index(ipin_chan_side, sorted_drive_nodes[j_from_node]);
/* We must have a valide node index */
assert ( (-1 != i_from_node_track_index) && (-1 != j_from_node_track_index) );
/* Now a lower ptc_num will win */
if ( i_from_node_track_index < j_from_node_track_index ) {
if ( i_from_node_track_index < sorted_drive_nodes_chan_node_index[j_from_node] ) {
insert_pos = j_from_node;
break; /* least type should stay in the front of the vector */
}
@ -1181,6 +1186,7 @@ void sort_rr_gsb_one_ipin_node_drive_rr_nodes(const RRGSB& rr_gsb,
/* We find the position, inserted to the vector */
sorted_drive_nodes.insert(sorted_drive_nodes.begin() + insert_pos, ipin_node->drive_rr_nodes[i_from_node]);
sorted_drive_switches.insert(sorted_drive_switches.begin() + insert_pos, ipin_node->drive_switches[i_from_node]);
sorted_drive_nodes_chan_node_index.insert(sorted_drive_nodes_chan_node_index.begin() + insert_pos, i_from_node_track_index);
}
/* Overwrite the edges and switches with sorted numbers */
@ -1213,17 +1219,26 @@ void sort_rr_gsb_one_chan_node_drive_rr_nodes(const RRGSB& rr_gsb,
/* Create a copy of the edges and switches of this node */
std::vector<t_rr_node*> sorted_drive_nodes;
std::vector<int> sorted_drive_switches;
std::vector<int> sorted_drive_nodes_from_node_index;
/* Ensure a clean start */
sorted_drive_nodes.clear();
sorted_drive_switches.clear();
/* Ensure a clean start and avoid frequent realloc */
sorted_drive_nodes.reserve(chan_node->num_drive_rr_nodes);
sorted_drive_switches.reserve(chan_node->num_drive_rr_nodes);
sorted_drive_nodes_from_node_index.reserve(chan_node->num_drive_rr_nodes);
/* Build the vectors w.r.t. to the order of node_type and ptc_num */
for (int i_from_node = 0; i_from_node < chan_node->num_drive_rr_nodes; ++i_from_node) {
enum e_side i_from_node_side = NUM_SIDES;
int i_from_node_index = -1;
rr_gsb.get_node_side_and_index(chan_node->drive_rr_nodes[i_from_node],
IN_PORT, &i_from_node_side, &i_from_node_index);
/* check */
assert ( (NUM_SIDES != i_from_node_side) && (-1 != i_from_node_index) );
/* For blank edges: directly push_back */
if (0 == sorted_drive_nodes.size()) {
sorted_drive_nodes.push_back(chan_node->drive_rr_nodes[i_from_node]);
sorted_drive_switches.push_back(chan_node->drive_switches[i_from_node]);
sorted_drive_nodes_from_node_index.push_back(i_from_node_index);
continue;
}
@ -1241,22 +1256,9 @@ void sort_rr_gsb_one_chan_node_drive_rr_nodes(const RRGSB& rr_gsb,
* But we are pretty sure it is either IN_PORT or OUT_PORT
* So we just try and find what is valid
*/
enum e_side i_from_node_side = NUM_SIDES;
int i_from_node_index = -1;
rr_gsb.get_node_side_and_index(chan_node->drive_rr_nodes[i_from_node],
IN_PORT, &i_from_node_side, &i_from_node_index);
/* check */
if (! ( (NUM_SIDES != i_from_node_side) && (-1 != i_from_node_index) ) )
assert ( (NUM_SIDES != i_from_node_side) && (-1 != i_from_node_index) );
enum e_side j_from_node_side = NUM_SIDES;
int j_from_node_index = -1;
rr_gsb.get_node_side_and_index(sorted_drive_nodes[j_from_node],
IN_PORT, &j_from_node_side, &j_from_node_index);
/* check */
assert ( (NUM_SIDES != j_from_node_side) && (-1 != j_from_node_index) );
/* Now a lower ptc_num will win */
if ( i_from_node_index < j_from_node_index) {
if ( i_from_node_index < sorted_drive_nodes_from_node_index[j_from_node]) {
insert_pos = j_from_node;
break; /* least type should stay in the front of the vector */
}
@ -1265,6 +1267,7 @@ void sort_rr_gsb_one_chan_node_drive_rr_nodes(const RRGSB& rr_gsb,
/* We find the position, inserted to the vector */
sorted_drive_nodes.insert(sorted_drive_nodes.begin() + insert_pos, chan_node->drive_rr_nodes[i_from_node]);
sorted_drive_switches.insert(sorted_drive_switches.begin() + insert_pos, chan_node->drive_switches[i_from_node]);
sorted_drive_nodes_from_node_index.insert(sorted_drive_nodes_from_node_index.begin() + insert_pos, i_from_node_index);
}
/* Overwrite the edges and switches with sorted numbers */
@ -1339,9 +1342,11 @@ DeviceRRGSB build_device_rr_gsb(boolean output_sb_xml, char* sb_xml_dir,
DeviceCoordinator reserve_range((size_t)nx + 1, (size_t)ny + 1);
LL_device_rr_gsb.reserve(reserve_range);
size_t gsb_cnt = 0;
/* For each switch block, determine the size of array */
for (size_t ix = 0; ix <= sb_range.get_x(); ++ix) {
for (size_t iy = 0; iy <= sb_range.get_y(); ++iy) {
gsb_cnt++; /* Update counter */
const RRGSB& rr_gsb = build_rr_gsb(sb_range, ix, iy,
LL_num_rr_nodes, LL_rr_node,
LL_rr_node_indices,
@ -1358,6 +1363,11 @@ DeviceRRGSB build_device_rr_gsb(boolean output_sb_xml, char* sb_xml_dir,
/* Add to device_rr_gsb */
DeviceCoordinator sb_coordinator = rr_gsb.get_sb_coordinator();
LL_device_rr_gsb.add_rr_gsb(sb_coordinator, rr_gsb);
/* Print info */
vpr_printf(TIO_MESSAGE_INFO,
"[%lu%] Backannotated GSB[%lu][%lu]\r",
100 * gsb_cnt / ((sb_range.get_x() + 1)* (sb_range.get_y() + 1)),
ix, iy );
}
}
/* Report number of unique mirrors */
@ -1369,9 +1379,9 @@ DeviceRRGSB build_device_rr_gsb(boolean output_sb_xml, char* sb_xml_dir,
t_end = clock();
run_time_sec = (float)(t_end - t_start) / CLOCKS_PER_SEC;
vpr_printf(TIO_MESSAGE_INFO, "Edge sorting for Switch Block took %g seconds\n", run_time_sec_profiling);
vpr_printf(TIO_MESSAGE_INFO, "Backannotation of Switch Block took %g seconds\n\n", run_time_sec);
vpr_printf(TIO_MESSAGE_INFO, "Edge sorting for Switch Block took %g seconds\n\n", run_time_sec_profiling);
if (TRUE == output_sb_xml) {

View File

@ -2432,7 +2432,7 @@ const RRGSB DeviceRRGSB::get_sb_unique_module(size_t index) const {
}
/* Get a rr switch block which a unique mirror */
const RRGSB DeviceRRGSB::get_cb_unique_module(t_rr_type cb_type, size_t index) const {
const RRGSB& DeviceRRGSB::get_cb_unique_module(t_rr_type cb_type, size_t index) const {
assert (validate_cb_unique_module_index(cb_type, index));
assert (validate_cb_type(cb_type));
switch(cb_type) {
@ -2449,7 +2449,7 @@ const RRGSB DeviceRRGSB::get_cb_unique_module(t_rr_type cb_type, size_t index) c
}
/* Give a coordinator of a rr switch block, and return its unique mirror */
const RRGSB DeviceRRGSB::get_cb_unique_module(t_rr_type cb_type, DeviceCoordinator& coordinator) const {
const RRGSB& DeviceRRGSB::get_cb_unique_module(t_rr_type cb_type, DeviceCoordinator& coordinator) const {
assert (validate_cb_type(cb_type));
assert(validate_coordinator(coordinator));
size_t cb_unique_module_id;
@ -2659,7 +2659,8 @@ void DeviceRRGSB::build_cb_unique_module(t_rr_type cb_type) {
/* Traverse the unique_mirror list and check it is an mirror of another */
for (size_t id = 0; id < get_num_cb_unique_module(cb_type); ++id) {
if (true == rr_gsb_[ix][iy].is_cb_mirror(get_cb_unique_module(cb_type, id), cb_type)) {
const RRGSB& unique_module = get_cb_unique_module(cb_type, id);
if (true == rr_gsb_[ix][iy].is_cb_mirror(unique_module, cb_type)) {
/* This is a mirror, raise the flag and we finish */
is_unique_module = false;
/* Record the id of unique mirror */
@ -3109,7 +3110,7 @@ bool DeviceRRGSB::validate_cb_unique_module_index(t_rr_type cb_type, size_t inde
}
return true;
case CHANY:
if (index >= cbx_unique_module_.size()) {
if (index >= cby_unique_module_.size()) {
return false;
}
return true;

View File

@ -339,8 +339,8 @@ class DeviceRRGSB {
const RRGSB get_sb_unique_submodule(DeviceCoordinator& coordinator, enum e_side side, size_t seg_id) const; /* Get a rr switch block which a unique mirror */
const RRGSB get_sb_unique_module(size_t index) const; /* Get a rr switch block which a unique mirror */
const RRGSB get_sb_unique_module(DeviceCoordinator& coordinator) const; /* Get a rr switch block which a unique mirror */
const RRGSB get_cb_unique_module(t_rr_type cb_type, size_t index) const; /* Get a rr switch block which a unique mirror */
const RRGSB get_cb_unique_module(t_rr_type cb_type, DeviceCoordinator& coordinator) const;
const RRGSB& get_cb_unique_module(t_rr_type cb_type, size_t index) const; /* Get a rr switch block which a unique mirror */
const RRGSB& get_cb_unique_module(t_rr_type cb_type, DeviceCoordinator& coordinator) const;
size_t get_max_num_sides() const; /* Get the maximum number of sides across the switch blocks */
size_t get_num_segments() const; /* Get the size of segment_ids */
size_t get_segment_id(size_t index) const; /* Get a segment id */

View File

@ -1340,7 +1340,8 @@ void dump_compact_verilog_top_netlist(t_sram_orgz_info* cur_sram_orgz_info,
dump_verilog_clb2clb_directs(fp, num_clb2clb_directs, clb2clb_direct);
/* Dump configuration circuits */
dump_verilog_configuration_circuits(cur_sram_orgz_info, fp);
dump_verilog_configuration_circuits(cur_sram_orgz_info, fp,
is_explicit_mapping);
/* verilog ends*/
fprintf(fp, "endmodule\n");

View File

@ -1072,6 +1072,10 @@ void dump_verilog_pb_graph_pin_interc(t_sram_orgz_info* cur_sram_orgz_info,
char* mem_subckt_name = NULL;
char* hierarchical_name = NULL;
char* mux_name = NULL;
int num_input_port;
int num_output_port;
t_spice_model_port** input_port;
t_spice_model_port** output_port;
/* Check the file handler*/
if (NULL == fp) {
@ -1087,6 +1091,8 @@ void dump_verilog_pb_graph_pin_interc(t_sram_orgz_info* cur_sram_orgz_info,
fan_in = 0;
cur_interc = NULL;
find_interc_fan_in_des_pb_graph_pin(des_pb_graph_pin, cur_mode, &cur_interc, &fan_in);
input_port = find_spice_model_ports(cur_interc->spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE);
output_port = find_spice_model_ports(cur_interc->spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE);
if ((NULL == cur_interc)||(0 == fan_in)) {
/* No interconnection matched */
/* Connect this pin to GND for better convergence */
@ -1136,7 +1142,7 @@ void dump_verilog_pb_graph_pin_interc(t_sram_orgz_info* cur_sram_orgz_info,
fprintf(fp, "%s_%d_ (", cur_interc->spice_model->prefix, cur_interc->spice_model->cnt);
cur_interc->spice_model->cnt++; /* Stats the number of spice_model used*/
/* Dump global ports */
if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_interc->spice_model, FALSE, FALSE, FALSE)) {
if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_interc->spice_model, FALSE, FALSE, my_bool_to_boolean(is_explicit_mapping))) {
fprintf(fp, ",\n");
}
/* Print the pin names! Input and output
@ -1147,11 +1153,26 @@ void dump_verilog_pb_graph_pin_interc(t_sram_orgz_info* cur_sram_orgz_info,
/* Make sure correctness*/
assert(src_pb_type == des_pb_graph_pin->input_edges[iedge]->input_pins[0]->port->parent_pb_type);
/* Print */
fprintf(fp, "%s__%s_%d_, ",
if (true == is_explicit_mapping) {
fprintf(fp, ".%s(",
input_port[0]->prefix);
}
fprintf(fp, "%s__%s_%d_",
src_pin_prefix, src_pb_graph_pin->port->name, src_pb_graph_pin->pin_number);
if (true == is_explicit_mapping) {
fprintf(fp, ")");
}
fprintf(fp, ", ");
/* Output */
if (true == is_explicit_mapping) {
fprintf(fp, ".%s(",
output_port[0]->prefix);
}
fprintf(fp, "%s__%s_%d_",
des_pin_prefix, des_pb_graph_pin->port->name, des_pb_graph_pin->pin_number);
if (true == is_explicit_mapping) {
fprintf(fp, ")");
}
/* Middle output for wires in logic blocks: TODO: Abolish to save simulation time */
/* fprintf(fp, "gidle_mid_out "); */
/* Local vdd and gnd, TODO: we should have an independent VDD for all local interconnections*/
@ -1257,19 +1278,35 @@ void dump_verilog_pb_graph_pin_interc(t_sram_orgz_info* cur_sram_orgz_info,
fprintf(fp, "%s_size%d ", cur_interc->spice_model->name, fan_in);
fprintf(fp, "%s_size%d_%d_ (", cur_interc->spice_model->prefix, fan_in, cur_interc->spice_model->cnt);
/* Dump global ports */
if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_interc->spice_model, FALSE, FALSE, FALSE)) {
if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_interc->spice_model, FALSE, FALSE, my_bool_to_boolean(is_explicit_mapping))) {
fprintf(fp, ",\n");
}
/* Inputs */
fprintf(fp, "in_bus_%s_size%d_%d_, ",
if (true == is_explicit_mapping) {
fprintf(fp, ".%s(",
input_port[0]->prefix);
}
fprintf(fp, "in_bus_%s_size%d_%d_",
cur_interc->spice_model->name, fan_in, cur_interc->spice_model->cnt);
if (true == is_explicit_mapping) {
fprintf(fp, ")");
}
fprintf(fp, ", ");
/* Generate the pin_prefix for src_pb_graph_node and des_pb_graph_node*/
if (true == is_explicit_mapping) {
fprintf(fp, ".%s(",
output_port[0]->prefix);
}
generate_verilog_src_des_pb_graph_pin_prefix(src_pb_graph_pin, des_pb_graph_pin, pin2pin_interc_type,
cur_interc, formatted_parent_pin_prefix, &src_pin_prefix, &des_pin_prefix);
des_pin_prefix = chomp_verilog_prefix(des_pin_prefix);
/* Outputs */
fprintf(fp, "%s__%s_%d_, ",
fprintf(fp, "%s__%s_%d_",
des_pin_prefix, des_pb_graph_pin->port->name, des_pb_graph_pin->pin_number);
if (true == is_explicit_mapping) {
fprintf(fp, ")");
}
fprintf(fp, ", ");
/* Different design technology requires different configuration bus! */
dump_verilog_mux_config_bus_ports(fp, cur_interc->spice_model, cur_sram_orgz_info,
@ -1853,13 +1890,8 @@ void dump_verilog_phy_pb_graph_node_rec(t_sram_orgz_info* cur_sram_orgz_info,
/* Print inputs, outputs, inouts, clocks
* NO SRAMs !!! They have already been fixed in the bottom level
*/
bool is_explicit_full_name = true;
if (NULL != cur_pb_type->modes[mode_index].pb_type_children[ipb].spice_model){
/*if (SPICE_MODEL_HARDLOGIC == cur_pb_type->modes[mode_index].pb_type_children[ipb].spice_model->type){
is_explicit_full_name = false;
}TEST*/
}
dump_verilog_pb_type_ports(fp, child_pb_type_prefix, 0, &(cur_pb_type->modes[mode_index].pb_type_children[ipb]), FALSE, FALSE, my_bool_to_boolean(is_explicit_mapping), is_explicit_full_name);
//}
dump_verilog_pb_type_ports(fp, child_pb_type_prefix, 0, &(cur_pb_type->modes[mode_index].pb_type_children[ipb]), FALSE, FALSE, my_bool_to_boolean(is_explicit_mapping), true);
/* Print I/O pads */
dump_verilog_grid_common_port(fp, iopad_verilog_model,
gio_inout_prefix,
@ -1906,7 +1938,7 @@ void dump_verilog_phy_pb_graph_node_rec(t_sram_orgz_info* cur_sram_orgz_info,
/* Print interconnections, set is_idle as TRUE*/
dump_verilog_pb_graph_interc(cur_sram_orgz_info, fp, subckt_name,
cur_pb_graph_node, mode_index,
false);
is_explicit_mapping);
/* Check each pins of pb_graph_node */
/* Check and update stamped_sram_cnt */
/* Now we only dump one Verilog for each pb_type, and instance them when num_pb > 1

View File

@ -184,7 +184,6 @@ void dump_verilog_pb_generic_primitive(t_sram_orgz_info* cur_sram_orgz_info,
dump_verilog_sram_config_bus_internal_wires(fp, cur_sram_orgz_info,
cur_num_sram, cur_num_sram + num_sram - 1);
}
if (0 < num_sram_port) {
switch (cur_sram_orgz_info->type) {
case SPICE_SRAM_MEMORY_BANK:
@ -234,6 +233,7 @@ void dump_verilog_pb_generic_primitive(t_sram_orgz_info* cur_sram_orgz_info,
/* Only dump the global ports belonging to a spice_model
* Disable recursive here !
*/
/*if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, FALSE, FALSE, my_bool_to_boolean(is_explicit_mapping))) {*/
if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, FALSE, FALSE, subckt_require_explicit_port_map)) {
fprintf(fp, ",\n");
}
@ -243,6 +243,7 @@ void dump_verilog_pb_generic_primitive(t_sram_orgz_info* cur_sram_orgz_info,
/* print ports --> input ports */
dump_verilog_pb_type_bus_ports(fp, port_prefix, 1, prim_pb_type, FALSE, FALSE,
subckt_require_explicit_port_map);
/* my_bool_to_boolean(is_explicit_mapping));*/
/* IOPADs requires a specical port to output */
if (SPICE_MODEL_IOPAD == verilog_model->type) {
fprintf(fp, ",\n");
@ -250,6 +251,7 @@ void dump_verilog_pb_generic_primitive(t_sram_orgz_info* cur_sram_orgz_info,
assert(NULL != pad_ports[0]);
/* Add explicit port mapping if required */
if (TRUE == subckt_require_explicit_port_map) {
/*if (true == is_explicit_mapping) {*/
fprintf(fp, ".%s (",
pad_ports[0]->lib_name);
}
@ -257,6 +259,7 @@ void dump_verilog_pb_generic_primitive(t_sram_orgz_info* cur_sram_orgz_info,
fprintf(fp, "%s%s[%d]", gio_inout_prefix,
verilog_model->prefix, verilog_model->cnt);
if (TRUE == subckt_require_explicit_port_map) {
/*if (true == is_explicit_mapping) {*/
fprintf(fp, ")");
}
fprintf(fp, ", ");
@ -301,7 +304,7 @@ void dump_verilog_pb_generic_primitive(t_sram_orgz_info* cur_sram_orgz_info,
cur_num_sram, cur_num_sram + num_sram - 1,
1, VERILOG_PORT_CONKT);
if ( (0 < num_sram)
&& (TRUE == verilog_model->dump_explicit_port_map || is_explicit_mapping)) {
&& (TRUE == subckt_require_explicit_port_map)) {
fprintf(fp, ")");
}
break;

View File

@ -2740,6 +2740,9 @@ void verilog_generate_routing_wire_report_timing(t_trpt_opts trpt_opts,
vpr_printf(TIO_MESSAGE_INFO,
"Generating TCL script to report timing for routing wires\n");
vpr_printf(TIO_MESSAGE_INFO,
"Generating TCL script to report timing for routing wires horizontal\n");
/* Start with horizontal SBs*/
/* We start from a SB[x][y] */
DeviceCoordinator sb_range = device_rr_gsb.get_gsb_range();
for (size_t ix = 0; ix < sb_range.get_x(); ++ix) {
@ -2759,6 +2762,9 @@ void verilog_generate_routing_wire_report_timing(t_trpt_opts trpt_opts,
if (1 == rr_sb.get_chan_node(side_manager.get_side(), itrack)->num_drive_rr_nodes) {
continue;
}
if (CHANY == rr_sb.get_chan_node(side_manager.get_side(), itrack)->type) {
continue;
}
/* Check if L_wire exists in the linked list */
L_wire = get_rr_node_wire_length(rr_sb.get_chan_node(side_manager.get_side(), itrack));
/* Get counter */
@ -2793,6 +2799,72 @@ void verilog_generate_routing_wire_report_timing(t_trpt_opts trpt_opts,
}
}
/* close file*/
fclose_wire_L_file_handler_in_llist(rr_path_cnt);
/* Need to reset the different variables */
rr_path_cnt = NULL;
wireL_cnt = NULL;
path_cnt = 0;
vpr_printf(TIO_MESSAGE_INFO,
"Generating TCL script to report timing for routing wires vertical\n");
/* Continue with vertical SBs*/
/* We start from a SB[x][y] */
for (size_t ix = 0; ix < sb_range.get_x(); ++ix) {
for (size_t iy = 0; iy < sb_range.get_y(); ++iy) {
const RRGSB& rr_sb = device_rr_gsb.get_gsb(ix, iy);
for (size_t side = 0; side < rr_sb.get_num_sides(); ++side) {
Side side_manager(side);
for (size_t itrack = 0; itrack < rr_sb.get_chan_width(side_manager.get_side()); ++itrack) {
assert((CHANX == rr_sb.get_chan_node(side_manager.get_side(), itrack)->type)
||(CHANY == rr_sb.get_chan_node(side_manager.get_side(), itrack)->type));
/* We only care the output port and it should indicate a SB mux */
if ( (OUT_PORT != rr_sb.get_chan_node_direction(side_manager.get_side(), itrack))
|| (false != rr_sb.is_sb_node_passing_wire(side_manager.get_side(), itrack))) {
continue;
}
/* Bypass if we have only 1 driving node */
if (1 == rr_sb.get_chan_node(side_manager.get_side(), itrack)->num_drive_rr_nodes) {
continue;
}
if (CHANX == rr_sb.get_chan_node(side_manager.get_side(), itrack)->type) {
continue;
}
/* Check if L_wire exists in the linked list */
L_wire = get_rr_node_wire_length(rr_sb.get_chan_node(side_manager.get_side(), itrack));
/* Get counter */
rr_path_cnt = get_wire_L_counter_in_llist(rr_path_cnt, trpt_opts, "vertical", L_wire, &wireL_cnt);
path_cnt = wireL_cnt->cnt;
fp = wireL_cnt->file_handler;
/* This is a new L-wire, create the file handler and the mkdir command to the TCL script */
if (0 == path_cnt) {
fprintf(fp, "exec mkdir -p %s\n",
gen_verilog_one_routing_report_timing_Lwire_dir_path(fpga_verilog_opts.report_timing_path, L_wire));
}
/* Restore the disable_timing for the SB outputs on the path */
/*fprintf(fp, "# Restore disable timing for the following Switch Block output:\n");
restore_disable_timing_one_sb_output(fp,
rr_sb,
rr_sb.get_chan_node(side_manager.get_side(), itrack));*/
fprintf(fp, "# Report timing for all the paths using this output:\n");
/* Dump report_timing command */
verilog_generate_one_routing_segmental_report_timing(fp, fpga_verilog_opts,
rr_sb,
side_manager.get_side(), itrack,
LL_rr_node, "vertical", &path_cnt);
/* Disable the timing again */
/*fprintf(fp, "# Set disable timing for the following Switch Block output:\n");
set_disable_timing_one_sb_output(fp,
rr_sb,
rr_sb.get_chan_node(side_manager.get_side(), itrack));*/
/* Update the wire L*/
update_wire_L_counter_in_llist(rr_path_cnt, L_wire, path_cnt);
}
}
}
}
/* close file*/
fclose_wire_L_file_handler_in_llist(rr_path_cnt);

View File

@ -981,6 +981,7 @@ void dump_verilog_unique_switch_box_mux(t_sram_orgz_info* cur_sram_orgz_info,
int cur_bl, cur_wl;
t_spice_model* mem_model = NULL;
char* mem_subckt_name = NULL;
int num_input_port, num_output_port, num_sram_port;
/* Check the file handler*/
if (NULL == fp) {
@ -1096,8 +1097,11 @@ void dump_verilog_unique_switch_box_mux(t_sram_orgz_info* cur_sram_orgz_info,
fprintf(fp, ",\n");
}
t_spice_model_port** input_port = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE);
t_spice_model_port** output_port = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE);
if (TRUE == is_explicit_mapping) {
fprintf(fp, ".in(");
fprintf(fp, ".%s(",
input_port[0]->prefix);
fprintf(fp, "%s_size%d_%d_inbus), ",
verilog_model->prefix, mux_size, verilog_model->cnt);
}
@ -1107,7 +1111,8 @@ void dump_verilog_unique_switch_box_mux(t_sram_orgz_info* cur_sram_orgz_info,
}
/* Output port */
if (TRUE == is_explicit_mapping) {
fprintf(fp, ".out(");
fprintf(fp, ".%s(",
output_port[0]->prefix);
dump_verilog_unique_switch_box_chan_port(fp, rr_sb, chan_side, cur_rr_node, OUT_PORT);
fprintf(fp, ")");
}
@ -1453,6 +1458,10 @@ void dump_verilog_unique_switch_box_interc(t_sram_orgz_info* cur_sram_orgz_info,
} else {
num_drive_rr_nodes = cur_rr_node->num_drive_rr_nodes;
drive_rr_nodes = cur_rr_node->drive_rr_nodes;
/* Special: if there are zero-driver nodes. We skip here */
if (0 == num_drive_rr_nodes) {
return;
}
}
if (0 == num_drive_rr_nodes) {

View File

@ -2732,12 +2732,13 @@ void verilog_generate_sdc_pnr(t_sram_orgz_info* cur_sram_orgz_info,
}
/* Part 5. Output routing constraints for Connection Blocks */
if (TRUE == sdc_opts.constrain_routing_channels) {
/* BC: Might not be useful as it constrains nets which are assigned too*/
/*if (TRUE == sdc_opts.constrain_routing_channels) {
verilog_generate_sdc_constrain_routing_channels(sdc_opts, arch,
LL_nx, LL_ny,
LL_num_rr_nodes, LL_rr_node,
LL_rr_node_indices, LL_rr_indexed_data);
}
}*/
/* Part 6. Output routing constraints for Programmable blocks */
if (TRUE == sdc_opts.constrain_pbs) {

View File

@ -722,8 +722,10 @@ void dump_verilog_cmos_mux_one_basis_module_structural(FILE* fp,
t_spice_model* tgate_spice_model = cur_spice_model->pass_gate_logic->spice_model;
int num_input_port = 0;
int num_output_port = 0;
int num_sram_port = 0;
t_spice_model_port** input_port = NULL;
t_spice_model_port** output_port = NULL;
t_spice_model_port** sram_port = NULL;
assert(TRUE == cur_spice_model->dump_structural_verilog);
@ -737,6 +739,7 @@ void dump_verilog_cmos_mux_one_basis_module_structural(FILE* fp,
assert ( NULL != tgate_spice_model);
input_port = find_spice_model_ports(tgate_spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE);
output_port = find_spice_model_ports(tgate_spice_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE);
sram_port = find_spice_model_ports(tgate_spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE);
/* Check */
assert ((3 == num_input_port));
@ -764,9 +767,9 @@ void dump_verilog_cmos_mux_one_basis_module_structural(FILE* fp,
fprintf(fp, "input [0:%d] in,\n", num_input_basis_subckt - 1);
fprintf(fp, "output out,\n");
fprintf(fp, "input [0:%d] mem,\n",
num_mem - 1);
num_mem - 1/*, sram_port[0]->prefix*/);
fprintf(fp, "input [0:%d] mem_inv);\n",
num_mem - 1);
num_mem - 1/*, sram_port[0]->prefix*/);
/* Verilog Behavior description for a MUX */
fprintf(fp, "//---- Structure-level description -----\n");
/* Special case: only one memory, switch case is simpler
@ -1678,7 +1681,8 @@ void dump_verilog_cmos_mux_submodule(FILE* fp,
switch (cur_mux_structure) {
case SPICE_MODEL_STRUCTURE_TREE:
dump_verilog_cmos_mux_tree_structure(fp, mux_basis_subckt_name,
spice_model, spice_mux_arch, num_sram_port, sram_port, is_explicit_mapping);
spice_model, spice_mux_arch,
num_sram_port, sram_port, is_explicit_mapping);
break;
case SPICE_MODEL_STRUCTURE_ONELEVEL:
dump_verilog_cmos_mux_onelevel_structure(fp, mux_basis_subckt_name,

View File

@ -1069,7 +1069,8 @@ void dump_verilog_configuration_circuits_standalone_srams(t_sram_orgz_info* cur_
*/
static
void dump_verilog_configuration_circuits_scan_chains(t_sram_orgz_info* cur_sram_orgz_info,
FILE* fp) {
FILE* fp,
bool is_explicit_mapping) {
int num_mem_bits = 0;
/* Check */
@ -1088,12 +1089,31 @@ void dump_verilog_configuration_circuits_scan_chains(t_sram_orgz_info* cur_sram_
verilog_config_peripheral_prefix,
verilog_config_peripheral_prefix);
/* Scan-chain input*/
if (true == is_explicit_mapping) {
fprintf(fp, ".%s (",
top_netlist_scan_chain_head_prefix);
}
dump_verilog_generic_port(fp, VERILOG_PORT_CONKT,
top_netlist_scan_chain_head_prefix, 0, 0);
if (true == is_explicit_mapping) {
fprintf(fp, ")");
}
fprintf(fp, ",\n");
if (true == is_explicit_mapping) {
fprintf(fp, ".scff_scff_in_local_bus (");
}
dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, 0, num_mem_bits - 1, -1, VERILOG_PORT_CONKT);
if (true == is_explicit_mapping) {
fprintf(fp, ")");
}
fprintf(fp, ",\n");
if (true == is_explicit_mapping) {
fprintf(fp, ".scff_scff_out_local_bus (");
}
dump_verilog_sram_one_local_outport(fp, cur_sram_orgz_info, 0, num_mem_bits - 1, 0, VERILOG_PORT_CONKT);
if (true == is_explicit_mapping) {
fprintf(fp, ")");
}
fprintf(fp, ");\n");
fprintf(fp, "//------ END Configuration peripheral Scan-chain FFs -----\n");
@ -1103,7 +1123,8 @@ void dump_verilog_configuration_circuits_scan_chains(t_sram_orgz_info* cur_sram_
/* Dump a memory bank to configure all the Bit lines and Word lines */
static
void dump_verilog_configuration_circuits_memory_bank(FILE* fp,
t_sram_orgz_info* cur_sram_orgz_info) {
t_sram_orgz_info* cur_sram_orgz_info,
bool is_explicit_mapping) {
int num_bl, num_wl;
int num_reserved_bl, num_reserved_wl;
int num_array_bl, num_array_wl;
@ -1210,16 +1231,18 @@ void dump_verilog_configuration_circuits_memory_bank(FILE* fp,
* 3. Standalone SRAMs
*/
void dump_verilog_configuration_circuits(t_sram_orgz_info* cur_sram_orgz_info,
FILE* fp) {
FILE* fp,
bool is_explicit_mapping) {
switch(cur_sram_orgz_info->type) {
case SPICE_SRAM_STANDALONE:
dump_verilog_configuration_circuits_standalone_srams(cur_sram_orgz_info, fp);
break;
case SPICE_SRAM_SCAN_CHAIN:
dump_verilog_configuration_circuits_scan_chains(cur_sram_orgz_info, fp);
dump_verilog_configuration_circuits_scan_chains(cur_sram_orgz_info, fp, is_explicit_mapping);
break;
case SPICE_SRAM_MEMORY_BANK:
dump_verilog_configuration_circuits_memory_bank(fp, cur_sram_orgz_info);
/* BC: TODO explicit_mapping*/
dump_verilog_configuration_circuits_memory_bank(fp, cur_sram_orgz_info, is_explicit_mapping);
break;
default:
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid type of SRAM organization in Verilog Generator!\n",

View File

@ -24,7 +24,8 @@ void dump_verilog_clb2clb_directs(FILE* fp,
int num_directs, t_clb_to_clb_directs* direct);
void dump_verilog_configuration_circuits(t_sram_orgz_info* cur_sram_orgz_info,
FILE* fp);
FILE* fp,
bool is_explicit_mapping);
void dump_verilog_top_module_ports(t_sram_orgz_info* cur_sram_orgz_info,
FILE* fp,

View File

@ -903,7 +903,7 @@ int rec_dump_verilog_spice_model_global_ports(FILE* fp,
if (TRUE == require_explicit_port_map ) {
fprintf(fp, ".%s(",
cur_spice_model_port->lib_name);
/*cur_spice_model_port->prefix);*/
//cur_spice_model_port->prefix);
}
fprintf(fp, "%s[0:%d]",
cur_spice_model_port->prefix,
@ -2575,6 +2575,8 @@ void dump_verilog_cmos_mux_config_bus_ports(FILE* fp, t_spice_model* mux_spice_m
int num_mux_reserved_conf_bits,
int num_mux_conf_bits,
bool is_explicit_mapping) {
int num_sram_port;
t_spice_model_port** sram_port = find_spice_model_ports(mux_spice_model, SPICE_MODEL_PORT_SRAM, &num_sram_port, TRUE);
/* Check the file handler*/
if (NULL == fp) {
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
@ -2595,7 +2597,8 @@ void dump_verilog_cmos_mux_config_bus_ports(FILE* fp, t_spice_model* mux_spice_m
* We do not need a prefix implying MUX name, size and index
*/
if (true == is_explicit_mapping) {
fprintf(fp, ".sram(");
fprintf(fp, ".%s (",
sram_port[0]->prefix);
}
dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info,
mux_spice_model, mux_size,
@ -2607,7 +2610,8 @@ void dump_verilog_cmos_mux_config_bus_ports(FILE* fp, t_spice_model* mux_spice_m
}
fprintf(fp, ", ");
if (TRUE == is_explicit_mapping) {
fprintf(fp, ".sram_inv(");
fprintf(fp, ".%s_inv (",
sram_port[0]->prefix);
}
dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info,
mux_spice_model, mux_size,
@ -2624,7 +2628,8 @@ void dump_verilog_cmos_mux_config_bus_ports(FILE* fp, t_spice_model* mux_spice_m
* We need a prefix implying MUX name, size and index
*/
if (TRUE == is_explicit_mapping) {
fprintf(fp, ".sram(");
fprintf(fp, ".%s (",
sram_port[0]->prefix);
}
dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info,
mux_spice_model, mux_size,
@ -2636,7 +2641,8 @@ void dump_verilog_cmos_mux_config_bus_ports(FILE* fp, t_spice_model* mux_spice_m
}
fprintf(fp, ",\n");
if (TRUE == is_explicit_mapping) {
fprintf(fp, ".sram_inv(");
fprintf(fp, ".%s_inv (",
sram_port[0]->prefix);
}
dump_verilog_mux_sram_one_outport(fp, cur_sram_orgz_info,
mux_spice_model, mux_size,
@ -3102,6 +3108,7 @@ void dump_verilog_mem_sram_submodule(FILE* fp,
int num_bl_per_sram = 0;
int num_wl_per_sram = 0;
int iport = 0;
t_llist* spice_model_head = NULL;
/* Check the file handler*/
if (NULL == fp) {
@ -3198,7 +3205,11 @@ void dump_verilog_mem_sram_submodule(FILE* fp,
break;
case SPICE_SRAM_SCAN_CHAIN:
/* Only dump the global ports belonging to a spice_model */
if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE, my_bool_to_boolean(is_explicit_mapping))) {
rec_stats_spice_model_global_ports(cur_sram_verilog_model,
TRUE,
&spice_model_head);
if (0 < dump_verilog_global_ports( fp, spice_model_head, FALSE, is_explicit_mapping)) {
//if (0 < rec_dump_verilog_spice_model_global_ports(fp, cur_sram_verilog_model, FALSE, TRUE, FALSE)) {
fprintf(fp, ",\n");
}
if (SPICE_MODEL_MUX == cur_verilog_model->type) {

View File

@ -25,7 +25,7 @@ arch_ff_keyword="FFPATHKEYWORD"
# Remove previous designs
rm -rf $verilog_output_dirpath/$verilog_output_dirname
mkdir ${OpenFPGA_path}/fpga_flow/arch/generated
mkdir -p ${OpenFPGA_path}/fpga_flow/arch/generated
cd $fpga_flow_scripts
perl rewrite_path_in_file.pl -i $template_arch_xml_file -o $arch_xml_file
@ -33,7 +33,8 @@ perl rewrite_path_in_file.pl -i $arch_xml_file -k $arch_ff_keyword $new_ff_path
cd -
# Run VPR
./vpr $arch_xml_file $blif_file --full_stats --nodisp --activity_file $act_file --fpga_verilog --fpga_verilog_dir $verilog_output_dirpath/$verilog_output_dirname --fpga_x2p_rename_illegal_port --fpga_bitstream_generator --fpga_verilog_print_top_testbench --fpga_verilog_print_input_blif_testbench --fpga_verilog_include_timing --fpga_verilog_include_signal_init --fpga_verilog_print_formal_verification_top_netlist --fpga_verilog_print_autocheck_top_testbench $verilog_reference --fpga_verilog_print_user_defined_template --route_chan_width $vpr_route_chan_width --fpga_verilog_include_icarus_simulator --fpga_verilog_print_report_timing_tcl --power --tech_properties $tech_file --fpga_verilog_print_sdc_pnr --fpga_verilog_print_sdc_analysis --fpga_x2p_compact_routing_hierarchy --fpga_verilog_explicit_mapping
#echo "./vpr $arch_xml_file $blif_file --full_stats --nodisp --activity_file $act_file --fpga_verilog --fpga_verilog_dir $verilog_output_dirpath/$verilog_output_dirname --fpga_x2p_rename_illegal_port --fpga_bitstream_generator --fpga_verilog_print_top_testbench --fpga_verilog_print_input_blif_testbench --fpga_verilog_include_timing --fpga_verilog_include_signal_init --fpga_verilog_print_formal_verification_top_netlist --fpga_verilog_print_autocheck_top_testbench $verilog_reference --fpga_verilog_print_user_defined_template --route_chan_width $vpr_route_chan_width --fpga_verilog_include_icarus_simulator --fpga_verilog_print_report_timing_tcl --power --tech_properties $tech_file --fpga_verilog_print_sdc_pnr --fpga_verilog_print_sdc_analysis --fpga_x2p_compact_routing_hierarchy #--fpga_verilog_explicit_mapping"
./vpr $arch_xml_file $blif_file --full_stats --nodisp --activity_file $act_file --fpga_verilog --fpga_verilog_dir $verilog_output_dirpath/$verilog_output_dirname --fpga_x2p_rename_illegal_port --fpga_bitstream_generator --fpga_verilog_print_top_testbench --fpga_verilog_print_input_blif_testbench --fpga_verilog_include_timing --fpga_verilog_include_signal_init --fpga_verilog_print_formal_verification_top_netlist --fpga_verilog_print_autocheck_top_testbench $verilog_reference --fpga_verilog_print_user_defined_template --route_chan_width $vpr_route_chan_width --fpga_verilog_include_icarus_simulator --fpga_verilog_print_report_timing_tcl --power --tech_properties $tech_file --fpga_verilog_print_sdc_pnr --fpga_verilog_print_sdc_analysis --fpga_x2p_compact_routing_hierarchy #--fpga_verilog_explicit_mapping
cd $fpga_flow_scripts
perl rewrite_path_in_file.pl -i $ff_path -o $new_ff_path -k $ff_keyword $ff_include_path