CHPT 3
CHPT 3
CHPT 3
entity half_add is port (I1, I2 : in bit; O1, O2 : out bit); end half_add; architecture behave_ex of half_add is begin process (I1, I2) begin O1 <= I1 xor I2 after 10 ns; -- statement 1 O2 <= I1 and I2 after 10 ns; -- statement 2 end process; end behave_ex;
Verilog Behavioral Description module half_add (I1, I2, O1, O2); input I1, I2; output O1, O2; reg O1, O2; always @(I1, I2) begin #10 O1 = I1 ^ I2; // statement 1. #10 O2 = I1 & I2; // statement 2.
end endmodule
Signal Assignment statements inside a process where s1,s2 and t1 are signals. Signal: process(t1) begin st1: s1<=t1; st2:s2<= not s1; end process
Sequential Statements
These statements have to appear inside process in VHDL or inside always in Verilog. IF statement Formats: if (Boolean Expression) then statement 1; statement 2; ............... else statement a; statement b; end if;
Verilog IF formats if (Boolean Expression) begin statement 1; statement 2; end else begin statement a; statement b; .. end
Execution of IF as a latch
if (clk =1) then temp:= s1; end if // verilog
Execution of IF as ELSE-IF
if ( Boolean Expression1) then statement 1; statement 2;.. elseif ( Boolean Expression 2) then statement i; statement ii;.. else statement a; statement b;.. end if;
// Verilog
if (Boolean Expression 1) begin statement 1; statement 2; end else if ( Boolean Expression 2) begin statement i; statement ii; end else begin statement a; statement b; end
Implementing ELSE-IF
if ( signal 1=1) then temp := s1; else if ( signal 2 = 1) then temp := s2; else temp := s3; end if // verilog if (signal 1= =1) begin temp = s1; end else if ( signal 2= = 1) begin temp = s2; end else temp = s3;
architecture MUX_bh of MUX_if is begin process (SEL, A, B, Gbar) variable temp : std_logic;
begin
if Gbar = '0' then if SEL = '1' then temp := B; else temp := A; end if; Y <= temp; else Y <= 'Z'; end if; end process; end MUX_bh;
// Verilog
module mux2x1 (A, B, SEL, Gbar, Y); input A, B, SEL, Gbar; output Y; reg Y; always @ (SEL, A, B, Gbar) begin if (Gbar == 1) Y = 1'bz; else begin if (SEL) Y = B; else Y = A; end end endmodule
begin if (Gbar = '0') and (SEL = '1') then temp := B; elsif (Gbar = '0') and (SEL = '0')then temp := A; else temp := 'Z'; -- Z is high impedance. end if; Y <= temp; end process; end MUX_bh;
//Verilog
module MUXBH (A, B, SEL, Gbar, Y); input A, B, SEL, Gbar; output Y; reg Y; always @ (SEL, A, B, Gbar) begin if (Gbar == 0 & SEL == 1) begin Y = B; end else if (Gbar == 0 & SEL == 0) Y = A; else Y = 1'bz end endmodule
Variable assignment
Signal Assignment
Case Statement
The case statement is a sequential statement having the following format. VHDL case Format
case ( control-expression) is when test value or expression1=> statement1; when test value or expression1=> statement2; when test value or expression1=> statement3; when others => statement 4; end case;
Verilog case Format case( control- expression) test value1 : begin statement1: end; test value1 : begin statement1: end; test value1 : begin statement1: end; default: begin default statements end end case
VHDL case sel is when 00=> temp:=i1; when 01=> temp:=i2; when 10=> temp:=i3; when others=> temp:=i4; end case;
J 0 1 0 1
K 0 0 1 1
clk
q(next state) No change, next = current 1 0 Toggle(next state)= invert of(current state)
Simulation waveform
begin
if rising_edge (clk) then case JK is when "01" => temp1 := '0'; when "10" => temp1 := '1'; when "00" => temp1 := temp1; when "11" => temp1 := not temp1; end case; q <= temp1; temp2 := not temp1; qb <= temp2; end if; end process P1; end JK_BEH;
L
L L L L L x
011
100 101 110 111
100
101 110 111 000 hold
begin
if rising_edge (clk) then if clr = '0' then case temp is when "000" => temp := "001"; when "001" => temp := "010"; when "010" => temp := "011"; when "011" => temp := "100"; when "100" => temp := "101"; when "101" => temp := "110"; when "110" => temp := "111"; when "111" => temp := "000"; when others => temp := "000"; end case;
else
temp := "000"; end if; end if; q <= temp; end process ctr;
end ctr_case;
case (q)
3'd0 : q = 3'd1; 3'd1 : q = 3'd2; 3'd2 : q = 3'd3; 3'd3 : q = 3'd4; 3'd4 : q = 3'd5; 3'd5 : q = 3'd6; 3'd6 : q = 3'd7; 3'd7 : q = 3'd0; endcase end else q = 3'b000; end endmodule
default : Rout_addrs=4'd0;
endcase end endmodule
Loop Statement
Loop is a sequential statement that has to appear inside the process in VHDL or inside always or initial in Verilog. Used to repeat the execution of statements written inside its body. The number of repetitions is controlled by the range of an index parameter.
for<lower index value> <upper index value> <step> statement1; statement2; . end loop
VHDL
for i in 0 to 2 loop if temp( i ) =1 then result:=result+2**i; end if; end loop statement1; statement2;
Verilog
for( i=0;i<=2;i=i+1) begin if(temp[ i ]= =1) begin result= result+2**i; end end statement1; statement2;
While-Loop
General format of while-loop is: while (condition) statement1; statement2; ... end
VHDL
while(i<x) loop i:= i+1; z:=i + z; end loop;
Verilog
while (i<x) begin i=i+1; z= i + z; end
Verilog Repeat
repeat (32) begin
#100 i=i+1;
end
Verilog Forever
initial begin clk =1b0; forever #20 clk = ~ clk; end
if rising_edge (clk) then if (clr = '0') then result := 0; -- change binary to integer lop1 : for i in 0 to 3 loop if temp(i) = '1' then result := result + 2**i; end if; end loop; -- increment result to describe a counter result := result + 1;
-- change integer to binary for j in 0 to 3 loop if (result MOD 2 = 1) then temp (j) := '1'; else temp (j) := '0'; end if; -- integer division by 2 result := result/2; end loop; else temp := "0000"; end if; q <= temp; end if; end process ct; end CTR_LOP;
always @ (posedge clk) begin if (clr == 0) begin result = 0; //change binary to integer for (i = 0; i < 4; i = i + 1) begin if (q[i] == 1) result = result + 2**i; end result = result + 1;
for (j = 0; j < 4; j = j + 1) begin if (result %2 == 1) q[j] = 1; else q[j] = 0; result = result/2; end end else q = 4'b0000; end endmodule
if rising_edge (clk) then if (clr = '0') then result := 0; -- change binary to integer lo0p1 : for i in 0 to 3 loop if temp(i) = '1' then result := result + 2**i; end if; end loop; -- increment result to describe a counter result := result + 1;
-- change integer to binary loop2: for j in 0 to 3 loop exit loop2 when hold = 1; if (result MOD 2 = 1) then temp (j) := '1'; else temp (j) := '0'; end if; -- integer division by 2 result := result/2; end loop; q <= temp; end if; end process ct; end CTR_LOP;
always @ (posedge clk) begin if (clr == 0) begin result = 0; //change binary to integer for (i = 0; i <= 3; i = i + 1) begin if (q[i] == 1) result = result + 2**i; end result = result + 1;
for (j = 0; j < =3; j = j + 1) begin if ( hold == 1) j=4; // 4 is out of range, exit else begin if (result %2 == 1) q[j] = 1; else q[j] = 0; result = result/2; end end endmodule
begin y := 1; i := 0; while (i < N) loop i := i + 1; y := y * i; end loop; z <= y; end process; end factorl;
Booth Algorithm
Used to multiply two signed numbers. The function is to determine the beginning and end of a string of ones in the multiplier and perform multiplicand additionaccumulation at the end of the string or perform subtraction accumulation at the beginning of the string. For multiplication Z = multiplier (X) * multiplicand (Y) X = {( 2end1+1- 2begin1) + ( 2 end2+1 2begin2)+.} Z = {( 2end1+1 Y- 2begin1 Y) + ( 2 end2+1 Y 2begin2 Y)+.}
Step
Initial 1. i =0
X(i) E
Action
E
0
Z
00000000 1001 10010000 11001000
10
2. i = 1
11
11100100
3. i = 2
01
Add y
0111 01010100
0
00101010 1001 10111010 11011101
HDL Code library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity booth is port (X, Y : in signed (3 downto 0); Z : buffer signed (7 downto 0)); end booth; architecture booth_4 of booth is begin process (X, Y) variable temp : signed (1 downto 0); variable sum : signed (7 downto 0); variable E1 : unsigned (0 downto 0); variable Y1 : signed (3 downto 0); begin sum := "00000000"; E1 := "0"; for i in 0 to 3 loop temp := X(i) & E1(0); Y1 := - Y;
case temp is when "10" => sum (7 downto 4) := sum (7 downto 4) + Y1; when "01" => sum (7 downto 4) := sum (7 downto 4) + Y; when others => null; end case; sum := sum srl 1; --This is a logical --shift of one position to the right sum (7) := sum(6); --The above two statements perform arithmetic shift where --the sign of the number is preserved after the shift.
--If Y = 1000; then according to our code, --Y1 = 1000 (-8 not 8 because Y1 is 4 bits only). --The statement sum = -sum adjusts the answer. sum := - sum; end if; z <= sum; end process; end booth_4;
module booth (X, Y, Z); input signed [3:0] X, Y; output signed [7:0] Z; reg signed [7:0] Z; reg [1:0] temp; integer i; reg E1; reg [3:0] Y1; always @ (X, Y) begin Z = 8'd0; E1 = 1'd0; for (i = 0; i < 4; i = i + 1) begin temp = {X[i], E1};
//The above statement is catenation Y1 = - Y; //Y1 is the 2 complement of Y
Procedures (VHDL)
Procedure has two parts.
Procedure
Declaration
Body
name
Input &Types
E.g. procedure xyz( a,b : in signed ( 3 downto 0); Z : out signed ( 7 downto 0)) is
E.g. procedure exmple(signal a : in std_logic; signal y : out std_logic) is variable x: std_logic; begin x :=a; case x is ---------end case; y<=x; end exmple;
E.g. Process( d, clk) begin . exmple( d , z); .. end process; The input to the procedure a assumes the value of d. The output of the procedure y is passed to z. If a vector is an input of a procedure, it should not be constrained in length. procedure vect_constr ( X: in std_logic_vector ; Y: out std_logic_vector ) is
Tasks ( Verilog)
Implemented to execute specified routines repeatedly.
Tasks
Declaration
Body
name
Input
Output
The body of the task shows the relationship between the outputs and inputs. E.g. begin cc = aa ^ bb; end end task The body of the task cannot include always or initial.
E.g. .. always @ ( a,b) begin addr( c, d , a , b); end
HDL procedure haddr ( sh , ch : out std_logic ; ah, bh : in std_logic) is begin sh:= ah xor bh; ch:= ah and bh; end haddr; To call the procedure it has to be inside process.
haddr ( sum1 , c1 , y , cin );
Verilog task haddr output sh,ch; input ah,bh; begin sh = ah ^ bh; ch = ah & bh; end endtask To call task, it has to be inside always or initial.
haddr ( sum1 , c1, y , cin );
procedure Haddr(sh, ch : out std_logic; ah, bh : in std_logic) is begin sh := ah xor bh; ch := ah and bh; end Haddr;
begin
addfull : process (x, y, cin) variable sum1, c1, c2, tem1, tem2 : std_logic; begin Haddr (sum1, c1, y, cin); Haddr (tem1, c2, sum1, x); --The above two statements are calls to the procedure Haddr tem2 := c1 or c2; sum <= tem1; cout <= tem2; end process; end two_halfs;
task Haddr; //This task describes the half adder output sh, ch; input ah, bh; begin sh = ah ^ bh; ch = ah & bh; end endtask
endmodule
VHDL N-Bit Ripple Carry Adder Using Procedure library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity adder_ripple is generic (N : integer := 3); port (x, y : in std_logic_vector (N downto 0); cin : in std_logic; sum : out std_logic_vector (N downto 0); cout : out std_logic); end adder_ripple;
architecture adder of adder_ripple is procedure Faddr (sf, cof : out std_logic; af, bf, cinf : in std_logic) is begin sf := af xor bf xor cinf; cof := (af and bf) or (af and cinf) or (bf and cinf); end Faddr;
begin addrpl : process (x, y, cin) variable c1, c2, tem1, tem2 : std_logic; variable cint : std_logic_vector (N+1 downto 0); variable sum1 : std_logic_vector (N downto 0); begin cint(0) := cin; for i in 0 to N loop Faddr (sum1(i), cint(i+1), x(i), y(i), cint(i)); --The above statement is a call to the procedure Faddr end loop; sum <= sum1; cout <= cint(N+1);
end process;
end adder;
Verilog N-Bit Ripple Carry Adder Using Task module adder_ripple (x, y, cin, sum, cout); parameter N = 3; input [N:0] x, y; input cin; output [N:0] sum; output cout; reg [N+1:0] cint; reg [N:0] sum; reg cout; integer i; always @ (x, y, cin) begin cint[0] = cin; for (i = 0; i <= N; i = i + 1) begin Faddr (sum[i], cint[i+1], x[i], y[i], cint[i]);
cout = cint[N+1]; end task Faddr; //The task describes a full adder output sf, cof; input af, bf, cinf; begin
sf = af ^ bf ^ cinf; cof = (af & bf) | (af & cinf) | (bf & cinf); end endtask
endmodule
VHDL: Converting an Unsigned Binary to an Integer Using Procedure library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; --This Library is for type unsigned
entity Bin_Int is generic (N : natural := 3); port (X_bin : unsigned (N downto 0); Y_int : out natural; Z : out std_logic); --Y is always positive end Bin_Int;
architecture convert of Bin_Int is procedure bti (bin : in unsigned; int : out natural; signal Z : out std_logic) is
--binRange represents the range of the unsigned vector bin --Range is a predefined attribute if bin(i) = '1' then result := result + 2**i; end if; end loop; int := result; if (result = 0) then Z <= '1'; else Z <= '0'; end if; end bti;
begin process (X_bin) variable tem : natural; begin bti (X_bin, tem, Z); Y_int <= tem; end process; end convert;
Verilog: Converting an Unsigned Binary to an Integer Using Task module Bin_Int (X_bin, Y_int, Z); parameter N = 3; input [N:0] X_bin; output integer Y_int; output Z; reg Z; always @ (X_bin) begin bti (Y_int, Z, N, X_bin); end task bti; parameter P = N; output integer int; output Z; input N; input [P:0] bin; integer i, result;
begin
int = 0; //change binary to integer for (i = 0; i <= P; i = i + 1) begin if (bin[i] == 1) int = int + 2**i; end if (int == 0) Z = 1'b1; else Z = 1'b0; end endtask
endmodule
begin if (int MOD 2 = 0) then flag <= '1'; else flag <= '0'; end if;
for i in 0 to N loop if (int MOD 2 = 1) then bin (i) := '1'; else bin (i) := '0'; end if;
int := int/2; end loop; end itb; begin process (Y_int) variable tem : std_logic_vector (N downto 0); variable tem_int : integer ; begin tem_int := Y_int; itb (tem, flag_even, N, tem_int); X_bin <= tem; end process; end convert;
Unsigned integer to binary conversion module Int_Bin (X_bin, flag_even, Y_int ); parameter N = 3; output [N:0] X_bin; output flag_even; input [N:0] Y_int; reg [N:0] X_bin; reg flag_even; always @ (Y_int) begin itb (Y_int, N, X_bin, flag_even); end
task itb; parameter P = N; input integer int; input N; output [P:0] bin; output flag; integer j; begin
if (int %2 == 0) flag = 1'b1; else flag = 1'b0;
for (j = 0; j <= P; j = j + 1) begin if (int %2 == 1) bin[j] = 1; else bin[j] = 0; int = int/2; end end endtask endmodule
Simulation Output
if (parity mod 2 = 1) then even <= '0'; else even <= '1'; end if; end sbti; begin process (X_bin) variable tem : integer;
//change binary to integer for (i = 0; i <= P; i = i + 1) begin if (bin[i] == 1) begin int = int + 2**i; parity = parity + 1; end end
Functions
Functions are behavioral statements and must be called inside process (VHDL) or always or initial (Verilog). Functions take one or more inputs, and in contrast to procedure or task return only a single output value. function exp( a,b: in std_logic) return std_logic is
Verilog Functions
function exp; input a,b; Eg: module func_exm(a1,b1,d1); input a1,b1; output d1; reg d1; always@(a1,b1) begin d1= exp(a1,b1); end
Verilog Functions
function exp; input a,b; begin exp = a^b; end end function end module
File Processing
Files are valuable HDL description tools that can be used when dealing with a large amount of data that needs to be stored and accessed.
File_open This procedure opens the files. Procedure file_open(status: file_open_status, infile: file type, external_name:in string, open_kind: file_open_kind) is Status enables to keep track of the activities ( e.g., open, close, read) Infile for input files. Outfile for output files. External_name is the name of the file to be opened. file_open( fstatus,infile,testfile.txt,read_mode); file_open(fstatus, outfile,store.txt,write_mode);
File_close(outfile);
Readline Reads a line from the file opened in read mode. readline( infile, temp) Writeline writes a line into a an outfile that is open for write mode. writeline(outfile, temp);
Read Is a procedure to read an integer, a character or a real value from a line in an infile that is open for read mode.
Verilog File Processing $Fopen: Used to open files. Channel=$fopen(name of the file); Channel is a variable of type integer which indicates the channel number. ch1=$fopen(testfile.txt); $Fclose Closes a file indicated by the channel number. $fclose(ch1);
Verilog File Processing $Fdisplay: counterpart of write in VHDL. can write variables,signals or quoted strings. $fdisplay(channel,V1,V2,V3); $fdisplay(ch1,item description quantity); $Fmonitor $fmonitor(channel, V1,V2,V3); monitors and records the values of V1,V2,V3 $fmonitor(ch1, %b, quantity);
Different formats. %d Display in decimal %s Display Strings %h Display in hex %o Display in octal %c Display ASCII %f Display real numbers in decimal format.
Reading a File consisting of integer numbers entity FREAD_INTG is port (START : in std_logic; z, z1, z2, z3 : out integer); end FREAD_INTG; architecture FILE_BEHAVIOR of FREAD_INTG is begin process (START) -- declare the infile as a text file file infile : text;
-- Read the first integer (12) from the line temp and store it --in the integer variable count. read (temp, count); --count has the value of 12. Multiply by 2 and store in z z <= 2 * count; -- Read the second integer from the line temp and -- store it in count read (temp, count); --count now has the value of -3
--Multiply by 5 and store in z1 z1 <= 5 * count;
-- read the third integer in line temp and store it in count read (temp, count);
--Multiply by 3 and store in z2 z2 <= 3 * count; --Read the second line and store it in temp readline (infile, temp); --temp has only the second line --Read the first integer of the second line and store it in count read (temp, count);
end FILE_BEHAVIOR;
entity FREAD_REAL is port (START : in std_logic; z, z1, z2, z3 : out real); end FREAD_REAL;
--Read one number and store it in real variable count read (temp, count); --multiply by 2 z <= 2.0 * count;
--read another number read (temp, count); --multiply by 5 z1 <= 5.0 * count; --read another number read (temp, count); --multiply by 3 z2 <= 3.0 * count
--read another line readline (infile, temp); read (temp, count); --multiply by 4 z3 <= 4.0 * count; file_close (infile); end process;
end FILE_BEHAVIOR;
-- Variable count has to be of type character variable temp : line; begin file_open (fstatus, infile, "file_chr.txt", read_mode);
--read a line from the file readline (infile, temp); --read a character from the line into count. Count has to be of --type character read (temp, count);
--store the character in z z <= count; read (temp, count); z1 <= count; read (temp, count); z2 <= count; readline (infile, temp); read (temp, count); z3 <= count; file_close (infile); end process;
end FILE_BEHAVIOR;
begin
file_open (fstatus, outfile, "Wfile_int.txt", write_mode); --The generated file "Wfile_int.txt" is in --the same directory as this VHDL module --Insert the title of the file Wfile_int.txt. --Your simulator should support formatted text; --if not, remove all formatted statements . write (temp, "This is an integer file"); --Write the line temp into the file writeline (outfile, temp); -store the first integer in line temp write (temp, z);
-- leave space between the integer numbers. write (temp, " "); write (temp, z1); -- leave another space between the integer numbers. write (temp, " "); write (temp, z2); write (temp, " ");
writeline (outfile, temp); --Insert the fourth integer value on a new line write (temp, z3); writeline (outfile, temp);
file_close(outfile);
end process; end FILE_BEHAVIOR;
VHDL Code for Reading a String of Characters into an Array entity FILE_CHARCTR is port (START : in std_logic; z : out string_chr);
--string_char is included in the package array_pkg; --Z is a 5-character array end FILE_CHARCTR;
architecture FILE_BEHAVIOR of FILE_CHARCTR is begin process (START) file infile : text; variable fstatus : file_open_status; variable count : string_chr; variable temp : line
begin file_open (fstatus, infile, "myfile1.txt", read_mode); readline (infile, temp); read (temp, count); --Variable count has been declared as an array of five elements, --each element is a single character z <= count;
file_close (infile); end process; end FILE_BEHAVIOR;
Synthesis Basics
entity system4 is port(a,b: in signed(3 downto 0); d: out std_logic_vector(7 downto 0)); end system4;
entity system7 is Generic (N: integer:= 4; M: integer:=3); port(a,b: in std_logic_vector(N downto 0); d: out std_logic_vector( M downto 0)); end system7;
package code is type op is(add, mul, divide, none); end; use work.codes;
entity alus2 is port( a,b: in std_logic_vecotr( 3 downto 0); cin: in std_logic; opc: in op; z: out std_logic_vector ( 7 downto 0); cout : out std_logic; err: out boolean); end alus2;
Entity array1 is generic (N: integer := 4; M:integer := 3;); port (a: in strng; z: out std_logic_vector ( M downto 0)); end array1;
entity weather_frcst is port( day_ in: in weekdays; out_temperature: out integer range -100 to 100; out_day: out weekdays; out_cond: out cast); end weather_frcst;
module SIGNA_ASSN (X, Y); input X; output Y; reg y; always @ (X) begin Y = X; end endmodule
module sign_assn2 (X, Y); input [1:0] X; output [3:0] Y; reg [3:0] Y; always @ (X) begin Y = 2 * X + 3; end endmodule
Y(0) = 1;
Y(1) =X(0) Y(2)=X(1)X(0)+X(1)X(0) Y(3)=X(1) X(0)
Verilog Casex
module Encoder_4 (IR, RA); input [3:0] IR; output [3:0] RA; reg [3:0] RA; always @ (IR) begin casex (IR) 4'bxxx1 : RA = 4'd1; 4'bxx10 : RA = 4'd2; 4'bx100 : RA = 4'd4; 4'b1000 : RA = 4'd8; default : RA = 4'd0; endcase end endmodule
result := 0; lop1 : for i in 0 to 3 loop if a(i) = '1' then result := result + 2**i; end if; end loop; if result > c then lop2 : for i in 0 to 3 loop j := (i + 2) mod 4; temp (j) := a(i); else
lop3 : for i in 0 to 3 loop j := (i + 1) mod 4; temp (j) := a(i); end loop; end if; b <= temp; end process shfl; end listing10_32;