With the advent of Verilog/VHDL co-simulators (Verilog = commercial and VHDL = DoD lines blurring) I thought I should hedge my bets by learning Verilog. I'm quite competent in VHDL, so armed with the Verilog-XL Reference Manual, the Digital Design with Verilog HDL book, and the free Wellspring Verilog simulator, I started my education.
The basics of each language seem common enough, but soon I was into nuances that I couldn't relate to. So, I decided I needed a summary of the language differenceshere it is.
The crux of the article is a cross-reference table indexed by Verilog (.v suffix) and VHDL (.vhd suffix) keywords. I don't show how to create designs using both languages, because Larry Saunders and Yatin Trivedi do a wonderful job. Nor do I show the BNF (Bachus-Naur Format) for language constructs, because the Language Reference Manuals and various "third-party" books cover the languages just fine. This table is merely a pointer into the other language.
Find the keyword of your favorite language in the "Keyword" column, then read along that row to find the other language equivalent keyword/construct/command in the "Equivalent" column. On the same row, in the "Verilog" and "VHDL" columns, are brief code fragments to illustrate a simple keyword usage with the keyword in bold type and names of user-created objects in italics.
I omitted the Verilog built-in compiler/simulator commands (+, -, $) because there are no VHDL equivalent commands, since the various VHDL tools have their own commands. I added the new VITAL (VHDL Initiative Towards ASIC Libraries) primitives that cross-reference to the Verilog primitives for netlisting purposes.
I suppose everybody knows that Verilog is patterned after "C" and VHDL is patterned after Ada. What that basically means is that Verilog is terse and doesn't take its type-checking seriously, whereas VHDL is verbose and strongly typed.
It would appear that the HDL benefits of Designing-in-English (if this ... else that), robust simulation capability, and logic synthesis can be achieved by either language. Being conversant in both languages allows access to a wide variety of models and tools to achieve maximum design efficiency and verification.
Johan Sandstrom (johan@sandstrom.org) is a system/logic design consultant who started out hand-drawing schematics and has evolved up the abstraction/tool chain.
Rob Antman (rob1a@aol.com) knows both languages and helped me over the rough spots in the table.
| Table 1 | |||
| Verilog/VHDL equivalent keywords | |||
| Keyword | Equivalent | Verilog | VHDL |
| abs.vhd | ?: // expression needed | out1 = (in1 < 0) ? -in1 : in1; | out1 <= abs(in1); |
| access.vhd | // no counterpart | // no counterpart | type pointer is access memory; |
| after.vhd | # | #10 out1 = in1; | out1 <= in1 after 10 ns; |
| alias.vhd | `define | `define status word[13] | alias status : std_logic is word(13); |
| all.vhd | +lib ... | // command line option | use libname.pkgname.all; |
| always.v | process | always begin ... end | process begin ... end process; |
| and.v // gate | vitaland | and (out1, in1, in2); | vitaland(out1, in1, in2); |
| and.vhd | &, && | out1 = in1 & in2; | out1 <= in1 and in2; |
| architecture.vhd | module | module name; endmodule | architecture name of entityname is ... end name; |
| array.vhd | reg[range] memory [range] | reg[0:3] memory [0:7] | type memory is array(0 to 3) of std_logic_vector(0 to 7); |
| assert.vhd | $display | if (not condition) $display("string"); | assert condition report "string" severity level; |
| assign.v | when ... else | if ... assign out1 = 0; else deassign out1; | when ... out1 <= '0'; else out1 <= 'Z'; |
| attribute.vhd | // no counterpart | // no counterpart | attribute capacitance : farads; |
| begin.v | begin | begin multiple statements end | name begin ... end name; |
| begin.vhd | begin | begin multiple statements end | name begin ... end name; |
| block.vhd | begin ... end | begin multiple statements end | alu : block ... end block alu; |
| body.vhd | // hierarchical path names | pkgname.definitions | package body pkgname is ... end pkgname; |
| buf.v // gate | vitalbuf | buf (out1, in1); | vitalbuf(out1, in1); |
| buffer.vhd | out | out out1; | port(out1 : buffer std_logic); |
| bufif0.v // gate | vitalbufif0 | bufif0(out1, in1, control1); | vitalbufif0(out1, in1, control1); |
| bufif1.v // gate | vitalbufif1 | bufif1(out1, in1, control1); | vitalbufif1(out1, in1, control1); |
| bus.vhd | tri | tri name; | signal name : std_logic bus; |
| case.v | case | case (expression) choices endcase | case expression is when choice => out1 <= in1; end case; |
| case.vhd | case | case (expression) choices endcase | case expression is when choice => out1 <= in1; end case; |
| casex.v | no direct counterpart | casex (expression) choices endcase | no direct counterpart |
| casez.v | no direct counterpart | casez (expression) choices endcase | no direct counterpart |
| cmos.v // gate | no standard counterpart | cmos(out1, in1, ncontrol, pcontrol); | no standard counterpart |
| component.vhd | // structural instantiation | inverter u1 (out1, in1); | componentinverter port(out1 : out std_logic; in1 : in std_logic); |
| configuration.vhd | // no counterpart | // no counterpart | configuration name of EntityName is ... end name; |
| constant.vhd | parameter | parameter maxsize = 64; | constant maxsize : positive := 64; |
| deassign.v | when ... else | if ... assign out1 = 0; else deassign out1; | when ... out1 <= '0'; else out1 <= 'Z'; |
| default.v | others | case (expression) ... default : out1 = in2; | case expression is ... when others => out1 <= in2; end case; |
| defparam.v | generic map | defparam maxsize = 32; | generic map(maxsize => 32); |
| disable.v | exit, next, return | for ... disable name ... | loop ... next when ... end loop; |
| disconnect.vhd | ?: // expression needed | out1 = guard ? in1 : 'bz; | disconnect GuardedSignalName : std_logic after 10 ns; |
| downto.vhd | // [higher:lower] | [15:0] | (15 downto 0) |
| else.v | else | if ... else if ... else | if ... then ... elsif ... then ... else ... end if; |
| else.vhd | else | if ... else if ... else | if ... then ... elsif ... then ... else ... end if; |
| elsif.vhd | else, if | if ... else if ... else | if ... then ... elsif ... then ... else ... end if; |
| end.v | end | begin multiple statements end | ... end ... ; |
| end.vhd | end | begin multiple statements end | ... end ... ; |
| endcase.v | case ... end case; | case (expression) choices endcase | case expression is when choice => out1 <= in1; end case; |
| endfunction.v | function ... end; | function name; ... endfunction | function name(...) return std_logic is ... end name; |
| endmodule.v | entity/architecture | module name; ... endmodule | entity name is ... end name; architecture ... |
| endprimitive.v // gate | VitalTruthTable | primitive name ... endprimitive | procedure VitalTruthTable(...); |
| endspecify.v | generic | specify specparem setup=10; endspecify | entity name is generic(setup : time := 10 ns); ... |
| endtable.v // gate | VitalTruthTable | table ... endtable | procedure VitalTruthTable(...); |
| endtask.v | procedure ... end; | task name; ... endtask | procedure name(...) is ... end name; |
| entity.vhd | module | module name; ... endmodule | entity name is ... end name; |
| event.v | signal | event name; | signal name : sync_type; |
| exit.vhd | disable | for ... disable name ... | loop ... exit when ... end loop; |
| file.vhd | $input | $input("source.txt"); | file source_code : text is in "source.txt"; |
| for.v | for | for (i = 1; i <= 10; i = i + 1) | for i in 1 to 10 loop |
| for.vhd | for, repeat | for (i = 1; i <= 10; i = i + 1) | for i in 1 to 10 loop |
| force.v | user defined resolution function | if ... force out1 = 0; else release out1; | out1 <= stomp_value; perhaps in an error_injector component. |
| forever.v | wait | forever @(posedge clock) out1 = in1; | wait until rising_edge(clock); out1 <= in1; |
| fork.v | user defined synchronization | ... fork concurrent_execution join ... | wait on sync'transaction until sync = 300; |
| function.v | function | function name; ... endfunction | function name(...) return std_logic is ... end name; |
| function.vhd | function | function name; ... endfunction | function name(...) return std_logic is ... end name; |
| generate.vhd | // no counterpart | // no counterpart | generate_label : if expression generate ... end generate; |
| generic.vhd | defparam, specparem | defparam maxsize = 32; | entity name is generic(maxsize : natural := 32); ... |
| group.vhd | // no counterpart | // no counterpart | attribute rising_delay of c2q : group is 7.2 ns; |
| guarded.vhd | ?: // expression needed | out1 = guard ? in1 : 'bz; | block (guard-expression) ... out1 <= guarded in1 after 10 ns; |
| highz0.v // strength | 'Z' in std_logic_1164 | buf(highz0) out1; | out1 <= 'Z'; |
| highz1.v // strength | 'Z' in std_logic_1164 | buf(highz1) out1; | out1 <= 'Z'; |
| if.v | if | if ... else if ... else | if ... then ... elsif ... then ... else ... end if; |
| if.vhd | if | if ... else if ... else | if ... then ... elsif ... then ... else ... end if; |
| impure.vhd | // no counterpart | // no counterpart | impure function ... |
| in.vhd | input | output out1; input in1; | port(out1 : out std_logic; in1 : in std_logic); |
| inertial.vhd | // inertial by default | #10 out1 = in1; | out1 <= reject 5 ns inertial in1 after 10 ns; |
| initial.v | process | initial begin ... end | process begin ... wait; end process; |
| inout.v | inout | inout inout1; | port(inout1 : inout std_logic); |
| inout.vhd | inout | inout inout1; | port(inout1 : inout std_logic); |
| input.v | in | output out1; input in1; | port(out1 : out std_logic; in1 : in std_logic); |
| integer.v | predefined type | integer name; | signal name : integer; |
| is.vhd | // unnecessary | module name; ... endmodule | entity name is ... end name; |
| join.v | user defined synchronization | ... fork concurrent_execution join ... | wait on sync'transaction until sync = 300; |
| label.vhd | // no counterpart | // no counterpart | attribute location of adder1 : label is (10, 15); |
| large.v // charge | enumerated type | trireg(large) out1; | type strength is (small, medium, large); |
| library.vhd | +lib ... | // command line option | library libname; |
| linkage.vhd | // no counterpart | // no counterpart | port(out1 : linkage std_logic; in1 : in std_logic); |
| literal.vhd | // no counterpart | // no counterpart | attribute areaof others : literal is 7; |
| loop.vhd | while, for, etc. | while (condition) | while (condition) loop |
| macromodule.v // gate | entity/architecture | macromodule name; ... endmodule | entity name is ... end name; architecture ... |
| map.vhd | // structural instantiation | inverter u1 (out1, in1); | u1 : inverter port map(out1 => out1, in1 => in1); |
| medium.v // charge | enumerated type | trireg(medium) out1; | type strength is (small, medium, large); |
| mod.vhd | % | out1 = in1 % in2; | out1 <= in1 mod in2; |
| module.v | entity/architecture | module name; ... endmodule | entity name is ... end name; architecture ... |
| nand.v // gate | vitalnand | nand (out1, in1, in2); | vitalnand(out1, in1, in2); |
| nand.vhd | ~, & | out1 = ~(in1 & in2); | out1 <= in1 nand in2; |
| negedge.v | falling_edge std_logic_1164 | always @ (negedge clk) begin ... end | wait until falling_edge(clk); |
| new.vhd | // no counterpart | // no counterpart | pointer := new name ... deallocate(name); |
| next.vhd | disable | for ... disable name ... | loop ... next when ... end loop; |
| nmos.v // gate | vitalbufif1 | nmos(out1, in1, control1); | vitalbufif1(out1, in1, control1, ... ResultMap); |
| nor.v // gate | vitalnor | nor (out1, in1, in2); | vitalnor(out1, in1, in2); |
| nor.vhd | ~, | | out1 = ~(in1 | in2); | out1 <= in1 nor in2; |
| not.v // gate | vitalinv | not (out1, in1); | vitalinv(out1, in1); |
| not.vhd | ~ | out1 = ~in1; | out1 <= not(in1); |
| notif0.v // gate | vitalinvif0 | notif0(out1, in1, control1); | vitalinvif0(out1, in1, control1); |
| notif1.v // gate | vitalinvif1 | notif1(out1, in1, control1); | vitalinvif1(out1, in1, control1); |
| null.vhd | // no direct counterpart | // no direct counterpart | case expression is when choice => out1 <= null; end case; |
| of.vhd | // unnecessary | module name; ... endmodule | architecture name of entityname is ... end name; |
| on.vhd | @ | @(posedge in1) ... | wait on in1; |
| open.vhd | // no counterpart | // no counterpart | u1 : inverter port map(out1 => open, in1 => in1); |
| or.v // gate | vitalor | or (out1, in1, in2); | vitalor(out1, in1, in2); |
| or.vhd | |, || | out1 = in1 | in2; | out1 <= in2 or in2; |
| others.vhd | default | case (expression) ... default : out1 = in2; | case expression is ... when others => out1 <= in2; end case; |
| out.vhd | output | output out1; input in1; | port(out1 : out std_logic; in1 : in std_logic); |
| output.v | out | output out1; input in1; | port(out1 : out std_logic; in1 : in std_logic); |
| package.vhd | // hierarchical path names | pkgname.definitions | package pkgname is ... end pkgname; |
| parameter.v | constant | parameter maxsize = 64; | constant maxsize : positive := 64; |
| pmos.v // gate | vitalbufif0 | pmos(out1, in1, control1); | vitalbufif0(out1, in1, control1, ... ResultMap); |
| port.vhd | module name (port signals); | module name (out1, in1); ... endmodule | port(out1 : out std_logic; in1 : in std_logic); |
| posedge.v | rising_edge std_logic_1164 | always @ (posedge clk) begin ... end | wait until rising_edge(clk); |
| postponed.vhd | #0 | #0 ... | postponed process ... |
| primitive.v // gate | VitalTruthTable | primitive name ... endprimitive | procedure VitalTruthTable(...); |
| procedure.vhd | task | task name; ... endtask | procedure name(...) is ... end name; |
| process.vhd | always | always begin ... end | process begin ... end process; |
| pull0.v // strength | 'L' in std_logic_1164 | buf(pull0) out1; | out1 <= 'L'; |
| pull1.v // strength | 'H' in std_logic_1164 | buf(pull1) out1; | out1 <= 'H'; |
| pulldown.v // gate | vitalbuf | pulldown(pull0) (out1); | out1 <= 'L'; |
| pullup.v // gate | vitalbuf | pullup(pull1) (out1); | out1 <= 'H'; |
| pure.vhd | // no counterpart | // no counterpart | pure function ... |
| range.vhd | // no counterpart | // no counterpart | for i in inputs'range loop ... end loop; |
| rcmos.v // gate | no standard counterpart | rcmos(out1, in1, ncontrol, pcontrol); | no standard counterpart |
| record.vhd | // hierarchical path names | module record_name ... endmodule | type name is record ... end record; |
| reg.v | variable, signal | reg name; | variable name : std_logic; |
| register.vhd | trireg | trireg name; | signal name: std_logic register; |
| reject.vhd | // no counterpart | // no counterpart | out1 <= reject 5 ns inertial in1 after 10 ns; |
| release.v | user defined resolution function | if ... force out1 = 0; else release out1; | out1 <= stomp_value; perhaps in an error_injector component. |
| rem.vhd | % | out1 = in1 % in2; | out1 <= in1 rem in2; |
| repeat.v | for | repeat (10) | for i in 1 to 10 loop ... |
| report.vhd | $display | if (not condition) $display("string"); | assert condition report "string" severity level; |
| return.vhd | disable | task name; ... disable name; | function name(...) return std_logic is ... end name; |
| rnmos.v // gate | vitalbufif1 | rnmos(out1, in1, control1); | vitalbufif1(out1, in1, control1, ... ResultMap); |
| rol.vhd | {} // expression needed | alu_data = {alu_data[5:0], alu_data[7:6]}; | alu_data <= alu_data rol 2; |
| ror.vhd | {} // expression needed | alu_data = {alu_data[1:0], alu_data[7:2]}; | alu_data <= alu_data ror 2; |
| rpmos.v // gate | vitalbufif0 | rpmos(out1, in1, control1); | vitalbufif0(out1, in1, control1, ... ResultMap); |
| rtran.v // gate | no standard counterpart | rtran(inout1, inout2); | no standard counterpart |
| rtranif0.v // gate | no standard counterpart | rtranif0(inout1, inout2, control); | no standard counterpart |
| rtranif1.v // gate | no standard counterpart | rtranif1(inout1, inout2, control); | no standard counterpart |
| scalared.v | std_logic_vector | tri1 scalared[63:0] name; | signal name : std_logic_vector(63 downto 0); |
| select.vhd | ?: // expression needed | cond_expr ? true_expr : false_expr | with expression select choices |
| severity.vhd | $stop, $finish | $stop(1); | assert condition report "string" severity level; |
| shared.vhd | // no counterpart | // no counterpart | shared variable ... |
| signal.vhd | wire | wire in1; | signal in1 : std_logic; |
| sla.vhd | // sla function needed | alu_data = sla(alu_data, 2); | alu_data <= alu_data sla 2; |
| sll.vhd | << | alu_data = alu_data << 2; | alu_data <= alu_data sll 2; |
| small.v // charge | enumerated type | trireg(small) out1; | type strength is (small, medium, large); |
| specify.v | generic | specify specparem setup=10; endspecify | entity name is generic(setup : time := 10 ns); ... |
| specparam.v | generic | specify specparem setup=10; endspecify | entity name is generic(setup : time := 10 ns); ... |
| sra.vhd | // sra function needed | alu_data = sra(alu_data, 2); | alu_data <= alu_data sra 2; |
| srl.vhd | >> | alu_data = alu_data >> 2; | alu_data <= alu_data srl 2; |
| strong0.v // strength | '0' in std_logic_1164 | buf(strong0) out1; | out1 <= '0'; |
| strong1.v // strength | '1' in std_logic_1164 | buf(strong1) out1; | out1 <= '1'; |
| subtype.vhd | // predefined types | // predefined types | subtype subtypename is typename range ... ; |
| supply0.v // strength | '0' in std_logic_1164 | buf(supply0) out1; | out1 <= '0'; |
| supply1.v // strength | '1' in std_logic_1164 | buf(supply1) out1; | out1 <= '1'; |
| table.v // gate | VitalTruthTable | table ... endtable | procedure VitalTruthTable(...); |
| task.v | procedure | task name; ... endtask | procedure name is ... end name; |
| then.vhd | // unnecessary | if ... else if ... else | if ... then ... elsif ... then ... else ... end if; |
| time.v | predefined type | time setup; | generic(setup: time := 3 ns); |
| to.vhd | // [lower:higher] | [0:15] | (0 to 15) |
| tran.v // gate | no standard counterpart | tran(inout1, inout2); | no standard counterpart |
| tranif0.v // gate | no standard counterpart | tranif0(inout1, inout2, control); | no standard counterpart |
| tranif1.v // gate | no standard counterpart | tranif1(inout1, inout2, control); | no standard counterpart |
| transport.vhd | // inertial only | // no counterpart | out1 <= transport in1 after 10 ns; |
| tri.v // net | bus, resolved signal | tri out1; | signal out1 : resolved_tri; |
| tri0.v // net | resolved signal | tri0 out1; | signal out1 : resolved_tri0; |
| tri1.v // net | resolved signal | tri1 out1; | signal out1 : resolved_tri1; |
| triand.v // net | resolved signal | triand out1; | signal out1 : resolved_triand; |
| trior.v // net | resolved signal | trior out1; | signal out1 : resolved_trior; |
| trireg.v // net | register, resolved signal | trireg out1; | signal out1 : resolved_trireg; |
| type.vhd | // predefined types | // predefined types | type typename ... enumerate; |
| unaffected.vhd | ?: // expression needed | #delay_value out1 = condition ? out1 : in1; | out1 <= unaffected when condition else in1 after delay_value; |
| units.vhd | // no counterpart | // no counterpart | physical type ... units ... |
| until.vhd | wait | wait (condition); | wait until condition; |
| use.vhd | +lib ... | // command line option | use libname.pkgname.all; |
| variable.vhd | reg | reg name; | variable name : std_logic; |
| vectored.v | enumerated type | tri vectored[31:0] name; | signal name : enumerated_type; |
| wait.v | wait | wait (condition); | wait [on] [until] [for] ... ; |
| wait.vhd | wait | wait (condition); | wait [on] [until] [for] ... ; |
| wand.v // net | resolved signal | wand out1; | signal out1 : resolved_wand; |
| weak0.v // strength | 'L' in std_logic_1164 | buf(weak0) out1; | out1 <= 'L'; |
| weak1.v // strength | 'H' in std_logic_1164 | buf(weak1) out1; | out1 <= 'H'; |
| when.vhd | case | case (expression) choices | case expression is when choice => out1 <= in1; end case; |
| while.v | while | while (condition) | while (condition) loop |
| while.vhd | while | while (condition) | while (condition) loop |
| wire.v // net | resolved signal | signal out1 : resolved_wire; | |
| with.vhd | ?: // expression needed | cond_expr ? true_expr : false_expr | with expression select choices |
| wor.v // net | resolved signal | wor out1; | signal out1 : resolved_wor; |
| xnor.v // gate | vitalxnor | xnor (out1, in1, in2); | vitalxnor(out1, in1, in2); |
| xnor.vhd | ^~ | out1 = in1 ^~ in2; | out1 <= in1 xnor in2; |
| xor.v // gate | vitalxor | xor (out1, in1, in2); | vitalxor(out1, in1, in2); |
| xor.vhd | ^ | out1 = in1 ^ in2; | out1 <= in1 xor in2; |
Home | About Us | Demo | Products | Articles | Methodology | Vocation | Avocation