![]()
작성일: 2008.03.31
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
(jsandstrom@mcimail.com)
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) ; | component inverter 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 area of 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 | wire out1 ; | 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 ; |
To voice an opinion on this or any Integrated System Design article, please e-mail your message to michael@asic.com.
![]()