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.
@@ -1,6 +1,6 @@
1
1
  name: Node.js CI
2
2
 
3
- on: [push]
3
+ on: [push, pull_request]
4
4
 
5
5
  jobs:
6
6
  build:
@@ -9,7 +9,7 @@ jobs:
9
9
 
10
10
  strategy:
11
11
  matrix:
12
- node-version: [8.x, 10.x, 12.x]
12
+ node-version: [18.x]
13
13
 
14
14
  steps:
15
15
  - uses: actions/checkout@v2
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](http://www.clifford.at/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](http://www.clifford.at/yosys/) installed to run
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
- type BitChar = '0' | '1' | 'x';
58
- type Bit = number | '0' | '1' | 'x';
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 == '0' || bit == '1' || bit == 'x';
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 escape_filename(cmd) {
1001
- return '"' + cmd.replace(/(["\s'$`\\])/g, '\\$1') + '"';
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(escape_filename).join(' '), { maxBuffer: 1000000, cwd: dirname || null, timeout: options.timeout || 60000 })
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 "hierarchy -auto-top; proc' + optimize_simp + fsmpass + '; memory -nomap; wreduce -memx' +
1050
- optimize + '" -o "' + tmpjson + '" ' + filenames.map(escape_filename).join(' '), { maxBuffer: 1000000, cwd: dirname || null, timeout: options.timeout || 60000 })
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
- dev.type = dev.bits == 1 ? 'Lamp' : 'NumDisplay';
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.6.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.3.5",
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 type BitChar = '0' | '1' | 'x';
178
+ export const ConstChars = ["0", "1", "x", "z"] as const;
178
179
 
179
- export type Bit = number | '0' | '1' | 'x';
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 bit == '0' || bit == '1' || bit == 'x';
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 escape_filename(cmd: string): string {
1154
- return '"' + cmd.replace(/(["\s'$`\\])/g,'\\$1') + '"';
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(escape_filename).join(' '),
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 "hierarchy -auto-top; proc' + optimize_simp + fsmpass + '; memory -nomap; wreduce -memx' +
1206
- optimize + '" -o "' + tmpjson + '" ' + filenames.map(escape_filename).join(' '),
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
- dev.type = dev.bits == 1 ? 'Lamp' : 'NumDisplay';
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
@@ -0,0 +1,19 @@
1
+
2
+ module m(
3
+ input a,
4
+ output b
5
+ );
6
+
7
+ n x(a, b);
8
+
9
+ endmodule
10
+
11
+ module n(
12
+ input a,
13
+ output b
14
+ );
15
+
16
+ assign b = !a;
17
+
18
+ endmodule
19
+
package/test1.v ADDED
@@ -0,0 +1,19 @@
1
+
2
+ module m(
3
+ input a,
4
+ output b
5
+ );
6
+
7
+ n x(a, b);
8
+
9
+ endmodule
10
+
11
+ module n(
12
+ input a,
13
+ output b
14
+ );
15
+
16
+ assign b = !a;
17
+
18
+ endmodule
19
+
package/test2.v ADDED
@@ -0,0 +1,19 @@
1
+
2
+ module n(
3
+ input a,
4
+ output b
5
+ );
6
+
7
+ assign b = !a;
8
+
9
+ endmodule
10
+
11
+ module m(
12
+ input a,
13
+ output b
14
+ );
15
+
16
+ n x(a, b);
17
+
18
+ endmodule
19
+
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
@@ -0,0 +1,19 @@
1
+
2
+ module m(
3
+ input a,
4
+ output b
5
+ );
6
+
7
+ assign b = !a;
8
+
9
+ endmodule
10
+
11
+ module n(
12
+ input a,
13
+ output b
14
+ );
15
+
16
+ m x(a, b);
17
+
18
+ endmodule
19
+
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
@@ -1,5 +1,5 @@
1
1
  // Simple RAM
2
- module rom
2
+ module ram
3
3
  #(parameter AWIDTH = 4, DWIDTH = 4)(
4
4
  input clk,
5
5
  input [AWIDTH-1:0] addr,
package/tests/z.sv ADDED
@@ -0,0 +1,7 @@
1
+ // high impedance state
2
+ module sourceZ(
3
+ output out
4
+ );
5
+ assign out = 1'bZ;
6
+
7
+ endmodule
package/yosyss ADDED
@@ -0,0 +1,4 @@
1
+ #!/bin/bash
2
+
3
+ kill -9 $$
4
+