完成了读入部分和电路数据结构的设计和实现
This commit is contained in:
parent
cb09360593
commit
6974117c68
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
*.o
|
||||
*.d
|
79
.vscode/settings.json
vendored
Normal file
79
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"*.ejs": "html",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"csetjmp": "cpp",
|
||||
"csignal": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"bitset": "cpp",
|
||||
"cfenv": "cpp",
|
||||
"charconv": "cpp",
|
||||
"chrono": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"complex": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cuchar": "cpp",
|
||||
"deque": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"regex": "cpp",
|
||||
"string": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"fstream": "cpp",
|
||||
"future": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"ostream": "cpp",
|
||||
"scoped_allocator": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"thread": "cpp",
|
||||
"typeindex": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"valarray": "cpp",
|
||||
"variant": "cpp"
|
||||
}
|
||||
}
|
207
c432.bench
Normal file
207
c432.bench
Normal file
@ -0,0 +1,207 @@
|
||||
# c432
|
||||
|
||||
INPUT(1)
|
||||
INPUT(4)
|
||||
INPUT(8)
|
||||
INPUT(11)
|
||||
INPUT(14)
|
||||
INPUT(17)
|
||||
INPUT(21)
|
||||
INPUT(24)
|
||||
INPUT(27)
|
||||
INPUT(30)
|
||||
INPUT(34)
|
||||
INPUT(37)
|
||||
INPUT(40)
|
||||
INPUT(43)
|
||||
INPUT(47)
|
||||
INPUT(50)
|
||||
INPUT(53)
|
||||
INPUT(56)
|
||||
INPUT(60)
|
||||
INPUT(63)
|
||||
INPUT(66)
|
||||
INPUT(69)
|
||||
INPUT(73)
|
||||
INPUT(76)
|
||||
INPUT(79)
|
||||
INPUT(82)
|
||||
INPUT(86)
|
||||
INPUT(89)
|
||||
INPUT(92)
|
||||
INPUT(95)
|
||||
INPUT(99)
|
||||
INPUT(102)
|
||||
INPUT(105)
|
||||
INPUT(108)
|
||||
INPUT(112)
|
||||
INPUT(115)
|
||||
|
||||
OUTPUT(223)
|
||||
OUTPUT(329)
|
||||
OUTPUT(370)
|
||||
OUTPUT(421)
|
||||
OUTPUT(430)
|
||||
OUTPUT(431)
|
||||
OUTPUT(432)
|
||||
|
||||
118 = NOT(1)
|
||||
119 = NOT(4)
|
||||
122 = NOT(11)
|
||||
123 = NOT(17)
|
||||
126 = NOT(24)
|
||||
127 = NOT(30)
|
||||
130 = NOT(37)
|
||||
131 = NOT(43)
|
||||
134 = NOT(50)
|
||||
135 = NOT(56)
|
||||
138 = NOT(63)
|
||||
139 = NOT(69)
|
||||
142 = NOT(76)
|
||||
143 = NOT(82)
|
||||
146 = NOT(89)
|
||||
147 = NOT(95)
|
||||
150 = NOT(102)
|
||||
151 = NOT(108)
|
||||
154 = NAND(118, 4)
|
||||
157 = NOR(8, 119)
|
||||
158 = NOR(14, 119)
|
||||
159 = NAND(122, 17)
|
||||
162 = NAND(126, 30)
|
||||
165 = NAND(130, 43)
|
||||
168 = NAND(134, 56)
|
||||
171 = NAND(138, 69)
|
||||
174 = NAND(142, 82)
|
||||
177 = NAND(146, 95)
|
||||
180 = NAND(150, 108)
|
||||
183 = NOR(21, 123)
|
||||
184 = NOR(27, 123)
|
||||
185 = NOR(34, 127)
|
||||
186 = NOR(40, 127)
|
||||
187 = NOR(47, 131)
|
||||
188 = NOR(53, 131)
|
||||
189 = NOR(60, 135)
|
||||
190 = NOR(66, 135)
|
||||
191 = NOR(73, 139)
|
||||
192 = NOR(79, 139)
|
||||
193 = NOR(86, 143)
|
||||
194 = NOR(92, 143)
|
||||
195 = NOR(99, 147)
|
||||
196 = NOR(105, 147)
|
||||
197 = NOR(112, 151)
|
||||
198 = NOR(115, 151)
|
||||
199 = AND(154, 159, 162, 165, 168, 171, 174, 177, 180)
|
||||
203 = NOT(199)
|
||||
213 = NOT(199)
|
||||
223 = NOT(199)
|
||||
224 = XOR(203, 154)
|
||||
227 = XOR(203, 159)
|
||||
230 = XOR(203, 162)
|
||||
233 = XOR(203, 165)
|
||||
236 = XOR(203, 168)
|
||||
239 = XOR(203, 171)
|
||||
242 = NAND(1, 213)
|
||||
243 = XOR(203, 174)
|
||||
246 = NAND(213, 11)
|
||||
247 = XOR(203, 177)
|
||||
250 = NAND(213, 24)
|
||||
251 = XOR(203, 180)
|
||||
254 = NAND(213, 37)
|
||||
255 = NAND(213, 50)
|
||||
256 = NAND(213, 63)
|
||||
257 = NAND(213, 76)
|
||||
258 = NAND(213, 89)
|
||||
259 = NAND(213, 102)
|
||||
260 = NAND(224, 157)
|
||||
263 = NAND(224, 158)
|
||||
264 = NAND(227, 183)
|
||||
267 = NAND(230, 185)
|
||||
270 = NAND(233, 187)
|
||||
273 = NAND(236, 189)
|
||||
276 = NAND(239, 191)
|
||||
279 = NAND(243, 193)
|
||||
282 = NAND(247, 195)
|
||||
285 = NAND(251, 197)
|
||||
288 = NAND(227, 184)
|
||||
289 = NAND(230, 186)
|
||||
290 = NAND(233, 188)
|
||||
291 = NAND(236, 190)
|
||||
292 = NAND(239, 192)
|
||||
293 = NAND(243, 194)
|
||||
294 = NAND(247, 196)
|
||||
295 = NAND(251, 198)
|
||||
296 = AND(260, 264, 267, 270, 273, 276, 279, 282, 285)
|
||||
300 = NOT(263)
|
||||
301 = NOT(288)
|
||||
302 = NOT(289)
|
||||
303 = NOT(290)
|
||||
304 = NOT(291)
|
||||
305 = NOT(292)
|
||||
306 = NOT(293)
|
||||
307 = NOT(294)
|
||||
308 = NOT(295)
|
||||
309 = NOT(296)
|
||||
319 = NOT(296)
|
||||
329 = NOT(296)
|
||||
330 = XOR(309, 260)
|
||||
331 = XOR(309, 264)
|
||||
332 = XOR(309, 267)
|
||||
333 = XOR(309, 270)
|
||||
334 = NAND(8, 319)
|
||||
335 = XOR(309, 273)
|
||||
336 = NAND(319, 21)
|
||||
337 = XOR(309, 276)
|
||||
338 = NAND(319, 34)
|
||||
339 = XOR(309, 279)
|
||||
340 = NAND(319, 47)
|
||||
341 = XOR(309, 282)
|
||||
342 = NAND(319, 60)
|
||||
343 = XOR(309, 285)
|
||||
344 = NAND(319, 73)
|
||||
345 = NAND(319, 86)
|
||||
346 = NAND(319, 99)
|
||||
347 = NAND(319, 112)
|
||||
348 = NAND(330, 300)
|
||||
349 = NAND(331, 301)
|
||||
350 = NAND(332, 302)
|
||||
351 = NAND(333, 303)
|
||||
352 = NAND(335, 304)
|
||||
353 = NAND(337, 305)
|
||||
354 = NAND(339, 306)
|
||||
355 = NAND(341, 307)
|
||||
356 = NAND(343, 308)
|
||||
357 = AND(348, 349, 350, 351, 352, 353, 354, 355, 356)
|
||||
360 = NOT(357)
|
||||
370 = NOT(357)
|
||||
371 = NAND(14, 360)
|
||||
372 = NAND(360, 27)
|
||||
373 = NAND(360, 40)
|
||||
374 = NAND(360, 53)
|
||||
375 = NAND(360, 66)
|
||||
376 = NAND(360, 79)
|
||||
377 = NAND(360, 92)
|
||||
378 = NAND(360, 105)
|
||||
379 = NAND(360, 115)
|
||||
380 = NAND(4, 242, 334, 371)
|
||||
381 = NAND(246, 336, 372, 17)
|
||||
386 = NAND(250, 338, 373, 30)
|
||||
393 = NAND(254, 340, 374, 43)
|
||||
399 = NAND(255, 342, 375, 56)
|
||||
404 = NAND(256, 344, 376, 69)
|
||||
407 = NAND(257, 345, 377, 82)
|
||||
411 = NAND(258, 346, 378, 95)
|
||||
414 = NAND(259, 347, 379, 108)
|
||||
415 = NOT(380)
|
||||
416 = AND(381, 386, 393, 399, 404, 407, 411, 414)
|
||||
417 = NOT(393)
|
||||
418 = NOT(404)
|
||||
419 = NOT(407)
|
||||
420 = NOT(411)
|
||||
421 = NOR(415, 416)
|
||||
422 = NAND(386, 417)
|
||||
425 = NAND(386, 393, 418, 399)
|
||||
428 = NAND(399, 393, 419)
|
||||
429 = NAND(386, 393, 407, 420)
|
||||
430 = NAND(381, 386, 422, 399)
|
||||
431 = NAND(381, 386, 425, 428)
|
||||
432 = NAND(381, 422, 425, 429)
|
0
circuit.cpp
Normal file
0
circuit.cpp
Normal file
20
circuit.h
Normal file
20
circuit.h
Normal file
@ -0,0 +1,20 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
class Gate {
|
||||
public:
|
||||
std::string name;
|
||||
enum { AND, NAND, OR, NOR, XOR, XNOR, NOT, BUF, INPUT, OUTPUT } type;
|
||||
enum { VAL_ZERO, VAL_ONE, VAL_X } value;
|
||||
std::vector<Gate*> outputs;
|
||||
std::vector<Gate*> inputs;
|
||||
};
|
||||
|
||||
class Circuit {
|
||||
public:
|
||||
std::vector<Gate*> PIs;
|
||||
std::vector<Gate*> POs;
|
||||
std::unordered_map<std::string, Gate*> name2gate;
|
||||
void parse_from_file(const char *filename);
|
||||
};
|
26
main.cpp
Normal file
26
main.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
|
||||
#include "circuit.h"
|
||||
|
||||
int main(int args, char* argv[]) {
|
||||
|
||||
if(args != 2) {
|
||||
printf("usage: ./atpg <XXX.bench>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Circuit circuit;
|
||||
|
||||
printf("parsing file %s...\n", argv[1]);
|
||||
circuit.parse_from_file(argv[1]);
|
||||
printf("====== Circuit Statistics ====== \n");
|
||||
printf("PI:\t%d\n", circuit.PIs.size());
|
||||
printf("PO:\t%d\n", circuit.POs.size());
|
||||
printf("Gates:\t%d\n", circuit.name2gate.size());
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
72
makefile
Normal file
72
makefile
Normal file
@ -0,0 +1,72 @@
|
||||
#一个实用的makefile,能自动编译当前目录下所有.c/.cpp源文件,支持二者混合编译
|
||||
#并且当某个.c/.cpp、.h或依赖的源文件被修改后,仅重编涉及到的源文件,未涉及的不编译
|
||||
#详解文档:http://blog.csdn.net/huyansoft/article/details/8924624
|
||||
#author:胡彦 2013-5-21
|
||||
|
||||
#----------------------------------------------------------
|
||||
#编译工具用g++,以同时支持C和C++程序,以及二者的混合编译
|
||||
CC=g++
|
||||
|
||||
CPPFLAGS=-O3
|
||||
|
||||
#使用$(winldcard *.c)来获取工作目录下的所有.c文件的列表
|
||||
#sources:=main.cpp command.c
|
||||
|
||||
#变量sources得到当前目录下待编译的.c/.cpp文件的列表,两次调用winldcard、结果连在一起即可
|
||||
sources:=$(wildcard *.c) $(wildcard *.cpp)
|
||||
|
||||
#变量objects得到待生成的.o文件的列表,把sources中每个文件的扩展名换成.o即可。这里两次调用patsubst函数,第1次把sources中所有.cpp换成.o,第2次把第1次结果里所有.c换成.o
|
||||
objects:=$(patsubst %.c,%.o,$(patsubst %.cpp,%.o,$(sources)))
|
||||
|
||||
#变量dependence得到待生成的.d文件的列表,把objects中每个扩展名.o换成.d即可。也可写成$(patsubst %.o,%.d,$(objects))
|
||||
dependence:=$(objects:.o=.d)
|
||||
|
||||
#----------------------------------------------------------
|
||||
#当$(objects)列表里所有文件都生成后,便可调用这里的 $(CC) $^ -o $@ 命令生成最终目标all了
|
||||
#把all定义成第1个规则,使得可以把make all命令简写成make
|
||||
atpg: $(objects)
|
||||
$(CC) $(CPPFLAGS) $^ -o $@
|
||||
# @./$@ #编译后立即执行
|
||||
|
||||
#这段使用make的模式规则,指示如何由.c文件生成.o,即对每个.c文件,调用gcc -c XX.c -o XX.o命令生成对应的.o文件
|
||||
#如果不写这段也可以,因为make的隐含规则可以起到同样的效果
|
||||
%.o: %.c
|
||||
$(CC) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
#同上,指示如何由.cpp生成.o,可省略
|
||||
%.o: %.cpp
|
||||
$(CC) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
#----------------------------------------------------------
|
||||
include $(dependence) #注意该句要放在终极目标all的规则之后,否则.d文件里的规则会被误当作终极规则了
|
||||
|
||||
#因为这4行命令要多次凋用,定义成命令包以简化书写
|
||||
define gen_dep
|
||||
set -e; rm -f $@; \
|
||||
$(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \
|
||||
sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
|
||||
rm -f $@.$$$$
|
||||
endef
|
||||
|
||||
#指示如何由.c生成其依赖规则文件.d
|
||||
#这段使用make的模式规则,指示对每个.c文件,如何生成其依赖规则文件.d,调用上面的命令包即可
|
||||
%.d: %.c
|
||||
$(gen_dep)
|
||||
|
||||
#同上,指示对每个.cpp,如何生成其依赖规则文件.d
|
||||
%.d: %.cpp
|
||||
$(gen_dep)
|
||||
|
||||
#----------------------------------------------------------
|
||||
#清除所有临时文件(所有.o和.d)。之所以把clean定义成伪目标,是因为这个目标并不对应实际的文件
|
||||
.PHONY: clean
|
||||
clean: #.$$已在每次使用后立即删除。-f参数表示被删文件不存在时不报错
|
||||
rm -f all $(objects) $(dependence)
|
||||
|
||||
echo: #调试时显示一些变量的值
|
||||
@echo sources=$(sources)
|
||||
@echo objects=$(objects)
|
||||
@echo dependence=$(dependence)
|
||||
@echo CPPFLAGS=$(CPPFLAGS)
|
||||
|
||||
#提醒:当混合编译.c/.cpp时,为了能够在C++程序里调用C函数,必须把每一个要调用的C函数,其声明都包括在extern "C"{}块里面,这样C++链接时才能成功链接它们。
|
101
parser.cpp
Normal file
101
parser.cpp
Normal file
@ -0,0 +1,101 @@
|
||||
#include "circuit.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <regex>
|
||||
#include <set>
|
||||
|
||||
std::string trim(const std::string& s) {
|
||||
auto wsfront = std::find_if_not(s.begin(), s.end(), [](int c){ return std::isspace(c); });
|
||||
auto wsback = std::find_if_not(s.rbegin(), s.rend(), [](int c){ return std::isspace(c); }).base();
|
||||
return (wsback <= wsfront ? std::string() : std::string(wsfront, wsback));
|
||||
}
|
||||
|
||||
void Circuit::parse_from_file(const char *filename) {
|
||||
|
||||
std::ifstream file(filename);
|
||||
if(!file.is_open()) {
|
||||
printf("Error while reading %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// buf 10MB
|
||||
file.rdbuf()->pubsetbuf(0, 10 *1024 * 1024);
|
||||
|
||||
std::string line;
|
||||
while(std::getline(file, line)) {
|
||||
if(line[0] == '#') continue;
|
||||
if(line == "\r" || line == "") continue;
|
||||
|
||||
std::cmatch m;
|
||||
if(std::regex_match(line.c_str(), m, std::regex("INPUT\\s*\\(\\s*(.*)\\s*\\)\\s*"))) {
|
||||
|
||||
Gate *input = new Gate();
|
||||
input->name = m.str(1);
|
||||
input->type = Gate::INPUT;
|
||||
input->value = Gate::VAL_X;
|
||||
name2gate.insert(std::make_pair(input->name, input));
|
||||
|
||||
|
||||
std::cout << "input -> $" << input->name << "$" << std::endl;
|
||||
|
||||
PIs.push_back(input);
|
||||
} else if(std::regex_match(line.c_str(), m, std::regex("OUTPUT\\s*\\(\\s*(.*)\\s*\\)\\s*"))) {
|
||||
|
||||
Gate *output = new Gate();
|
||||
output->name = m.str(1);
|
||||
output->type = Gate::OUTPUT;
|
||||
output->value = Gate::VAL_X;
|
||||
name2gate.insert(std::make_pair(output->name, output));
|
||||
|
||||
POs.push_back(output);
|
||||
} else if(std::regex_match(line.c_str(), m, std::regex("\\s*(\\S+)\\s*=\\s*(\\w+)\\s*\\(\\s*(.*)\\s*\\)\\s*"))) {
|
||||
|
||||
std::string output_name = m.str(1);
|
||||
std::string gate_name = m.str(2);
|
||||
std::string list = m.str(3);
|
||||
|
||||
Gate *gate = new Gate();
|
||||
|
||||
gate->name = output_name;
|
||||
gate->value = Gate::VAL_X;
|
||||
|
||||
name2gate.insert(std::make_pair(gate->name, gate));
|
||||
|
||||
// split by ","
|
||||
std::regex pattern(R"(\s*,\s*)");
|
||||
std::sregex_token_iterator it(list.begin(), list.end(), pattern, -1);
|
||||
std::sregex_token_iterator end;
|
||||
|
||||
while (it != end) {
|
||||
std::string in = trim(*it++);
|
||||
if(!name2gate.count(in)) {
|
||||
printf("Error while reading file: $%s$ is not defined before used.\n", in.c_str());
|
||||
exit(1);
|
||||
}
|
||||
Gate* in_gate = name2gate[in];
|
||||
|
||||
gate->inputs.push_back(in_gate);
|
||||
in_gate->outputs.push_back(gate);
|
||||
}
|
||||
|
||||
if(gate_name == "AND") { gate->type = Gate::AND; }
|
||||
else if(gate_name == "NAND") { gate->type = Gate::NAND; }
|
||||
else if(gate_name == "OR") { gate->type = Gate::OR; }
|
||||
else if(gate_name == "NOR") { gate->type = Gate::NOR; }
|
||||
else if(gate_name == "XOR") { gate->type = Gate::XOR; }
|
||||
else if(gate_name == "XNOR") { gate->type = Gate::XNOR; }
|
||||
else if(gate_name == "NOT") { gate->type = Gate::NOT; }
|
||||
else if(gate_name == "BUF") { gate->type = Gate::BUF; }
|
||||
else {
|
||||
printf("Error while reading file: %s is not a valid gate.\n", gate_name.c_str());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
} else {
|
||||
printf("Error while reading file: \"%s\" is a wrong line.\n", line.c_str());
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user