diff --git a/README.md b/README.md index 4f89b092..b2cc15d0 100644 --- a/README.md +++ b/README.md @@ -61,15 +61,16 @@ Other languages are supported via extensions: [Apollo](src/lang-apollo.js); [Basic](src/lang-basic.js); -[Clojure](src/lang-clj.js); [CSS](src/lang-css.js); +[Clojure](src/lang-clj.js); [Dart](src/lang-dart.js); [Erlang](src/lang-erlang.js); [Go](src/lang-go.js); [Haskell](src/lang-hs.js); +[LLVM](src/lang-llvm.js); +[LaTeX](src/lang-tex.js); [Lasso](src/lang-lasso.js); [Lisp, Scheme](src/lang-lisp.js); -[LLVM](src/lang-llvm.js); [Logtalk](src/lang-logtalk.js); [Lua](src/lang-lua.js); [MATLAB](src/lang-matlab.js); @@ -81,16 +82,16 @@ Other languages are supported via extensions: [R, S](src/lang-r.js); [RD](src/lang-rd.js); [Rust](src/lang-rust.js); -[Scala](src/lang-scala.js); [SQL](src/lang-sql.js); +[Scala](src/lang-scala.js); [Swift](src/lang-swift.js); [TCL](src/lang-tcl.js); -[LaTeX](src/lang-tex.js); -[Visual Basic](src/lang-vb.js); [VHDL](src/lang-vhdl.js); +[Verilog](src/lang-verilog.js); +[Visual Basic](src/lang-vb.js); [Wiki](src/lang-wiki.js); [XQ](src/lang-xq.js); -[YAML](src/lang-yaml.js) +[YAML](src/lang-yaml.js); If you'd like to add an extension for your favorite language, please look at `src/lang-lisp.js` and submit a pull request. diff --git a/src/lang-verilog.js b/src/lang-verilog.js new file mode 100644 index 00000000..35c9befd --- /dev/null +++ b/src/lang-verilog.js @@ -0,0 +1,48 @@ +/** + * @license + * Copyright (C) 2020 wmin0@hotmail.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @fileoverview + * Registers a language handler for Verilog. + * + * Based on the lexical grammar and keywords at + * https://www.verilog.com/VerilogBNF.html#REF170 + * + * @author wmin0@hotmail.com + */ +PR['registerLangHandler']( + PR['createSimpleLexer']( + [ + [PR['PR_PLAIN'], /^[\t\n\r \xA0]+/, null, '\t\n\r \xA0'], + [PR['PR_PUNCTUATION'], /^[.!%&()*+,\-;<=>?\[\\\]^{|}:@#]+/, null, '.!%&()*+,-;<=>?[\\]^{|}:@#'] + ], + [ + [PR['PR_KEYWORD'], /^(?:\$hold|\$period|\$recovery|\$setup|\$setuphold\$skew|\$width|always|assign|begin|case|casex|casez|default|defparam|disable|else|end|endcase|endfunction|endmodule|endprimitive|endspecify|endtable|endtask|for|force|forever|fork|function|if|initial|join|macromodule|module|negedge|parameter|posedge|primitive|release|repeat|specify|specparam|table|task|wait|while)(?=[^\w-]|$)/i], + [PR['PR_TYPE'], /^(?:and|buf|bufif0|bufif1|cmos|event|inout|input|integer|nand|nmos|nor|not|notif0|notif1|or|output|pmos|pulldown|pullup|rcmos|real|reg|rnmos|rpmos|rtran|rtranif0|rtranif1|scalared|supply0|supply1|time|tran|tranif0|tranif1|tri|tri0|tri1|triand|trior|trireg|vectored|wand|wire|wor|xnor|xor)(?=[^\w-]|$)/i], + [PR['PR_TAG'], /^(?:highz0|highz1|large|medium|pull0|pull1|small|strong0|strong1|supply0|supply1|weak0|weak1)(?=[^\w-]|$)/i], + // number + [PR['PR_LITERAL'], /^(?:[0-9][0-9_]*(?:\.[0-9_]+)?(?:e[0-9_]+)?)|(?:(?:[0-9][0-9_]*)?'[bodh][0-9a-fA-FxXzZ?]+)/i], + // edge + [PR['PR_LITERAL'], /^(?:01|0x|10|1x|x0|x1)(?=[^\w-]|$)/i], + // string + [PR['PR_STRING'], /^"([^"\\]|\\[\s\S])*"/], + // double slash comments + [PR['PR_COMMENT'], /^\/\/.*/], + // slash star comments and documentation + [PR['PR_COMMENT'], /^\/\*[\s\S]*?(?:\*\/|$)/] + ]), + ['verilog', 'v']); diff --git a/tests/prettify_test_2.html b/tests/prettify_test_2.html index c62e032b..fcda9c2b 100644 --- a/tests/prettify_test_2.html +++ b/tests/prettify_test_2.html @@ -36,6 +36,7 @@ 'lang-r.js', 'lang-tcl.js', 'lang-tex.js', + 'lang-verilog.js', 'lang-xq.js' ]; var styles = [ @@ -1201,5 +1202,76 @@

