850 likes | 873 Views
2. Verilog Elements. Why (V)HDL? (VHDL, Verilog etc. ). module Mult ( inpu t [15:0] A, input [15:0] B, output [31:0] Y ); assign Y = A * B; endmodule. Karen Parnell, Nick Mehta, “Programmable Logic Design Quick Start Handbook”, Xilinx Coorporation , June 2003 ,.
E N D
Why (V)HDL? (VHDL, Verilog etc.) moduleMult ( input [15:0] A, input [15:0] B, output [31:0] Y ); assign Y = A * B; endmodule • Karen Parnell, Nick Mehta, “Programmable Logic Design Quick Start Handbook”, Xilinx Coorporation, June 2003,
Algorithmic level. Modelling systems and stimulus Behaviour Machine-independent description: registers, logic, clocking RTL “Gate-Level” netlist Logic Physical level – technology dependent. For ex: 15um Layout Advantages of HDL languages: • Easy to describe combinational circuits • High-level language – easy to be understand by both human and machine • Projects can be easily PARTITIONED and HIERARCHIZED – supports teamwork! • Allows for Design Reuse • Platform independent • Allows different levels of abstractization (what is this?) Abstractization: Hiding details of a project, insignifiant at a specific level. Abstractization level example HDL – useful for the upper three levels
VERILOG – Generalities • Verisign Logic (?) by Verisign. Inc. • Historically: 1984 Gateway Design Automation Inc, bought then by Cadence Design Systems, inc. • First IEEE standard in 1995: IEEE Std. 1364-1995., then in 2001 – IEEE std 1364-2001, then in 2005 - IEEE Standard 1364-2005 • Newest language extention: Verilog – AMS (Analog and Mixed Signal, standardized in 2008) • What VHDL/Verilog is used for? • To describe DIGITAL Systems and Circuits • To describe a TESTBENCH (used to test those above…) • Verilog is NOT a Programming language !!! • A Programming Language represents: (incomplete definition?) • A set of instructions and data, that is passed through a compiler or interpreter • The compiler transforms the set of instructions into machine code • The machine code is loaded into a MEMORY and executed by a PROCESSING UNIT • VHDL/Verilog do NOT comply with the above description!!! • Exception: A Testbench can be considered as a multi-threading program
VERILOG – Generalities • For a (BEHAVIORAL) Simulator: • VHDL/Verilog for Digital Circuits: The Instructions (Statements) are EXECUTED in order to SIMULATE the functionality of the circuit • Testbenches are also EXECUTED to create the input signaling and output verification • For a Synthesizer: • VHDL/Verilog for Digital Circuits: The statements are TRANSFORMED into digital elements (Logic gates, registers etc) • Testbenches are, by default, IGNORED by synthesizers • Therefore we speak about two types of HDL code: VHDL/Verilog for Synthesis VHDL/Verilog for Tetbenches
VHDL/Verilog for Synthesis • Generalities: EVERY DIGITAL CIRCUIT • Contains AT LEAST one input signal (port) (*), (**) • Contains AT LEAST one output signal (port) (**) • It may contain internal signals and lower-level components • (*) Assume the circuit contains an internal signal generator, the input can missing. NOT the case of FPGA designs! FPGA devices NEED EXTERNAL CLOCKING • (**) Circuits with no input and circuits with no output will be removed by the synthesizer in the optimization process. • (**) Same if the input ports are not read, or the output port is never written or constant
VHDL/Verilog for Synthesis • Moreover: EVERY: • Port • Internal Signal • Internal Component • … is IDENTIFIED by a Name (IDENTIFIER) (*) • (*) The OR gate will be probably described as: assign Cout = C1 | C0; • The synthesizer will generate an OR gate. Will the OR gate have no name? • Names i.e. IDENTIFIERS ARE IMPORTANT!
CASE SENSITIVE, keywords always written with small letters • Comment: // until the end of line • /* …Can extend on more than one line */ • A statement (instruction) can extend to more than one line! • More than one statements can be on the same line!!! • Instruction delimiter: ; (Every instruction ends up with; ) • Compound instructions: • begin – end:neitherbegin, norendare ended with ;Same for statements delimiting “the end of something”: endcase, endmodule etc. Verilog Syntax elements
List Delimiter: , • The last element of a list does not have to be delimited! A list is not ended with , ! • In a VHDL/Verilog code we assign signal and/or variable values. Verilog: Two type of assignments: • Blocking: ‘=‘ • Non-Blocking: for signals: ‘<=‘, for variables: ‘:=‘ • Recommendation: In “always” statements use NON-BLOCKING assignments • Inside of an “always” statements cannot mix non-blocking and blocking assignments • So: use <= for assingmnets Verilog Syntax elements
How to give a numerical value to a signal? • number_of_bits’[s]number_basevalue • Exemple: 1’b0; 2’b10, 16’hffef, 8’ds123; • Default numbering base: Decimal • What is 0, or 1, or 121? i.e. represented on how many bits? • s – signed value i.e. two’s complement • Some synthesizers do not support signed value • How to treat then a signed value? Verilog Syntax elements
USER IDENTIFIERS • Can contain letters, numbers, underscore ‘_’, CANNOT contain special characters such as /, ‘, “ • MUST start with letters • Examples: • Mysignal23 -- correct • rdy, RDY, Rdy -- these are DIFFERENT identifiers • vector_/_vector -- NO: Special character, not allowed • last line -- Spaces are not allowed • next__state -- Two consecutive underscores are NOT allowed • 10th_signal -- NO: Starts with a number • open, reg -- NO: Are Verilog Keywords Verilog Syntax elements
Extended Identifiers: • The Escape character \ allows for extended identifiers - Verilog ’93 +! • \12name – can begin with a number: ALLOWED • \last line\ -- ALLOWED • \next__state\ -- ALLOWED • \open\, \reg\ -- ALLOWED • XST: may need extra synthesis options to support Verilog ‘93! • Suggestion: try to avoid extended identifiers Verilog Syntax elements
Example forNaming convention (Xilinx) • -- active low signals: "*_n" • -- clock signals: "clk", "clk_div#", "clk_#x" • -- reset signals: "rst", "rst_n" • -- parameters: "C_*" • -- state machine next state: "*_ns" • -- state machine current state: "*_cs" • -- combinatorial signals: "*_cmb" • -- pipelined or register delay signals: "*_d#" • -- counter signals: "*cnt*" • -- clock enable signals: "*_ce" • -- internal version of output port "*_i" • -- device pins: "*_pin" • -- ports: - Names begin with Uppercase Verilog Syntax elements
Verilog Syntax elements • To create a digital component, we start with…? The component’s interface signals • Defined in MODULE • Module contains the WHOLE code of the component, including the definitions for • Ports – input, output and inout signals • Parameters – can be overwritten from the upper hierarchical level
General Form Definition Naming Conventions • <name> - MUST be there • [name] - Optional (does not have to be present) • <name1 | name2> - Either name1 or name 2 • [name1 | name2] – Optional name1 or name2 • Example: port definition: • <direction> [type] [size] <name>; • OR: • <input | output | inout> [wire | reg] [size] <name>;
Symbol Drawing Elements My_module A[7:0] 8 DATA[7:0] 8 B[7:0] 8 CE CLK • Input and Output Ports: Arrowheads will be usually missing • Usually, inputs are at the left side, outputs at the right side. If not, arrows indicating direction should be present • Inout ports: arrowheads should be present • Arrowhead indicating that is a clock signal (convention!) • These are only helpers, indicating the signal width. Recommended to be present
Symbol Drawing Elements My_module A[7:0] 8 DATA[7:0] 8 B[7:0] 8 CE CLK • Bus label designators are not part of the signal name!!! • Do not write input A[7:0]! • Syntactically is correct, but it will create an array of 8 signals, each signal of one bit wide • Do not use arrays for input/output ports! • The signal name is A • The bus designator is [7:0] • Correct form: input [7:0] A
Verilog Module Definition General Form • Prior Verilog 2001: • module <name> [#(paramater_list)] ( • <port_list>); • //for each port in the list: • <direction> [size] name; • Example: My_module • module My_module (A, B, CLK, DATA, CE); • input [7:0] A; • input [7:0] B; • input CLK; • inout [7:0] DATA; • output CE; • … • endmodule My_module A[7:0] 8 DATA[7:0] 8 B[7:0] 8 CE CLK This is a LIST of ports, end each element with , except the last one This is NOT a list of ports but port declaration statements, end each statement with ;
Verilog Module Definition General Form • Newer form – more compact • module <name> [#(parameter_list)] ( • <port_definitions_list>); • Example: My_module • module My_module • (input [7:0] A, • input [7:0] B, • input CLK, • inout [7:0] DATA, • output CE); • … • endmodule My_module A[7:0] 8 DATA[7:0] 8 B[7:0] 8 CE CLK This is a LIST of ports, end each element with , except the last one
input • Signal values can be ONLY READ, not written • output • Signal values can be both read and written (assigned), with the restriction: • A SIGNAL CAN BE ASSIGNED IN ONLY ONE PLACE, i.e. • One assign statement (if the signal is wire type), or • One always statement (if the signal is reg type) inout • Bidirectional signal (tri-state) • Although newer FPGA devices can have tristate buffers on-chip, it is recommended to be used only for connections outside the chip • Recommendations: • Use two different signals for reading and assigning input values • Use a separate control signal to control the direction of the inout signal Port directions
VHDL ENTITY Definition General Form • entity <name> is • generic (<generic_name> : <type> := <value>; • <other generics>... ); • port (<port_name> : <mode> <type>; • <other ports>…); • end [entity] <name>; • Example: My_module • entity My_module is • port ( A: in std_logic_vector (7 downto 0); • B: in std_logic_vector (7 downto 0); • CLK: in std_logic; • DATA: inout std_logic_vector (7 downto 0); • CE: out std_logic • ); • end My_module; My_module A[7:0] 8 DATA[7:0] 8 B[7:0] 8 CE CLK This is a LIST of port statements, end each element with ; except the last one VHDL: out ports can be written in only one place, but CAN NOT BE READ! An internal signal has to be declared and used to read the output port
wire • Can be assigned only in a concurrent statement (assign) • Cannot have initial value! • Example: • wire s = 0; • … • assign s = … //NOT ALLOWED! s is already constant (0) • Otherwise, the synthesizer would be forced to create a circuit like: • reg • Can be assigned only in a sequential statement (always) • Can have initial value • Example: • reg q = 0; //Allowed Signal and port modes
input • By default, considered as wire, cannot be assigned anyway • output, inout • If their type is not specified, by default are considered as wire • If needed to assign output ports in always statements, specify reg in port declaration • Example: • outputreg [7:0] Dout, • outputreg CE, • ... • From upper level hierarchy, output or inout ports are always seen as wire • Recommended design practice: • declare output ports as wire • Use an internal signal with _reg suffix and assign the output port to it • In this way, port declarations does not have to change, only internal code Port directions linked to modes
Hierarchical Connections: What port directions can be connected? • Case Study: Upper level to lower level or vice versa • Input to input: ALLOWED • Input to output or output to input: • NOT ALLOWED • Input is already driven fromoutside. Don’t try to drive it from inside! • Output to output: ALLOWED • The output has to be driven from inside • Bidirectional: Only to Bidirectional Top_module Module1 Din Din Dout 8 A 8 8 EN B EN CLK A Module2 Data Din Data 8 8 8 C EN CLK CLK
Hierarchical Connections: What port directions can be connected? • Case Study: At the same level • Input to input: • Allowed, but the connecting signal has to be driven! i.e. also connected to a source (output) • Input to output or output to input: • ALLOWED • Output to output: Not ALLOWED • Do not try to drive a signal by two different circuits! • Bidirectional: Only to Bidirectional Top_module Module1 Din Din Dout 8 A 8 8 EN B EN CLK A Module2 Data Din Data 8 8 8 C EN CLK CLK
Hierarchical Connections: Code example SSG Decoder: module Ssg_decoder #( parameter CLK_FREQ = 50000000, parameter REFRESH_RATE = 1000 ) ( input CLK, input RESET, input [15:0] DIN, output [3:0] AN, output [6:0] SSG ); //We have to define the internal signals wire CE; wire [3:0] AN_Int; wire [1:0] mux_addr; wire [3:0] mux_data; #(CLK_FREQ, REFRESH_RATE) #(CLK_FREQREFRESH_RATE) Ssg_decoder Ssg_decoder Freq_divider CLK CLK #(CLK_FREQ, DIV_RATE) CLK CE_div CE CE Shift_reg_walk_0 AN CLK AN RESET RESET AN RESET 4 4 4 AN_Int CE AN_Int Priority_decoder Din Dout 2 4 mux_addr mux_addr Din[3:0] 2 Mux_4X_4To1 I0 4 [7:4] Din Din mux_data I1 mux_data O Hex_to_ssg_encoder 4 SSG I2 16 16 4 SSG 4 [11:8] Din Dout A I3 7 7 4 [15:11] 7 4
Hierarchical Connections: Code example SSG Decoder: //connect now the internal modules //each module connection can be taken //from its definition: #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) Ssg_decoder Ssg_decoder Freq_divider CLK CLK #(CLK_FREQ, DIV_RATE) CLK CE_div CE module #( parameter parameter ) ( input output ); #( ) ( ); . . . . Freq_divider CLK_FREQ DIV_RATE CLK, CE_div CE Shift_reg_walk_0 AN CLK AN = 50000000, = 50000 RESET RESET AN RESET 4 4 4 AN_Int CE AN_Int Priority_decoder Din Dout 2 4 mux_addr mux_addr Din[3:0] 2 Mux_4X_4To1 I0 4 [7:4] Din Din mux_data I1 mux_data O Hex_to_ssg_encoder 4 SSG I2 16 16 4 SSG 4 [11:8] Din Dout A I3 7 7 4 [15:11] 7 4
Hierarchical Connections: Code example SSG Decoder: //connect now the internal modules //each module connection can be taken //from its definition: #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) Ssg_decoder Ssg_decoder Freq_divider CLK CLK #(CLK_FREQ, DIV_RATE) #(CLK_FREQ, DIV_RATE) CLK CE_div CE CE (CLK_FREQ), (REFRESH_RATE) My_Freq_divider_inst (CLK), (CE) Freq_divider #( . CLK_FREQ . DIV_RATE ) ( . CLK . CE_div ); Shift_reg_walk_0 AN CLK AN RESET RESET AN RESET 4 4 4 AN_Int CE AN_Int Priority_decoder Din Dout 2 4 mux_addr mux_addr Din[3:0] 2 Mux_4X_4To1 I0 • Remember: If the module has parameters to override, the instance name comes AFTER the parameter connections! • Check for the commas in the parameter and port list! 4 [7:4] Din Din mux_data I1 mux_data O Hex_to_ssg_encoder 4 SSG I2 16 16 4 SSG 4 [11:8] Din Dout A I3 7 7 4 [15:11] 7 4
Hierarchical Connections: Code example SSG Decoder: #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) Ssg_decoder Ssg_decoder Freq_divider #( . CLK_FREQ (CLK_FREQ), . DIV_RATE (REFRESH_RATE) ) My_Freq_divider_inst ( . CLK (CLK) . CE_div (CE) ); //OR, keeping the order of parameters and //ports, the shortened version does not have //to contain the formal (internal) //parameters and ports: Freq_divider #(CLK_FREQ, REFRESH_RATE) My_Freq_divider_inst (CLK, CE); Freq_divider CLK CLK #(CLK_FREQ, DIV_RATE) #(CLK_FREQ, DIV_RATE) CLK CE_div CE CE Shift_reg_walk_0 AN CLK AN RESET RESET AN RESET 4 4 4 AN_Int CE AN_Int Priority_decoder Din Dout 2 4 mux_addr mux_addr Din[3:0] 2 Mux_4X_4To1 I0 4 [7:4] Din Din mux_data I1 mux_data O Hex_to_ssg_encoder 4 SSG I2 16 16 4 SSG 4 //NOT RECOMMENDED FOR//LARGE COMPONENTS: REDUCES//CODE VISIBILITY DRASTICALLY [11:8] Din Dout A I3 7 7 4 [15:11] 7 4
Hierarchical Connections: Code example SSG Decoder: //In a similar manner: Shift_reg_walk_0 My_shift_reg_inst (.CLK (CLK), .RESET (RESET), .CE (CE), .AN (AN_Int) ); Priority_decoder My_decoder (.Din (AN_Int), .Dout (mux_addr)); Mux_4X_To1 My_mux_inst (.I0 (Din[3:0]), .I1 (Din[7:4]), .I2 (Din[11:8]) .I3 (Din[15:11]), .A (mux_data), .O (mux_addr) ); Hex_to_ssg_encoder My_encoder_inst (.Din (mux_data), .Dout (SSG) ); endmodule SSG Decoder: //In a similar manner: Shift_reg_walk_0 My_shift_reg_inst (.CLK (CLK), .RESET (RESET), .CE (CE), .AN (AN_Int) ); Priority_decoder My_decoder (.Din (AN_Int), .Dout (mux_addr)); Mux_4X_To1 My_mux_inst (.I0 (Din[3:0]), .I1 (Din[7:4]), .I2 (Din[11:8]), .I3 (Din[15:11]), .A (mux_data), .O (mux_addr) ); Hex_to_ssg_encoder My_encoder_inst (.Din (mux_data), .Dout (SSG) ); endmodule #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) Ssg_decoder Ssg_decoder Freq_divider CLK CLK #(CLK_FREQ, DIV_RATE) #(CLK_FREQ, DIV_RATE) CLK CE_div CE CE Shift_reg_walk_0 AN CLK AN RESET RESET AN RESET 4 4 4 AN_Int CE AN_Int Priority_decoder There are at least two errors in the code! Where? Din Dout 2 4 mux_addr mux_addr Din[3:0] 2 Mux_4X_4To1 I0 4 [7:4] Din Din mux_data I1 mux_data O Hex_to_ssg_encoder 4 SSG I2 16 16 4 SSG 4 [11:8] Din Dout A I3 7 7 4 [15:11] 7 4
Hierarchical Connections: Code example SSG Decoder: //Corrected version: Shift_reg_walk_0 My_shift_reg_inst (.CLK (CLK), .RESET (RESET), .CE (CE), .AN (AN_Int) ); Priority_decoder My_decoder (.Din (AN_Int), .Dout (mux_addr)); Mux_4X_To1 My_mux_inst (.I0 (Din[3:0]), .I1 (Din[7:4]), .I2 (Din[11:8]), .I3 (Din[15:11]), .A (mux_addr), .O (mux_data) ); Hex_to_ssg_encoder My_encoder_inst (.Din (mux_data), .Dout (SSG) ); endmodule #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) Ssg_decoder Ssg_decoder Freq_divider CLK CLK #(CLK_FREQ, DIV_RATE) #(CLK_FREQ, DIV_RATE) CLK CE_div CE CE Shift_reg_walk_0 AN CLK AN RESET RESET AN RESET 4 4 4 AN_Int CE AN_Int Priority_decoder Din Dout 2 4 mux_addr mux_addr Din[3:0] 2 Mux_4X_4To1 I0 4 [7:4] Din Din mux_data I1 mux_data O Hex_to_ssg_encoder 4 SSG I2 16 16 4 SSG 4 [11:8] Din Dout A I3 7 7 4 [15:11] 7 4
Hierarchical Connections Example in VHDL SSG Decoder: architecture my_arch of ssg_decoder is --internal signals signal CE: std_logic; signal AN_Int: std_logic_vector (3 downto 0); signal mux_addr: std_logic_vector (1 downto 0); signal mux_data: std_logic_vector (3 downto 0); --we have to declare each component --if not included in library component Freq_divider generic ( CLK_FREQ: integer := 50000000; DIV_RATE : integer := 1000 ); port (CLK : instd_logic; CE_div: outstd_logic ) endcomponent; … begin #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) Ssg_decoder Ssg_decoder Freq_divider CLK CLK #(CLK_FREQ, DIV_RATE) #(CLK_FREQ, DIV_RATE) CLK CE_div CE CE Shift_reg_walk_0 AN CLK AN RESET RESET AN RESET 4 4 4 AN_Int CE AN_Int Priority_decoder Din Dout 2 4 mux_addr mux_addr Din[3:0] 2 Mux_4X_4To1 I0 For component declaration the semicolon is present Every signal and component declaration is done between the architecture… begin statements 4 [7:4] Din Din mux_data I1 mux_data O Hex_to_ssg_encoder 4 SSG I2 16 16 4 SSG 4 [11:8] Din Dout A I3 7 7 4 [15:11] 7 4
Hierarchical Connections Example in VHDL SSG Decoder: … begin My_Freq_divider_inst: Freq_divider genericmap ( CLK_FREQ => CLK_FREQ, DIV_RATE => REFRESH_RATE ) portmap ( CLK => CLK, CE_div => CE ); -- other instantiations -- and statements … endarchitecture my_arch; #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) Ssg_decoder Ssg_decoder Freq_divider CLK CLK #(CLK_FREQ, DIV_RATE) #(CLK_FREQ, DIV_RATE) CLK CE_div CE CE Shift_reg_walk_0 AN CLK AN RESET RESET AN RESET 4 4 Component instantiations and statements are done between the begin… endarchitecture statements For component instantiation the semicolon is not present Generic map and port map statements are followed by a list of ports, separated by commas 4 AN_Int CE AN_Int Priority_decoder Din Dout 2 4 mux_addr mux_addr Din[3:0] 2 Mux_4X_4To1 I0 4 [7:4] Din Din mux_data I1 mux_data O Hex_to_ssg_encoder 4 SSG I2 16 16 4 SSG 4 [11:8] Din Dout A I3 7 7 4 [15:11] 7 4
Verilog for synthesis: What operators can we use? • Operators can be used in both assign and always statements • Logical bitwise operators: • &, |, ~, ^, ~^ • Operation applies to each bit of a signal • Therefore, apply operators to signals with the SAME WIDTH only • Otherwise, the signal with lower width will be left aligned (some synthesizers might align it to right) • Logical operators: • !, &&, ||, ==, !=, ===, <, >, <=, >=, !== • Used in conditions only. Same as in C, a condition is written always in () • What is === and !== ? • Signals are compared including X and Z • Note: X = don’t care, not undefined! • Applies to simulation only!
Verilog for synthesis: What operators can we use? • Operators can be used in both assign and always statements • Arithmetic operators: • +, -, *, /, %, ** • /, % and ** can be synthesized only if the second operand is 2 or power of 2! • Shift: • <<, >>, <<<, >>> • Shifted in values are 0 • <<< and >>> : shift and maintain sign bit • Unary reduction operators • &, ~&, |, ~|, ~, ^, ~^, • Concatenate and replicate • { }, {{}}
Verilog for synthesis: What operators can we use? • Unary reduction operators • Example: We have a N-bit wide signal named A. The width of A is determined by a parameter called SIGNAL_WIDTH. We have to make a logic AND between all of the bits of A into a signal called A_and. How can we do this? • Solution 1: • … • wire [SIGNAL_WIDTH-1:0] A; • reg A_and; • integer I; • always@ (A) • for (i=0; i<SIGNAL_WIDTH; i = i+1) • A_and <= A_and & A[i]; • Solution 2: • … • wire A_and; • assign A_and = &A; • Note: To test whether any of the bits of A is 1, one can use (|A)
Verilog for synthesis: What operators can we use? • Concatenate and replicate • Concatenate Examples: • 1. {a, b, c} – Concatenate a, b, c into a bus • The width of the resulting bus = width of a + width of b + width of c • Concatenate assignment is also positional! The leftmost bit of the resulting bus is the leftmost bit of a • 2. Assume the following code snippet: • wire [7:0] a; • wire [2:0] b; • wire [4:0] c; • wire [18:0] q; • assign q = {a[5:0], c[3:0], b, a[7:6], 1’b0, 2’b10, b[2]}; • What will be connected to q[17], q[7] and q[2]?
Verilog for synthesis: What operators can we use? • Concatenate and replicate • Replicate Examples: • We have a N-bit wide signal called A and a 1-bit wide signal called EN. The value of N is determined by the parameter SIGNAL_WIDTH. • The EN signal acts as an enable for the N-bit wide output signal A_out such as A_out = A if EN = 1, otherwise all of the bits of A are 0. How can we do this? • Solution 1: • assignA_out = (EN)? A:0; • //works only if A is less than 32-bit wide! Otherwise: N’h00…. • Solution 2: • assignA_out = A & {SIGNAL_WIDTH{EN}}; • 2. wire [19:0] q = {{2{4’hA}}, {4{3’b101}}}. Write down in hexadecimal the value of Q!
Verilog for synthesis: About indexes • One-dimension signals i.e. BUSES: • How to access a part of a bus? Example: • wire | reg [N:n] A; • N and n are POSITIVE INTEGER numbers • A[Upper:Lower] always represents the CONTINUOUS part of the bus having the width of Upper-Lower+1 • Assume Upper >= Lower, then ALWAYS Upper <=N, Lower >=n! • Otherwise the Verilog parser generates an error. Careful when using parameters or variables for indexing! • The synthesizer is able to determine if the index is out of the range [N:n]. Example: • reg [15:0] A; • … • for (i=0; i<=16; i++) A[i] <= … //will generate an error • For selecting non-continuous parts of A, use concatenation operators • A[i] ALWAYS represents a 1-bit wide signal. Obviously, n<=i<=N • A ALWAYS represents the WHOLE range of A, equivalent to A[N:n] • Note: A[N:N] is valid if A was defined in this way! • Example: parameter SIGNAL_WIDTH = 0; • reg [SIGNAL_WIDTH-1:0] A; //A will be defined as A[0:0]
Verilog for synthesis: About indexes • One-dimension signals i.e. BUSES: • How to access a part of a bus? Example: • wire | reg [N:n] A; • What about accessing part of A as A[Lower:Upper]? • Syntactically it is accepted but the synthesizer will generate an error • Use the endianness of signals in the way they wer defined! • RECCOMENDATION: use only one endianness in your code! (usually little) • If cannot avoid both little and big endian signals, in your code, Example: • wire [Lower:Upper] B = A [Upper:Lower];//B[Lower] = A[Upper]… • Two-dimension signals i.e. ARRAYS • Example: • reg [N:n] A [m:M]; //It can be also [M:m] • Used mostly for MEMORY structures: RAM, ROM, FIFO and multi-dimensional shift registers • ALWAYS THE SECOND INDEX COMES FIRST! • A[ i ], m<= i <=M ALWAYS represents a N-n+1-width signal i.e the i-th location of the memory or shift register
Verilog for synthesis: About indexes • Two-dimension signals i.e. ARRAYS • Example: • reg [N:n] A [m:M]; //It can be also [M:m] • A[ i ], m<=i<=M ALWAYS represents a N-n+1-width signal i.e the i-th location of the memory or shift register, equivalent to A [ i ] [N:n] • A[ i ][ j ], m<= i <=M, n <= i <= N ALWAYS represents bit j of location i • A[ i ][Upper:Lower] ALWAYS represents a part selector of the bus from location i • A [L1:U1] [U2:L2] is syntactically valid, but the synthesizer will generate an error • For example: • reg [7:0] Mem [0:255]; • … • always @ .. begin • Mem <= 0; //NOT ALLOWED. Mem is an array of 256X8! Not 32 bits • //and not even 2048 bits! • Mem [0:3] <= {32{1’b0}};//Also not allowed • Mem [3] <= 8’hFF;//Allowed • Mem [255] [7:4] <= 4’h8;//Allowed
Verilog for synthesis: About indexes • Multi-Dimension signals? • Example: • reg [N:n] A [m:M] [p:P]; //It can be also [m:M], [P:p] and so on • It will be visible as a three-dimensional memory • ALWAYS, THE SECOND INDEX COMES FIRST! • XST solves the three-dimensional array as a two-dimensional array of • (P-p+1) * (N-n+1) X (M-m+1) • The third index i.e. [p:P] represents a multiplier for the first index i.e. [N:n] • Therefore A[ i ] [ j ], m<= i <=M, p <= j <= P represents a N-n+1-width signal i.e the i-th location, bits [ (( j+1 ) * N) + j : (( j+1 ) * N ) + j – (N-n) ] of the memory, or shift register, equivalent to A [ i ] [ j ] [N:n] • A[ i ][ j ][ k ], m<= i <=M, p <= i <= P, n <= k <=N represents bit j*k of location i • A[ i ][ j ][Upper:Lower] represents a part selector [ (j * Upper: j * Lower] of the bus from location i • A [L1:U1] [U2:L2] is not accepted by the synthesizer, it will generate an error • Example: reg [7:0] Mem [0:255][0:3]; //will generate an array of 256 X 32-bit wide registers
VHDL: About indexes • One-dimension signals i.e. BUSES: • Example: • signal A: std_logic_vector (7 downto 0); • signal B, C: std_logic_vector (0 to 3); • Index can be also negative! • Part selectors: • Valid: • A (5 downto 4); B(0 to 2); A (5 downto 5); C(0 to 3); • Invalid, even syntactically is not accepted to change the endianness or using indexes larger than the range: • A (3 to 7); B(3 downto 0); C(0 downto 0); A(8), A(6 downto -1); • A is equivalent to A(7 downto 0), B to B(0 to 3) and so on • 1-bit value: enclosed in ‘ ‘, multiple-bit values: enclosed in “ “ • Hexadecimal prefix: X • Concatenation operator: &. Examples: • A <= C & B; -- A(7) <= C(0), A(6) <= C(1) and so on • A <= ‘0’ & B &”000”; • A<= X”FF”; • B <= C(0 to 2) & ‘1’;
VHDL: About indexes • Multi-dimension signals i.e. ARRAYS: • First, the type of array has to be defined. Example: • type my_mem2type isarray (0 to 7) ofstd_logic_vector ( 15 downto 0); • type my_mem3type isarray (0 to 3) of my_mem2type; • signal A: my_mem2type; • signal B: my_mem3type; • The first defined index comes first! • Part selectors: similar to Verilog • A(7); A(5) (5 downto 4); B(3) (7) (15); • Invalid: • A (3 to 7); B(2 to 3) etc.
Verilog for Synthesis: Behavioral description • Instead of instantiating components, describe them using behavioral description in a single module • Connect the various components using internal signals • Advantages: • Often allows for shorter description • A single module may be needed to describe a project consisting of various components • Easier to understand the behavior of the internal components • Disadvantages: • It might reduce code readability – Comments here are necesarry! • Can lead to large files i.e. hundredths of lines of code
Verilog for Synthesis: Behavioral description example SSG Decoder again: module Ssg_decoder #( parameter CLK_FREQ = 50000000, parameter REFRESH_RATE = 1000) (input CLK, input RESET, input [15:0] DIN, output [3:0] AN, output [6:0] SSG); //now we need more internal signals //to make the frequency divider wire CE; integer Freq_divider; //to make the shift register reg [3:0] AN_Int; //to make the multiplexer wire [3:0] mux_data; //mux_addr disappeard! The priority //decoder will be also made using behavioral // description //to make the Hex_to_ssg_decoder reg [6:0] SSG_Int; #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) Ssg_decoder Ssg_decoder Freq_divider CLK CLK #(CLK_FREQ, DIV_RATE) #(CLK_FREQ, DIV_RATE) CLK CE_div CE CE Shift_reg_walk_0 AN CLK AN RESET RESET AN RESET 4 4 4 AN_Int CE AN_Int Priority_decoder Din Dout 2 4 mux_addr mux_addr Din[3:0] 2 Mux_4X_4To1 I0 4 [7:4] Din Din mux_data I1 mux_data O Hex_to_ssg_encoder 4 SSG I2 16 16 4 SSG 4 [11:8] Din Dout A I3 7 7 4 [15:11] 7 4
Verilog for Synthesis: Behavioral description example SSG Decoder again: //describe the divider always @ (posedge CLK) if (Freq_divider == ((CLK_FREQUENCY_HZ/REFRESH_RATE) - 1 )) Freq_divider <=0; else Freq_divider <= Freq_divider + 1; //assign the divided signal assign CE = (CE_div == ((CLK_FREQUENCY_HZ/REFRESH_RATE) - 1 )) ? 1:0; //note: CE is one-shot signal! //describe the walking 0 shift register always @ (posedge CLK or posedge RESET) if (RESET) AN_Int<=4'hf; elseif (CE) if (AN_Int==4'b0111 || AN_Int==4'b0000 || AN_Int==4'b1111) AN_Int<=4'b1110; else AN_Int <= {AN_Int[2:0],1'b1}; //shift register #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) Ssg_decoder Ssg_decoder Freq_divider CLK CLK #(CLK_FREQ, DIV_RATE) #(CLK_FREQ, DIV_RATE) CLK CE_div CE CE Shift_reg_walk_0 AN CLK AN RESET RESET AN RESET 4 4 4 AN_Int CE AN_Int Priority_decoder Din Dout 2 4 mux_addr mux_addr Din[3:0] 2 Mux_4X_4To1 I0 4 [7:4] Din Din mux_data I1 mux_data O Hex_to_ssg_encoder 4 SSG I2 16 16 4 SSG 4 [11:8] Din Dout A I3 7 7 4 [15:11] 7 4
Verilog for Synthesis: Behavioral description example SSG Decoder again: //Priority encoder and multiplexer combined assign mux_data = (An_Int==4'b1110) ? DIN[3:0] : (An_Int==4'b1101) ? DIN[7:4] : (An_Int==4'b1011) ? DIN[11:8] : (An_Int==4'b0111) ? DIN[15:12] : 4'h0; #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) Ssg_decoder Ssg_decoder Freq_divider CLK CLK #(CLK_FREQ, DIV_RATE) #(CLK_FREQ, DIV_RATE) CLK CE_div CE CE Shift_reg_walk_0 AN CLK AN RESET RESET AN RESET 4 4 4 AN_Int CE AN_Int Priority_decoder Din Dout 2 4 mux_addr mux_addr Din[3:0] 2 Mux_4X_4To1 I0 4 [7:4] Din Din mux_data I1 mux_data O Hex_to_ssg_encoder 4 SSG I2 16 16 4 SSG 4 [11:8] Din Dout A I3 7 7 4 [15:11] 7 4
Verilog for Synthesis: Behavioral description example SSG Decoder again: //write the seven segment decoder always @ (mux_data) case (mux_data) 4'b0001: Ssg_Int=7'b1111001; //1 4'b0010: Ssg_Int=7'b0100100; //2 4'b0011: Ssg_Int=7'b0110000; //3 4'b0100: Ssg_Int=7'b0011001; //4 4'b0101: Ssg_Int=7'b0010010; //5 4'b0110: Ssg_Int=7'b0000010; //6 4'b0111: Ssg_Int=7'b1111000; //7 4'b1000: Ssg_Int=7'b0000000; //8 4'b1001: Ssg_Int=7'b0010000; //9 4'b1010: Ssg_Int=7'b0001000; //A 4'b1011: Ssg_Int=7'b0000011; //B 4'b1100: Ssg_Int=7'b1000110; //C 4'b1101: Ssg_Int=7'b0100001; //D 4'b1110: Ssg_Int=7'b0000110; //E 4'b1111: Ssg_Int=7'b0001110; //F default: Ssg_Int=7'b1000000; //0 endcase #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) #(CLK_FREQREFRESH_RATE) Ssg_decoder Ssg_decoder Freq_divider CLK CLK #(CLK_FREQ, DIV_RATE) #(CLK_FREQ, DIV_RATE) CLK CE_div CE CE Shift_reg_walk_0 AN CLK AN RESET RESET AN RESET 4 4 4 AN_Int CE AN_Int Priority_decoder Din Dout 2 4 mux_addr mux_addr Din[3:0] 2 Mux_4X_4To1 I0 4 [7:4] Din Din mux_data I1 mux_data O Hex_to_ssg_encoder 4 SSG I2 16 16 4 SSG 4 [11:8] Din Dout A I3 7 7 4 [15:11] 7 4