yosys2digitaljs 0.6.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/nodejs.yml +2 -2
- package/ChangeLog.md +7 -0
- package/README.md +3 -3
- package/dist/index.d.ts +3 -2
- package/dist/index.js +62 -10
- package/package.json +2 -2
- package/src/index.ts +64 -13
- package/test.sv +31 -0
- package/test1.sv +19 -0
- package/test1.v +19 -0
- package/test2.v +19 -0
- package/test3.sv +63 -0
- package/test3.v +19 -0
- package/test4.sv +62 -0
- package/tests/ram.sv +1 -1
- package/tests/z.sv +7 -0
- package/yosyss +4 -0
package/ChangeLog.md
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
|
3
3
|
|
|
4
|
+
## [0.7.0] -- 2023-03-2023
|
|
5
|
+
|
|
6
|
+
### Added
|
|
7
|
+
|
|
8
|
+
- Support for `$lut` cells
|
|
9
|
+
- Support for generating 7-segment display outputs
|
|
10
|
+
|
|
4
11
|
## [0.6.0] -- 2022-02-02
|
|
5
12
|
|
|
6
13
|
### Added
|
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# yosys2digitaljs
|
|
2
|
-
This program converts JSON netlist output generated by [Yosys](
|
|
3
|
-
circuit synthesis software for use with the
|
|
2
|
+
This program converts JSON netlist output generated by [Yosys](https://yosyshq.net/yosys/)
|
|
3
|
+
circuit synthesis software (Github repo [here](https://github.com/YosysHQ/yosys/)) for use with the
|
|
4
4
|
[DigitalJS](http://github.com/tilk/digitaljs) graphical circuit simulator.
|
|
5
5
|
|
|
6
6
|
# Usage
|
|
7
|
-
You need to have [Yosys](
|
|
7
|
+
You need to have [Yosys](https://yosyshq.net/yosys/) installed to run
|
|
8
8
|
yosys2digitaljs. For example, in Debian/Ubuntu, run:
|
|
9
9
|
```bash
|
|
10
10
|
apt install yosys
|
package/dist/index.d.ts
CHANGED
|
@@ -54,8 +54,9 @@ declare namespace Digitaljs {
|
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
56
|
declare namespace Yosys {
|
|
57
|
-
|
|
58
|
-
type
|
|
57
|
+
const ConstChars: readonly ["0", "1", "x", "z"];
|
|
58
|
+
type BitChar = (typeof ConstChars)[number];
|
|
59
|
+
type Bit = number | BitChar;
|
|
59
60
|
type BitVector = Bit[];
|
|
60
61
|
type Port = {
|
|
61
62
|
direction: 'input' | 'output' | 'inout';
|
package/dist/index.js
CHANGED
|
@@ -62,6 +62,7 @@ const gate_subst = new Map([
|
|
|
62
62
|
['$pmux', 'Mux1Hot'],
|
|
63
63
|
['$mem', 'Memory'],
|
|
64
64
|
['$mem_v2', 'Memory'],
|
|
65
|
+
['$lut', 'Memory'],
|
|
65
66
|
['$fsm', 'FSM'],
|
|
66
67
|
['$clock', 'Clock'],
|
|
67
68
|
['$button', 'Button'],
|
|
@@ -114,6 +115,10 @@ const gate_negations = new Map([
|
|
|
114
115
|
['XnorReduce', 'XorReduce']
|
|
115
116
|
]);
|
|
116
117
|
;
|
|
118
|
+
var Yosys;
|
|
119
|
+
(function (Yosys) {
|
|
120
|
+
Yosys.ConstChars = ["0", "1", "x", "z"];
|
|
121
|
+
})(Yosys || (Yosys = {}));
|
|
117
122
|
;
|
|
118
123
|
function chunkArray(a, chunk_size) {
|
|
119
124
|
let results = [];
|
|
@@ -214,7 +219,7 @@ function yosys_to_digitaljs(data, portmaps, options = {}) {
|
|
|
214
219
|
}
|
|
215
220
|
function yosys_to_digitaljs_mod(name, mod, portmaps, options = {}) {
|
|
216
221
|
function constbit(bit) {
|
|
217
|
-
return bit
|
|
222
|
+
return Yosys.ConstChars.includes(bit.toString());
|
|
218
223
|
}
|
|
219
224
|
const nets = new HashMap();
|
|
220
225
|
const netnames = new HashMap();
|
|
@@ -245,8 +250,6 @@ function yosys_to_digitaljs_mod(name, mod, portmaps, options = {}) {
|
|
|
245
250
|
const net = get_net(k);
|
|
246
251
|
if (net.source !== undefined) {
|
|
247
252
|
// multiple sources driving one net, disallowed in digitaljs
|
|
248
|
-
console.log(k);
|
|
249
|
-
console.log(net);
|
|
250
253
|
throw Error('Multiple sources driving net: ' + net.name);
|
|
251
254
|
}
|
|
252
255
|
net.source = { id: d, port: p };
|
|
@@ -865,6 +868,23 @@ function yosys_to_digitaljs_mod(name, mod, portmaps, options = {}) {
|
|
|
865
868
|
}
|
|
866
869
|
break;
|
|
867
870
|
}
|
|
871
|
+
case '$lut':
|
|
872
|
+
assert(cell.connections.A.length == decode_json_number(cell.parameters.WIDTH));
|
|
873
|
+
assert(cell.connections.Y.length == 1);
|
|
874
|
+
assert(cell.port_directions.A == 'input');
|
|
875
|
+
assert(cell.port_directions.Y == 'output');
|
|
876
|
+
dev.abits = cell.connections.A.length;
|
|
877
|
+
dev.bits = cell.connections.Y.length;
|
|
878
|
+
dev.rdports = [{}];
|
|
879
|
+
dev.wrports = [];
|
|
880
|
+
dev.memdata = cell.parameters.LUT.split('').reverse();
|
|
881
|
+
assert(dev.memdata.length == Math.pow(2, dev.abits));
|
|
882
|
+
// Rewrite cell connections to be $mem compatible for port mapping
|
|
883
|
+
cell.connections.RD_ADDR = cell.connections.A;
|
|
884
|
+
cell.connections.RD_DATA = cell.connections.Y;
|
|
885
|
+
delete cell.connections.A;
|
|
886
|
+
delete cell.connections.Y;
|
|
887
|
+
break;
|
|
868
888
|
default:
|
|
869
889
|
}
|
|
870
890
|
if (dev.type == 'Dff') {
|
|
@@ -887,6 +907,8 @@ function yosys_to_digitaljs_mod(name, mod, portmaps, options = {}) {
|
|
|
887
907
|
connect_mem(dname, cell, dev);
|
|
888
908
|
else if (cell.type == '$mem_v2')
|
|
889
909
|
connect_mem(dname, cell, dev);
|
|
910
|
+
else if (cell.type == '$lut')
|
|
911
|
+
connect_mem(dname, cell, dev);
|
|
890
912
|
else
|
|
891
913
|
throw Error('Invalid cell type: ' + cell.type);
|
|
892
914
|
}
|
|
@@ -997,14 +1019,37 @@ function yosys_to_digitaljs_mod(name, mod, portmaps, options = {}) {
|
|
|
997
1019
|
}
|
|
998
1020
|
return mout;
|
|
999
1021
|
}
|
|
1000
|
-
function
|
|
1001
|
-
|
|
1022
|
+
function ansi_c_escape_contents(cmd) {
|
|
1023
|
+
function func(ch) {
|
|
1024
|
+
if (ch == '\t')
|
|
1025
|
+
return '\\t';
|
|
1026
|
+
if (ch == '\r')
|
|
1027
|
+
return '\\r';
|
|
1028
|
+
if (ch == '\n')
|
|
1029
|
+
return '\\n';
|
|
1030
|
+
return '\\x' + ch.charCodeAt(0).toString(16).padStart(2, '0');
|
|
1031
|
+
}
|
|
1032
|
+
return cmd.replace(/(["'\\])/g, '\\$1')
|
|
1033
|
+
.replace(/[\x00-\x1F\x7F-\x9F]/g, func);
|
|
1034
|
+
}
|
|
1035
|
+
function ansi_c_escape(cmd) {
|
|
1036
|
+
return '"' + ansi_c_escape_contents(cmd) + '"';
|
|
1037
|
+
}
|
|
1038
|
+
function shell_escape_contents(cmd) {
|
|
1039
|
+
return cmd.replace(/(["\r\n$`\\])/g, '\\$1');
|
|
1040
|
+
}
|
|
1041
|
+
function shell_escape(cmd) {
|
|
1042
|
+
return '"' + shell_escape_contents(cmd) + '"';
|
|
1043
|
+
}
|
|
1044
|
+
function process_filename(filename) {
|
|
1045
|
+
const flags = /\.sv$/.test(filename) ? " -sv" : "";
|
|
1046
|
+
return "read_verilog" + flags + " " + ansi_c_escape(filename);
|
|
1002
1047
|
}
|
|
1003
1048
|
const verilator_re = /^%(Warning|Error)[^:]*: ([^:]*):([0-9]+):([0-9]+): (.*)$/;
|
|
1004
1049
|
async function verilator_lint(filenames, dirname, options = {}) {
|
|
1005
1050
|
try {
|
|
1006
1051
|
const output = [];
|
|
1007
|
-
const verilator_result = await (0, util_1.promisify)(child_process.exec)('verilator -lint-only -Wall -Wno-DECLFILENAME -Wno-UNOPT -Wno-UNOPTFLAT ' + filenames.map(
|
|
1052
|
+
const verilator_result = await (0, util_1.promisify)(child_process.exec)('timeout -k10s 40s verilator -lint-only -Wall -Wno-DECLFILENAME -Wno-UNOPT -Wno-UNOPTFLAT ' + filenames.map(shell_escape).join(' '), { maxBuffer: 1000000, cwd: dirname || null, timeout: options.timeout || 60000 })
|
|
1008
1053
|
.catch(exc => exc);
|
|
1009
1054
|
for (const line of verilator_result.stderr.split('\n')) {
|
|
1010
1055
|
const result = line.match(verilator_re);
|
|
@@ -1046,8 +1091,9 @@ async function process(filenames, dirname, options = {}) {
|
|
|
1046
1091
|
: "";
|
|
1047
1092
|
const tmpjson = await tmp.tmpName({ postfix: '.json' });
|
|
1048
1093
|
let obj = undefined;
|
|
1049
|
-
const yosys_result = await (0, util_1.promisify)(child_process.exec)('yosys -p "
|
|
1050
|
-
|
|
1094
|
+
const yosys_result = await (0, util_1.promisify)(child_process.exec)('timeout -k10s 40s yosys -p "' + shell_escape_contents(filenames.map(process_filename).join('; ')) +
|
|
1095
|
+
'; hierarchy -auto-top; proc' + optimize_simp + fsmpass + '; memory -nomap; wreduce -memx' +
|
|
1096
|
+
optimize + '" -o "' + tmpjson + '"', { maxBuffer: 1000000, cwd: dirname || null, timeout: options.timeout || 60000 })
|
|
1051
1097
|
.catch(exc => exc);
|
|
1052
1098
|
try {
|
|
1053
1099
|
if (yosys_result instanceof Error) {
|
|
@@ -1093,8 +1139,14 @@ function io_ui(output) {
|
|
|
1093
1139
|
}
|
|
1094
1140
|
if (dev.type == 'Input')
|
|
1095
1141
|
dev.type = dev.bits == 1 ? 'Button' : 'NumEntry';
|
|
1096
|
-
if (dev.type == 'Output')
|
|
1097
|
-
|
|
1142
|
+
if (dev.type == 'Output') {
|
|
1143
|
+
if (dev.bits == 1)
|
|
1144
|
+
dev.type = 'Lamp';
|
|
1145
|
+
else if (dev.bits == 8 && (dev.label == 'display7' || dev.label.startsWith('display7_')))
|
|
1146
|
+
dev.type = 'Display7';
|
|
1147
|
+
else
|
|
1148
|
+
dev.type = 'NumDisplay';
|
|
1149
|
+
}
|
|
1098
1150
|
}
|
|
1099
1151
|
}
|
|
1100
1152
|
exports.io_ui = io_ui;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yosys2digitaljs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Export Yosys netlists to a logic simulator",
|
|
5
5
|
"main": "dist/index",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"author": "Marek Materzok",
|
|
14
14
|
"license": "BSD-2-Clause",
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"3vl": "^0.
|
|
16
|
+
"3vl": "^1.0.1",
|
|
17
17
|
"big-integer": "^1.6.49",
|
|
18
18
|
"hashmap": "^2.4.0",
|
|
19
19
|
"minimist": "^1.2.5",
|
package/src/index.ts
CHANGED
|
@@ -61,6 +61,7 @@ const gate_subst = new Map([
|
|
|
61
61
|
['$pmux', 'Mux1Hot'],
|
|
62
62
|
['$mem', 'Memory'],
|
|
63
63
|
['$mem_v2', 'Memory'],
|
|
64
|
+
['$lut', 'Memory'],
|
|
64
65
|
['$fsm', 'FSM'],
|
|
65
66
|
['$clock', 'Clock'],
|
|
66
67
|
['$button', 'Button'],
|
|
@@ -174,9 +175,11 @@ namespace Digitaljs {
|
|
|
174
175
|
|
|
175
176
|
namespace Yosys {
|
|
176
177
|
|
|
177
|
-
export
|
|
178
|
+
export const ConstChars = ["0", "1", "x", "z"] as const;
|
|
178
179
|
|
|
179
|
-
export type
|
|
180
|
+
export type BitChar = (typeof ConstChars)[number];
|
|
181
|
+
|
|
182
|
+
export type Bit = number | BitChar;
|
|
180
183
|
|
|
181
184
|
export type BitVector = Bit[];
|
|
182
185
|
|
|
@@ -403,7 +406,7 @@ function yosys_to_digitaljs(data: Yosys.Output, portmaps: Portmaps, options: Con
|
|
|
403
406
|
|
|
404
407
|
function yosys_to_digitaljs_mod(name: string, mod: Yosys.Module, portmaps: Portmaps, options: ConvertOptions = {}): Digitaljs.Module {
|
|
405
408
|
function constbit(bit: Bit) {
|
|
406
|
-
return
|
|
409
|
+
return (Yosys.ConstChars as readonly string[]).includes(bit.toString());
|
|
407
410
|
}
|
|
408
411
|
const nets = new HashMap<Net, NetInfo>();
|
|
409
412
|
const netnames = new HashMap<Net, string[]>();
|
|
@@ -433,8 +436,6 @@ function yosys_to_digitaljs_mod(name: string, mod: Yosys.Module, portmaps: Portm
|
|
|
433
436
|
const net = get_net(k);
|
|
434
437
|
if(net.source !== undefined) {
|
|
435
438
|
// multiple sources driving one net, disallowed in digitaljs
|
|
436
|
-
console.log(k);
|
|
437
|
-
console.log(net);
|
|
438
439
|
throw Error('Multiple sources driving net: ' + net.name);
|
|
439
440
|
}
|
|
440
441
|
net.source = { id: d, port: p };
|
|
@@ -1030,6 +1031,24 @@ function yosys_to_digitaljs_mod(name: string, mod: Yosys.Module, portmaps: Portm
|
|
|
1030
1031
|
}
|
|
1031
1032
|
break;
|
|
1032
1033
|
}
|
|
1034
|
+
case '$lut':
|
|
1035
|
+
assert(cell.connections.A.length == decode_json_number(cell.parameters.WIDTH));
|
|
1036
|
+
assert(cell.connections.Y.length == 1);
|
|
1037
|
+
assert(cell.port_directions.A == 'input');
|
|
1038
|
+
assert(cell.port_directions.Y == 'output');
|
|
1039
|
+
dev.abits = cell.connections.A.length;
|
|
1040
|
+
dev.bits = cell.connections.Y.length;
|
|
1041
|
+
dev.rdports = [{}];
|
|
1042
|
+
dev.wrports = [];
|
|
1043
|
+
dev.memdata = cell.parameters.LUT.split('').reverse();
|
|
1044
|
+
assert(dev.memdata.length == Math.pow(2, dev.abits));
|
|
1045
|
+
|
|
1046
|
+
// Rewrite cell connections to be $mem compatible for port mapping
|
|
1047
|
+
cell.connections.RD_ADDR = cell.connections.A;
|
|
1048
|
+
cell.connections.RD_DATA = cell.connections.Y;
|
|
1049
|
+
delete cell.connections.A;
|
|
1050
|
+
delete cell.connections.Y;
|
|
1051
|
+
break;
|
|
1033
1052
|
default:
|
|
1034
1053
|
}
|
|
1035
1054
|
if (dev.type == 'Dff') {
|
|
@@ -1048,6 +1067,7 @@ function yosys_to_digitaljs_mod(name: string, mod: Yosys.Module, portmaps: Portm
|
|
|
1048
1067
|
else if (cell.type == '$pmux') connect_pmux(dname, cell);
|
|
1049
1068
|
else if (cell.type == '$mem') connect_mem(dname, cell, dev);
|
|
1050
1069
|
else if (cell.type == '$mem_v2') connect_mem(dname, cell, dev);
|
|
1070
|
+
else if (cell.type == '$lut') connect_mem(dname, cell, dev);
|
|
1051
1071
|
else throw Error('Invalid cell type: ' + cell.type);
|
|
1052
1072
|
}
|
|
1053
1073
|
// Group bits into nets for complex sources
|
|
@@ -1150,17 +1170,41 @@ function yosys_to_digitaljs_mod(name: string, mod: Yosys.Module, portmaps: Portm
|
|
|
1150
1170
|
return mout;
|
|
1151
1171
|
}
|
|
1152
1172
|
|
|
1153
|
-
function
|
|
1154
|
-
|
|
1173
|
+
function ansi_c_escape_contents(cmd: string): string {
|
|
1174
|
+
function func(ch: string) {
|
|
1175
|
+
if (ch == '\t') return '\\t';
|
|
1176
|
+
if (ch == '\r') return '\\r';
|
|
1177
|
+
if (ch == '\n') return '\\n';
|
|
1178
|
+
return '\\x' + ch.charCodeAt(0).toString(16).padStart(2, '0');
|
|
1179
|
+
}
|
|
1180
|
+
return cmd.replace(/(["'\\])/g,'\\$1')
|
|
1181
|
+
.replace(/[\x00-\x1F\x7F-\x9F]/g, func);
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
function ansi_c_escape(cmd: string): string {
|
|
1185
|
+
return '"' + ansi_c_escape_contents(cmd) + '"';
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
function shell_escape_contents(cmd: string): string {
|
|
1189
|
+
return cmd.replace(/(["\r\n$`\\])/g,'\\$1');
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
function shell_escape(cmd: string): string {
|
|
1193
|
+
return '"' + shell_escape_contents(cmd) + '"';
|
|
1155
1194
|
}
|
|
1156
|
-
|
|
1195
|
+
|
|
1196
|
+
function process_filename(filename: string): string {
|
|
1197
|
+
const flags = /\.sv$/.test(filename) ? " -sv" : "";
|
|
1198
|
+
return "read_verilog" + flags + " " + ansi_c_escape(filename);
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1157
1201
|
const verilator_re = /^%(Warning|Error)[^:]*: ([^:]*):([0-9]+):([0-9]+): (.*)$/;
|
|
1158
1202
|
|
|
1159
1203
|
export async function verilator_lint(filenames: string[], dirname?: string, options: Options = {}): Promise<LintMessage[]> {
|
|
1160
1204
|
try {
|
|
1161
1205
|
const output: LintMessage[] = [];
|
|
1162
1206
|
const verilator_result: {stdout: string, stderr: string} = await promisify(child_process.exec)(
|
|
1163
|
-
'verilator -lint-only -Wall -Wno-DECLFILENAME -Wno-UNOPT -Wno-UNOPTFLAT ' + filenames.map(
|
|
1207
|
+
'timeout -k10s 40s verilator -lint-only -Wall -Wno-DECLFILENAME -Wno-UNOPT -Wno-UNOPTFLAT ' + filenames.map(shell_escape).join(' '),
|
|
1164
1208
|
{maxBuffer: 1000000, cwd: dirname || null, timeout: options.timeout || 60000})
|
|
1165
1209
|
.catch(exc => exc);
|
|
1166
1210
|
for (const line of verilator_result.stderr.split('\n')) {
|
|
@@ -1202,8 +1246,9 @@ export async function process(filenames: string[], dirname?: string, options: Op
|
|
|
1202
1246
|
const tmpjson = await tmp.tmpName({ postfix: '.json' });
|
|
1203
1247
|
let obj = undefined;
|
|
1204
1248
|
const yosys_result: {stdout: string, stderr: string, killed?: boolean, code?: number} = await promisify(child_process.exec)(
|
|
1205
|
-
'yosys -p "
|
|
1206
|
-
|
|
1249
|
+
'timeout -k10s 40s yosys -p "' + shell_escape_contents(filenames.map(process_filename).join('; ')) +
|
|
1250
|
+
'; hierarchy -auto-top; proc' + optimize_simp + fsmpass + '; memory -nomap; wreduce -memx' +
|
|
1251
|
+
optimize + '" -o "' + tmpjson + '"',
|
|
1207
1252
|
{maxBuffer: 1000000, cwd: dirname || null, timeout: options.timeout || 60000})
|
|
1208
1253
|
.catch(exc => exc);
|
|
1209
1254
|
try {
|
|
@@ -1248,8 +1293,14 @@ export function io_ui(output: Digitaljs.Module) {
|
|
|
1248
1293
|
}
|
|
1249
1294
|
if (dev.type == 'Input')
|
|
1250
1295
|
dev.type = dev.bits == 1 ? 'Button' : 'NumEntry';
|
|
1251
|
-
if (dev.type == 'Output')
|
|
1252
|
-
|
|
1296
|
+
if (dev.type == 'Output') {
|
|
1297
|
+
if (dev.bits == 1)
|
|
1298
|
+
dev.type = 'Lamp';
|
|
1299
|
+
else if (dev.bits == 8 && (dev.label == 'display7' || dev.label.startsWith('display7_')))
|
|
1300
|
+
dev.type = 'Display7';
|
|
1301
|
+
else
|
|
1302
|
+
dev.type = 'NumDisplay';
|
|
1303
|
+
}
|
|
1253
1304
|
}
|
|
1254
1305
|
}
|
|
1255
1306
|
|
package/test.sv
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
// Full adder
|
|
3
|
+
module fulladder(
|
|
4
|
+
input a,
|
|
5
|
+
input b,
|
|
6
|
+
input d,
|
|
7
|
+
output o,
|
|
8
|
+
output c
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
logic t, c1, c2;
|
|
12
|
+
|
|
13
|
+
halfadder ha1(a, b, t, c1);
|
|
14
|
+
halfadder ha2(t, d, o, c2);
|
|
15
|
+
|
|
16
|
+
assign c = c1 | c2;
|
|
17
|
+
|
|
18
|
+
endmodule
|
|
19
|
+
// Half adder
|
|
20
|
+
module halfadder(
|
|
21
|
+
input a,
|
|
22
|
+
input b,
|
|
23
|
+
output o,
|
|
24
|
+
output c
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
assign o = a ^ b;
|
|
28
|
+
assign c = a & b;
|
|
29
|
+
|
|
30
|
+
endmodule
|
|
31
|
+
|
package/test1.sv
ADDED
package/test1.v
ADDED
package/test2.v
ADDED
package/test3.sv
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Half adder
|
|
2
|
+
module halfadder(
|
|
3
|
+
input a,
|
|
4
|
+
input b,
|
|
5
|
+
output o,
|
|
6
|
+
output c
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
assign o = a ^ b;
|
|
10
|
+
assign c = a & b;
|
|
11
|
+
|
|
12
|
+
endmodule
|
|
13
|
+
|
|
14
|
+
// Full adder
|
|
15
|
+
module fulladder(
|
|
16
|
+
input a,
|
|
17
|
+
input b,
|
|
18
|
+
input d,
|
|
19
|
+
output o,
|
|
20
|
+
output c
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
logic t, c1, c2;
|
|
24
|
+
|
|
25
|
+
halfadder ha1(a, b, t, c1);
|
|
26
|
+
halfadder ha2(t, d, o, c2);
|
|
27
|
+
|
|
28
|
+
assign c = c1 | c2;
|
|
29
|
+
|
|
30
|
+
endmodule
|
|
31
|
+
|
|
32
|
+
// Multibit serial adder
|
|
33
|
+
module serialadder
|
|
34
|
+
#(parameter WIDTH = 4)(
|
|
35
|
+
input [WIDTH-1:0] a,
|
|
36
|
+
input [WIDTH-1:0] b,
|
|
37
|
+
output [WIDTH:0] o
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
logic [WIDTH:0] c;
|
|
41
|
+
logic [WIDTH-1:0] s;
|
|
42
|
+
|
|
43
|
+
assign c[0] = 1'b0;
|
|
44
|
+
|
|
45
|
+
genvar ii;
|
|
46
|
+
generate
|
|
47
|
+
for (ii=0; ii<WIDTH; ii=ii+1)
|
|
48
|
+
begin
|
|
49
|
+
fulladder fa(a[ii],b[ii],c[ii],s[ii],c[ii+1]);
|
|
50
|
+
end
|
|
51
|
+
endgenerate
|
|
52
|
+
|
|
53
|
+
assign o = {c[WIDTH], s};
|
|
54
|
+
|
|
55
|
+
endmodule
|
|
56
|
+
|
|
57
|
+
module zzz(
|
|
58
|
+
input [3:0] a,
|
|
59
|
+
input [3:0] b,
|
|
60
|
+
output [4:0] o
|
|
61
|
+
);
|
|
62
|
+
serialadder z(a,b,o);
|
|
63
|
+
endmodule
|
package/test3.v
ADDED
package/test4.sv
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Half adder
|
|
2
|
+
module halfadder(
|
|
3
|
+
input a,
|
|
4
|
+
input b,
|
|
5
|
+
output o,
|
|
6
|
+
output c
|
|
7
|
+
);
|
|
8
|
+
|
|
9
|
+
assign o = a ^ b;
|
|
10
|
+
assign c = a & b;
|
|
11
|
+
|
|
12
|
+
endmodule
|
|
13
|
+
|
|
14
|
+
// Full adder
|
|
15
|
+
module fulladder(
|
|
16
|
+
input a,
|
|
17
|
+
input b,
|
|
18
|
+
input d,
|
|
19
|
+
output o,
|
|
20
|
+
output c
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
logic t, c1, c2;
|
|
24
|
+
|
|
25
|
+
halfadder ha1(a, b, t, c1);
|
|
26
|
+
halfadder ha2(t, d, o, c2);
|
|
27
|
+
|
|
28
|
+
assign c = c1 | c2;
|
|
29
|
+
|
|
30
|
+
endmodule
|
|
31
|
+
|
|
32
|
+
// Multibit serial adder
|
|
33
|
+
module serialadder(
|
|
34
|
+
input [4-1:0] a,
|
|
35
|
+
input [4-1:0] b,
|
|
36
|
+
output [4:0] o
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
logic [4:0] c;
|
|
40
|
+
logic [4-1:0] s;
|
|
41
|
+
|
|
42
|
+
assign c[0] = 1'b0;
|
|
43
|
+
|
|
44
|
+
genvar ii;
|
|
45
|
+
generate
|
|
46
|
+
for (ii=0; ii<4; ii=ii+1)
|
|
47
|
+
begin
|
|
48
|
+
fulladder fa(a[ii],b[ii],c[ii],s[ii],c[ii+1]);
|
|
49
|
+
end
|
|
50
|
+
endgenerate
|
|
51
|
+
|
|
52
|
+
assign o = {c[4], s};
|
|
53
|
+
|
|
54
|
+
endmodule
|
|
55
|
+
|
|
56
|
+
module zzz(
|
|
57
|
+
input [3:0] a,
|
|
58
|
+
input [3:0] b,
|
|
59
|
+
output [4:0] o
|
|
60
|
+
);
|
|
61
|
+
serialadder z(a,b,o);
|
|
62
|
+
endmodule
|
package/tests/ram.sv
CHANGED
package/tests/z.sv
ADDED
package/yosyss
ADDED