Kotlin

fun Boolean?.getOrThrow(): Boolean = this ?: throw Exception() + +

Verilog

+
+/*
+ * Multiline
+ * comment
+ */
+a = "123"
+nor ( small )
+nor (highz1, strong0)
+//-----------------------------------------------------
+// Design Name : cam
+// File Name   : cam.v
+// Function    : CAM
+// Coder       : Deepak Kumar Tala
+//-----------------------------------------------------
+module cam (
+clk         , // Cam clock
+cam_enable  , // Cam enable
+cam_data_in , // Cam data to match
+cam_hit_out , // Cam match has happened
+cam_addr_out  // Cam output address
+);
+
+parameter ADDR_WIDTH  = 8;
+parameter DEPTH       = 1 << ADDR_WIDTH;
+//------------Input Ports--------------
+input                    clk;
+input                    cam_enable;
+input  [DEPTH-1:0]       cam_data_in;
+//----------Output Ports--------------
+output                   cam_hit_out;
+output [ADDR_WIDTH-1:0]  cam_addr_out;
+//------------Internal Variables--------
+reg [ADDR_WIDTH-1:0]  cam_addr_out;
+reg                   cam_hit_out;
+reg [ADDR_WIDTH-1:0]  cam_addr_combo;
+reg                   cam_hit_combo;
+reg                   found_match;
+integer               i;
+//-------------Code Starts Here-------
+always @(cam_data_in) begin
+  cam_addr_combo   = {ADDR_WIDTH{1'b0}};
+  found_match      = 1'b0;
+  cam_hit_combo    = 1'b0;
+  for (i=0; i<DEPTH; i=i+1) begin
+    if (cam_data_in[i] && !found_match) begin
+      found_match     = 1'b1;
+      cam_hit_combo   = 1'b1;
+      cam_addr_combo  = i;
+    end else begin
+      found_match     = found_match;
+      cam_hit_combo   = cam_hit_combo;
+      cam_addr_combo  = cam_addr_combo;
+    end
+  end
+end
+
+// Register the outputs
+always @(posedge clk) begin
+  if (cam_enable) begin
+    cam_hit_out  <=  cam_hit_combo;
+    cam_addr_out <=  cam_addr_combo;
+  end else begin
+    cam_hit_out  <=  1'b0;
+    cam_addr_out <=  {ADDR_WIDTH{1'b0}};
+  end
+end
+
+endmodule
+
diff --git a/tests/prettify_test_2.js b/tests/prettify_test_2.js index 03e29f5a..d8e99ced 100644 --- a/tests/prettify_test_2.js +++ b/tests/prettify_test_2.js @@ -768,6 +768,75 @@ var goldens = { '\n' + '`END`KWDfun`END`PLN `END`TYPBoolean`END`PUN?.`END`PLNgetOrThrow`END`PUN():`END`PLN `END`TYPBoolean`END`PLN `END`PUN=`END`PLN `END`KWDthis`END`PLN `END`PUN?:`END`PLN `END`KWDthrow`END`PLN `END`TYPException`END`PUN()`END' ), + verilog: ( + '`COM/*\n' + + ' * Multiline\n' + + ' * comment\n' + + ' */`END`PLN\n' + + 'a `END`PUN=`END`PLN `END`STR"123"`END`PLN\n' + + '`ENDnor`END`PLN `END`PUN(`END`PLN `END`TAGsmall`END`PLN `END`PUN)`END`PLN\n' + + '`ENDnor`END`PLN `END`PUN(`END`TAGhighz1`END`PUN,`END`PLN `END`TAGstrong0`END`PUN)`END`PLN\n' + + '`END`COM//-----------------------------------------------------`END`PLN\n' + + '`END`COM// Design Name : cam`END`PLN\n' + + '`END`COM// File Name : cam.v`END`PLN\n' + + '`END`COM// Function : CAM`END`PLN\n' + + '`END`COM// Coder : Deepak Kumar Tala`END`PLN\n' + + '`END`COM//-----------------------------------------------------`END`PLN\n' + + '`END`KWDmodule`END`PLN cam `END`PUN(`END`PLN\n' + + 'clk `END`PUN,`END`PLN `END`COM// Cam clock`END`PLN\n' + + 'cam_enable `END`PUN,`END`PLN `END`COM// Cam enable`END`PLN\n' + + 'cam_data_in `END`PUN,`END`PLN `END`COM// Cam data to match`END`PLN\n' + + 'cam_hit_out `END`PUN,`END`PLN `END`COM// Cam match has happened`END`PLN\n' + + 'cam_addr_out `END`COM// Cam output address`END`PLN\n' + + '`END`PUN);`END`PLN\n' + + '\n' + + '`END`KWDparameter`END`PLN ADDR_WIDTH `END`PUN=`END`PLN `END`LIT8`END`PUN;`END`PLN\n' + + '`END`KWDparameter`END`PLN DEPTH `END`PUN=`END`PLN `END`LIT1`END`PLN `END`PUN<<`END`PLN ADDR_WIDTH`END`PUN;`END`PLN\n' + + '`END`COM//------------Input Ports--------------`END`PLN\n' + + '`END`TYPinput`END`PLN clk`END`PUN;`END`PLN\n' + + '`END`TYPinput`END`PLN cam_enable`END`PUN;`END`PLN\n' + + '`END`TYPinput`END`PLN `END`PUN[`END`PLNDEPTH`END`PUN-`END`LIT1`END`PUN:`END`LIT0`END`PUN]`END`PLN cam_data_in`END`PUN;`END`PLN\n' + + '`END`COM//----------Output Ports--------------`END`PLN\n' + + '`END`TYPoutput`END`PLN cam_hit_out`END`PUN;`END`PLN\n' + + '`END`TYPoutput`END`PLN `END`PUN[`END`PLNADDR_WIDTH`END`PUN-`END`LIT1`END`PUN:`END`LIT0`END`PUN]`END`PLN cam_addr_out`END`PUN;`END`PLN\n' + + '`END`COM//------------Internal Variables--------`END`PLN\n' + + '`END`TYPreg`END`PLN `END`PUN[`END`PLNADDR_WIDTH`END`PUN-`END`LIT1`END`PUN:`END`LIT0`END`PUN]`END`PLN cam_addr_out`END`PUN;`END`PLN\n' + + '`END`TYPreg`END`PLN cam_hit_out`END`PUN;`END`PLN\n' + + '`END`TYPreg`END`PLN `END`PUN[`END`PLNADDR_WIDTH`END`PUN-`END`LIT1`END`PUN:`END`LIT0`END`PUN]`END`PLN cam_addr_combo`END`PUN;`END`PLN\n' + + '`END`TYPreg`END`PLN cam_hit_combo`END`PUN;`END`PLN\n' + + '`END`TYPreg`END`PLN found_match`END`PUN;`END`PLN\n' + + '`END`TYPinteger`END`PLN i`END`PUN;`END`PLN\n' + + '`END`COM//-------------Code Starts Here-------`END`PLN\n' + + '`END`KWDalways`END`PLN `END`PUN@(`END`PLNcam_data_in`END`PUN)`END`PLN `END`KWDbegin`END`PLN\n' + + ' cam_addr_combo `END`PUN=`END`PLN `END`PUN{`END`PLNADDR_WIDTH`END`PUN{`END`LIT1\'b0`END`PUN}};`END`PLN\n' + + ' found_match `END`PUN=`END`PLN `END`LIT1\'b0`END`PUN;`END`PLN\n' + + ' cam_hit_combo `END`PUN=`END`PLN `END`LIT1\'b0`END`PUN;`END`PLN\n' + + ' `END`KWDfor`END`PLN `END`PUN(`END`PLNi`END`PUN=`END`LIT0`END`PUN;`END`PLN i`END`PUN<`END`PLNDEPTH`END`PUN;`END`PLN i`END`PUN=`END`PLNi`END`PUN+`END`LIT1`END`PUN)`END`PLN `END`KWDbegin`END`PLN\n' + + ' `END`KWDif`END`PLN `END`PUN(`END`PLNcam_data_in`END`PUN[`END`PLNi`END`PUN]`END`PLN `END`PUN&&`END`PLN `END`PUN!`END`PLNfound_match`END`PUN)`END`PLN `END`KWDbegin`END`PLN\n' + + ' found_match `END`PUN=`END`PLN `END`LIT1\'b1`END`PUN;`END`PLN\n' + + ' cam_hit_combo `END`PUN=`END`PLN `END`LIT1\'b1`END`PUN;`END`PLN\n' + + ' cam_addr_combo `END`PUN=`END`PLN i`END`PUN;`END`PLN\n' + + ' `END`KWDend`END`PLN `END`KWDelse`END`PLN `END`KWDbegin`END`PLN\n' + + ' found_match `END`PUN=`END`PLN found_match`END`PUN;`END`PLN\n' + + ' cam_hit_combo `END`PUN=`END`PLN cam_hit_combo`END`PUN;`END`PLN\n' + + ' cam_addr_combo `END`PUN=`END`PLN cam_addr_combo`END`PUN;`END`PLN\n' + + ' `END`KWDend`END`PLN\n' + + ' `END`KWDend`END`PLN\n' + + '`END`KWDend`END`PLN\n' + + '\n' + + '`END`COM// Register the outputs`END`PLN\n' + + '`END`KWDalways`END`PLN `END`PUN@(`END`KWDposedge`END`PLN clk`END`PUN)`END`PLN `END`KWDbegin`END`PLN\n' + + ' `END`KWDif`END`PLN `END`PUN(`END`PLNcam_enable`END`PUN)`END`PLN `END`KWDbegin`END`PLN\n' + + ' cam_hit_out `END`PUN<=`END`PLN cam_hit_combo`END`PUN;`END`PLN\n' + + ' cam_addr_out `END`PUN<=`END`PLN cam_addr_combo`END`PUN;`END`PLN\n' + + ' `END`KWDend`END`PLN `END`KWDelse`END`PLN `END`KWDbegin`END`PLN\n' + + ' cam_hit_out `END`PUN<=`END`PLN `END`LIT1\'b0`END`PUN;`END`PLN\n' + + ' cam_addr_out `END`PUN<=`END`PLN `END`PUN{`END`PLNADDR_WIDTH`END`PUN{`END`LIT1\'b0`END`PUN}};`END`PLN\n' + + ' `END`KWDend`END`PLN\n' + + '`END`KWDend`END`PLN\n' + + '\n' + + '`END`KWDendmodule`END' + ), llvm: ( '`COM; Declare the string constant as a global constant.`END`PLN\n' + '@.str `END`PUN=`END`PLN `END`KWDprivate`END`PLN `END`KWDunnamed_addr`END`PLN `END`KWDconstant`END`PLN `END`PUN[`END`LIT13`END`PLN `END`KWDx`END`PLN `END`KWDi8`END`PUN]`END`PLN `END`KWDc`END`STR"hello world\\0A\\00"`END`PLN\n' +