Skip to content

Commit c8553e5

Browse files
authored
Merge branch 'master' into diagonals
2 parents 64d6389 + 7da51f7 commit c8553e5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1791
-114
lines changed

ODIN_II/SRC/BLIFElaborate.cpp

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#include "hard_blocks.h"
5151
#include "memories.h"
5252
#include "BlockMemories.hpp"
53+
#include "BitwiseOps.hpp"
5354
#include "LogicalOps.hpp"
5455
#include "memories.h"
5556
#include "adders.h"
@@ -72,6 +73,7 @@ void depth_first_traverse_blif_elaborate(nnode_t* node, uintptr_t traverse_mark_
7273

7374
void blif_elaborate_node(nnode_t* node, short traverse_mark_number, netlist_t* netlist);
7475

76+
static void resolve_bitwise_nodes(nnode_t* node, uintptr_t traverse_mark_number, netlist_t* netlist);
7577
static void resolve_logical_nodes(nnode_t* node, uintptr_t traverse_mark_number, netlist_t* netlist);
7678
static void resolve_shift_nodes(nnode_t* node, uintptr_t traverse_mark_number, netlist_t* netlist);
7779
static void resolve_case_equal_nodes(nnode_t* node, uintptr_t traverse_mark_number, netlist_t* netlist);
@@ -200,6 +202,19 @@ void depth_first_traverse_blif_elaborate(nnode_t* node, uintptr_t traverse_mark_
200202
*--------------------------------------------------------------------*/
201203
void blif_elaborate_node(nnode_t* node, short traverse_number, netlist_t* netlist) {
202204
switch (node->type) {
205+
case BITWISE_NOT: //fallthrough
206+
case BITWISE_AND: //fallthrough
207+
case BITWISE_OR: //fallthrough
208+
case BITWISE_NAND: //fallthrough
209+
case BITWISE_NOR: //fallthrough
210+
case BITWISE_XNOR: //fallthrough
211+
case BITWISE_XOR: {
212+
/**
213+
* make sure they have only two inputs and a single output pin for partial mapping phase
214+
*/
215+
resolve_bitwise_nodes(node, traverse_number, netlist);
216+
break;
217+
}
203218
case GTE: //fallthrough
204219
case LTE: //fallthrough
205220
case GT: //fallthrough
@@ -296,20 +311,13 @@ void blif_elaborate_node(nnode_t* node, short traverse_number, netlist_t* netlis
296311
resolve_memory_nodes(node, traverse_number, netlist);
297312
break;
298313
}
299-
case GND_NODE: //fallthrough
300-
case VCC_NODE: //fallthrough
301-
case PAD_NODE: //fallthrough
302-
case INPUT_NODE: //fallthrough
303-
case OUTPUT_NODE: //fallthrough
304-
case HARD_IP: //fallthrough
305-
case BUF_NODE: //fallthrough
306-
case BITWISE_NOT: //fallthrough
307-
case BITWISE_AND: //fallthrough
308-
case BITWISE_OR: //fallthrough
309-
case BITWISE_NAND: //fallthrough
310-
case BITWISE_NOR: //fallthrough
311-
case BITWISE_XNOR: //fallthrough
312-
case BITWISE_XOR: {
314+
case GND_NODE: //fallthrough
315+
case VCC_NODE: //fallthrough
316+
case PAD_NODE: //fallthrough
317+
case INPUT_NODE: //fallthrough
318+
case OUTPUT_NODE: //fallthrough
319+
case HARD_IP: //fallthrough
320+
case BUF_NODE: {
313321
/* some are already resolved for this phase */
314322
break;
315323
}
@@ -323,6 +331,45 @@ void blif_elaborate_node(nnode_t* node, short traverse_number, netlist_t* netlis
323331
}
324332
}
325333

334+
/**
335+
* (function: resolve_bitwise_nodes)
336+
*
337+
* @brief resolving the bitwise nodes by decoding them into 2-1 nodes
338+
*
339+
* @param node pointing to a bitwise node
340+
* @param traverse_mark_number unique traversal mark for blif elaboration pass
341+
* @param netlist pointer to the current netlist file
342+
*/
343+
static void resolve_bitwise_nodes(nnode_t* node, uintptr_t traverse_mark_number, netlist_t* netlist) {
344+
oassert(node->traverse_visited == traverse_mark_number);
345+
346+
switch (node->type) {
347+
case BITWISE_XNOR: //fallthrough
348+
case BITWISE_XOR: {
349+
/**
350+
* decode bitwise nodes into nodes with 2 input and 1 output
351+
* only for reduction operation
352+
*/
353+
if (node->num_output_pins == 1)
354+
decode_bitwise_nodes(node, traverse_mark_number, netlist);
355+
break;
356+
}
357+
case BITWISE_NOT: //fallthrough
358+
case BITWISE_AND: //fallthrough
359+
case BITWISE_OR: //fallthrough
360+
case BITWISE_NAND: //fallthrough
361+
case BITWISE_NOR: {
362+
/* to be handled in partial map */
363+
break;
364+
}
365+
default: {
366+
error_message(BLIF_ELABORATION, node->loc,
367+
"The node(%s) type is not among Odin's bitwise types [BITWISE_NOT, BITWISE_AND, BITWISE_OR, BITWISE_NAND, BITWISE_NOR, BITWISE_XNOR, BITWISE_XOR]\n", node->name);
368+
break;
369+
}
370+
}
371+
}
372+
326373
/**
327374
* (function: resolve_logical_nodes)
328375
*

ODIN_II/SRC/BLIFReader.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,6 +2053,8 @@ hard_block_model* BLIF::Reader::create_hard_block_model(const char* name, operat
20532053
case (BITWISE_OR): //fallthrough
20542054
case (BITWISE_NOT): //fallthrough
20552055
case (BITWISE_AND): //fallthrough
2056+
case (BITWISE_XOR): //fallthrough
2057+
case (BITWISE_XNOR): //fallthrough
20562058
case (LOGICAL_OR): //fallthrough
20572059
case (LOGICAL_XOR): //fallthrough
20582060
case (LOGICAL_AND): //fallthrough

ODIN_II/SRC/BitwiseOps.cpp

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/**
2+
* Copyright (c) 2022 Seyed Alireza Damghani ([email protected])
3+
*
4+
* Permission is hereby granted, free of charge, to any person
5+
* obtaining a copy of this software and associated documentation
6+
* files (the "Software"), to deal in the Software without
7+
* restriction, including without limitation the rights to use,
8+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the
10+
* Software is furnished to do so, subject to the following
11+
* conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be
14+
* included in all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23+
* OTHER DEALINGS IN THE SOFTWARE.
24+
*
25+
* @file: This file provides utilities to modify the bitwise nodes
26+
* to make them compatible with the Odin-II partial mapper.
27+
*/
28+
29+
#include <cmath> // log2
30+
#include "BitwiseOps.hpp"
31+
#include "node_creation_library.h"
32+
#include "odin_util.h"
33+
#include "netlist_utils.h"
34+
#include "vtr_memory.h"
35+
36+
/**
37+
* (function: decode_bitwise_nodes)
38+
*
39+
* @brief decoding bitwise nodes into 2 inputs - 1 output nodes
40+
*
41+
* @param node pointing to a bitwise node
42+
* @param traverse_mark_number unique traversal mark for blif elaboration pass
43+
* @param netlist pointer to the current netlist file
44+
*/
45+
void decode_bitwise_nodes(nnode_t* node, uintptr_t traverse_mark_number, netlist_t* /* netlist */) {
46+
oassert(node->traverse_visited == traverse_mark_number);
47+
oassert(node->num_input_port_sizes < 3);
48+
oassert(node->num_output_port_sizes == 1);
49+
oassert(node->num_output_pins == 1);
50+
51+
// already satisfied the partial mapper requirement
52+
if (node->num_input_pins < 3 || node->num_input_port_sizes == 2)
53+
return;
54+
55+
int i, j;
56+
/* keep the record of primary node info */
57+
int width = node->input_port_sizes[0];
58+
int levels = std::ceil(std::log2(width));
59+
60+
/**
61+
*************************************************************************************************
62+
* *
63+
* |\ *
64+
* N bit | \ 1 bit *
65+
* in --'--> | | ----'----> *
66+
* | / *
67+
* |/ *
68+
* *
69+
***************************************** <decoded nodes> ***************************************
70+
* *
71+
* *
72+
* |\ *
73+
* 2 bits | \ *
74+
* in --'-- | | -- *
75+
* | / |\ *
76+
* |/ 2 bits | \ *
77+
* --'-- | | -- *
78+
* |\ | / *
79+
* 2 bits | \ |/ *
80+
* in --'-- | | -- *
81+
* | / |\ *
82+
* |/ 2 bits | \ *
83+
* --'-- | | -- *
84+
* |\ | / *
85+
* 2 bits | \ |/ *
86+
* in --'-- | | -- *
87+
* | / |\ *
88+
* |/ 2 bits | \ *
89+
* --'-- | | -- *
90+
* |\ | / *
91+
* 2 bits | \ |/ *
92+
* in --'-- | | -- *
93+
* | / *
94+
* |/ *
95+
* *
96+
* ... ... ... *
97+
* *
98+
* ... ... ... *
99+
* *
100+
* ... ... ... *
101+
*************************************************************************************************/
102+
103+
nnode_t*** decoded_nodes = (nnode_t***)vtr::calloc(levels, sizeof(nnode_t**));
104+
/* to keep the internal input signals for future usage */
105+
signal_list_t** input_signals = (signal_list_t**)vtr::calloc(levels + 1, sizeof(signal_list_t*));
106+
107+
/* init the first input signals with the primary node input signals */
108+
input_signals[0] = init_signal_list();
109+
for (i = 0; i < width; ++i)
110+
add_pin_to_signal_list(input_signals[0], node->input_pins[i]);
111+
112+
/* creating multiple stages to decode bitwise nodes into 2-1 nodes */
113+
for (i = 0; i < levels; ++i) {
114+
/* num of nodes in each stage */
115+
int num_of_nodes = width / 2;
116+
decoded_nodes[i] = (nnode_t**)vtr::calloc(num_of_nodes, sizeof(nnode_t*));
117+
input_signals[i + 1] = init_signal_list();
118+
119+
/* iterating over each decoded node to connect inputs */
120+
for (j = 0; j < num_of_nodes; ++j) {
121+
/*****************************************************************************************
122+
* <Bitwise Node> *
123+
* *
124+
* Port 1 *
125+
* 0: in1 |\ *
126+
* 1: in2 1 bit | \ *
127+
* in1 --'--> | | 1 bit *
128+
* | |---'---> *
129+
* in2 --'--> | | *
130+
* | / *
131+
* |/ *
132+
****************************************************************************************/
133+
decoded_nodes[i][j] = make_1port_gate(node->type, 2, 1, node, traverse_mark_number);
134+
135+
if (input_signals[i]->pins[2 * j]->node)
136+
remap_pin_to_new_node(input_signals[i]->pins[2 * j], decoded_nodes[i][j], 0);
137+
else
138+
add_input_pin_to_node(decoded_nodes[i][j], input_signals[i]->pins[2 * j], 0);
139+
140+
if (input_signals[i]->pins[2 * j + 1]->node)
141+
remap_pin_to_new_node(input_signals[i]->pins[2 * j + 1], decoded_nodes[i][j], 1);
142+
else
143+
add_input_pin_to_node(decoded_nodes[i][j], input_signals[i]->pins[2 * j + 1], 1);
144+
145+
// Connect output pin to related input pin
146+
if (i != levels - 1) {
147+
npin_t* new_pin1 = allocate_npin();
148+
npin_t* new_pin2 = allocate_npin();
149+
nnet_t* new_net = allocate_nnet();
150+
new_net->name = make_full_ref_name(NULL, NULL, NULL, decoded_nodes[i][j]->name, -1);
151+
/* hook the output pin into the node */
152+
add_output_pin_to_node(decoded_nodes[i][j], new_pin1, 0);
153+
/* hook up new pin 1 into the new net */
154+
add_driver_pin_to_net(new_net, new_pin1);
155+
/* hook up the new pin 2 to this new net */
156+
add_fanout_pin_to_net(new_net, new_pin2);
157+
158+
// Storing the output pins of the current node as the input of the next one
159+
add_pin_to_signal_list(input_signals[i + 1], new_pin2);
160+
161+
} else {
162+
remap_pin_to_new_node(node->output_pins[0], decoded_nodes[i][j], 0);
163+
}
164+
}
165+
/* in case we have odd width, move the last pin to next level */
166+
if (width - 2 * j > 0) {
167+
oassert(width - 2 * j < 2);
168+
add_pin_to_signal_list(input_signals[i + 1], input_signals[i]->pins[width - 1]);
169+
}
170+
width = input_signals[i + 1]->count;
171+
}
172+
173+
// CLEAN UP
174+
for (i = 0; i < levels; i++) {
175+
vtr::free(decoded_nodes[i]);
176+
}
177+
vtr::free(decoded_nodes);
178+
179+
for (i = 0; i < levels + 1; i++) {
180+
free_signal_list(input_signals[i]);
181+
}
182+
vtr::free(input_signals);
183+
184+
// to free primary node
185+
free_nnode(node);
186+
}

ODIN_II/SRC/enum_str.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,6 @@ extern const strbimap<file_type_e> file_extension_strmap({{".ilang", file_type_e
213213
{".vh", file_type_e::_VERILOG_HEADER},
214214
{".sv", file_type_e::_SYSTEM_VERILOG},
215215
{".svh", file_type_e::_SYSTEM_VERILOG_HEADER},
216-
{".uhdm", file_type_e::_UHDM},
217216
{".blif", file_type_e::_BLIF},
218217
{".eblif", file_type_e::_EBLIF}});
219218

ODIN_II/SRC/include/BitwiseOps.hpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* Copyright (c) 2022 Seyed Alireza Damghani ([email protected])
3+
*
4+
* Permission is hereby granted, free of charge, to any person
5+
* obtaining a copy of this software and associated documentation
6+
* files (the "Software"), to deal in the Software without
7+
* restriction, including without limitation the rights to use,
8+
* copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the
10+
* Software is furnished to do so, subject to the following
11+
* conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be
14+
* included in all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18+
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20+
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21+
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22+
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23+
* OTHER DEALINGS IN THE SOFTWARE.
24+
*/
25+
#ifndef __BITWISE_OPS_H__
26+
#define __BITWISE_OPS_H__
27+
28+
#include "odin_types.h"
29+
30+
extern void decode_bitwise_nodes(nnode_t* node, uintptr_t traverse_mark_number, netlist_t* netlist);
31+
#endif //__BITWISE_OPS_H__

ODIN_II/SRC/odin_util.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,15 @@ void assert_valid_file_extenstion(std::vector<std::string> name_list, file_type_
138138
error_message(UTIL, unknown_location, "%s", YOSYS_PLUGINS_NOT_COMPILED);
139139
#endif
140140
}
141-
[[fallthrough]];
141+
if (file_type != type && type != file_type_e::_UHDM)
142+
error_message(UTIL, unknown_location,
143+
"File (%s) has an invalid extension (%s), supposed to be a %s file { %s },\
144+
please see ./odin --help",
145+
file_name.c_str(),
146+
file_ext_str.c_str(),
147+
file_type_strmap.find(type)->second.c_str(),
148+
file_extension_strmap.find(type)->second.c_str());
149+
break;
142150
}
143151
case (file_type_e::_BLIF): {
144152
if (file_type != type)

0 commit comments

Comments
 (0)