• 1

    ..

  • 2

    ...

  • 3

    ...

Showing posts with label Verilog codes. Show all posts
Showing posts with label Verilog codes. Show all posts

Thursday, 2 November 2017

conditional operator (?:) vs IF statement

Here is the simple code for comparing conditional operator and if statement.

Code:
module testing;
  reg foo;
  wire [3:0] c1,c2,c3;
  reg [3:0] a=1,b=3,cif1,cif2,cif3;
  
  assign c1 = foo ? a : b;  

  //equality
  assign c2 = (foo==1) ? a : b;

  //case equality
  assign c3 = (foo===1) ? a : b;
  
  always@(foo or a or b) begin 
    if (foo) 
      cif1 = a;
    else 
      cif1 = b;

    //equality
    if (foo==1) 
      cif2 = a;
    else 
      cif2 = b;
    //case equality
    if (foo===1) 
      cif3 = a;
    else 
      cif3 = b;
  end
  
  initial begin
    $monitor("@%3t :: foo=%b, a=%x, b=%x,   c1=%x, c2=%x, c3=%x,   cif1=%x ,cif2=%x ,cif3=%x", $realtime,foo,a,b,c1,c2,c3,cif1,cif2,cif3);
    #10 foo=1;
      #5 a=a+1;
    #10 foo=0;
      #5 b=b+1;
    #10 foo=1;
  end
  
endmodule

OUTPUT:
@  0 :: foo=x, a=1, b=3,   c1=X, c2=X, c3=3,   cif1=3 ,cif2=3 ,cif3=3  @ 10 :: foo=1, a=1, b=3,   c1=1, c2=1, c3=1,   cif1=1 ,cif2=1 ,cif3=1  @ 15 :: foo=1, a=2, b=3,   c1=2, c2=2, c3=2,   cif1=2 ,cif2=2 ,cif3=2  @ 25 :: foo=0, a=2, b=3,   c1=3, c2=3, c3=3,   cif1=3 ,cif2=3 ,cif3=3  @ 30 :: foo=0, a=2, b=4,   c1=4, c2=4, c3=4,   cif1=4 ,cif2=4 ,cif3=4  @ 40 :: foo=1, a=2, b=4,   c1=2, c2=2, c3=2,   cif1=2 ,cif2=2 ,cif3=2  

Based on the simulation, when the condition is X conditional operator outputs X whereas if statement outputs else part. Except this, moreover no difference in execution of these two.

Tuesday, 7 June 2016

VERILOG TIMESCALE - TIMEFORMAT - EXAMPLE

In this post, let us see the timescale feature and system tasks that are available in Verilog HDL with brief examples.

`timescale directive specifies the time unit and time precision of the modules that follow it. The time unit is the unit of measurement for time values such as the simulation time and delay values.
Syntax:   `timescale <time_unit>/<time_precision>
              The time_unit argument specifies the unit of measurement for times and delays.
The time_precision argument specifies how delay values are rounded before being used in simulation. The smallest time_precision argument of all the 'timescale compiler directives in the design determines the precision of the time unit of the simulation.

The time_precision argument shall be at least as precise as the time_unit argument; it cannot specify a longer unit of time than time_unit. The integers in these arguments specify an order of magnitude for the size of the value; the valid integers are 1, 10, and 100. The character strings "s, ms, us, ns, ps, and fs " represent units of measurement;

Example: `timescale 1ns/100ps
                Here in the above example, time_unit is 1ns & time_precision is 100ps. So the delay of #1 in the code is equivalent to 1ns delay in simulation. The delay of #1.56 will be rounded to 1.6ns. i.e. the decimal fraction will be rounded to in multiples of the time_precision value. Each #delay value is rounded to time delays w.r.t the timescale specified and added to the current simulation time.

Some of the system tasks on timescale are
·         $printtimescale() prints the timescale settings of the current scope of the file.
·         $timeformat(..,..,,,) system task

The $timeformat system task performs the following two operations:
Ø  It sets the time unit for all later-entered delays entered interactively.
Ø  It sets the time unit, precision number, suffix string, and minimum field width for all %t formats specified in all modules that follow in the source description until another $timeformat system task is invoked.

Syntax for $timeformat is
$timeformat ( units_number , precision_number , suffix_string , minimum_field_width ) ;

Example: $timeformat(-9,3,"ns",8);   This will display any %t string in ns with 3 digits precision, and 8 characters string size.

Let us see the code for the example used for different timescale settings & $timeformat system task.
initial begin
    $timeformat(-9,3,"ns",8);
    #1     $display("\n1) %t",$realtime); 
    #10.5  $display("\n2) %t",$realtime); 
    #10.56 $display("\n3) %t",$realtime);
    #10.56 $display("\n4) %t",$realtime);
    #11.46 $display("\n5) %t",$realtime);
 $finish;
end

The output of the above code with different timescale values are illustrated in the below table.
Timescale
`timescale 1ns/1ps
`timescale 1ns/10ps
`timescale 1ns/100ps
Output
1)  1.000ns
2) 11.500ns
3) 22.060ns
4) 32.620ns
5) 44.080ns
1)  1.000ns
2) 11.500ns
3) 22.060ns
4) 32.620ns
5) 44.080ns
1)  1.000ns
2) 11.500ns
3) 22.100ns
4) 32.700ns
5) 44.200ns





The calculation for timescale 1ns/100ps is as below:
1.       Step 1, time is 1ns
2.       Step 2, time is (1ns+10.5ns)=11.5ns
3.       Step 3, time is (11.5ns + 10.6ns) = 22.1ns
4.       Step 4, time is (22.1ns + 10.6ns) = 32.7ns
5.       Step 5, time is (32.7ns + 11.5ns) = 44.2ns

 Similarly you could calculate for different timescale values. If you've any queries, plz do comment it.


If you enjoyed this post plz let us know your views via comments.
This helps us to do much more better.
Thankyou.

Friday, 11 March 2016

Glitch Free Clock Gating - verilog good clock gating


   Clock gating is a popular technique used in many synchronous circuits for reducing dynamic power dissipation. This saves power by adding more logic to a circuit to the clock by disabling clock switching, so that the flip-flops in them do not have to switch states. As a result, the switching power consumption goes to zero, and only leakage currents are incurred.

   Clock gating logic can be added into a design in a variety of ways:
  1. Coded into the RTL code as enable conditions that can be automatically translated into clock gating logic by synthesis tools.
  2. Inserted into the design manually by the RTL designers (typically as module level clock gating) by instantiating library specific ICG (Integrated Clock Gating) cells to gate the clocks of specific modules or registers.
  3. Semi-automatically inserted into the RTL by automated clock gating tools. These tools either insert ICG cells into the RTL, or add enable conditions into the RTL code. These typically also offer sequential clock gating optimisations.
   Poor clock gating produces glitches in the output clock, making unwanted clock transitions which may lead to timing violations,etc., and increased power consumption.
   Here is an Verilog example illustrating the RTL code for clock gating & its issues.

The below code produces simple clock gating mechanism with an 2-input AND gate, with inputs as CLK & CLK_EN. But the greatest disadvantage is that it produces glitches in output as in the below waveform.
//BAD clock gating, can cause glitches in output
 assign clk_out1 = c_en && clk;

To overcome the glitches, a latching needs to be added to change the enable only when CLK is high/low. By this way, glitches are avoided & produces a good clock for the rest of the block. 
//GOOD clock gating & glitch free
 always @ (c_en or clk) begin
     if (!clk)
        en_out2 = c_en; // build latch
 end
 assign clk_out2 = en_out2 && clk;

Circuit synthesized for the above codes:
Verilog RTL - Clock gating- circuit :: ELecDude

Waveform for the above code:




If you enjoyed this post plz let us know your views via comments.
This helps us to do much more better.
Thankyou.


Friday, 6 March 2015

RTC VERILOG CODE - ELECDUDE

RTC VERILOG CODE - ELECDUDE



            A real-time clock (RTC) is a computer clock (most often in the form of an integrated circuit) that keeps track of the current time. Although the term often refers to the devices in personal computers, servers and embedded systems, RTCs are present in almost any electronic device which needs to keep accurate time. The term is used to avoid confusion with ordinary hardware clocks which are only signals that govern digital electronics, and do not count time in human units.
            Here we've designed an RTC module using Verilog which is very much similar to that of the RTC Chips, but it is a RTL design. This RTL   RTC module can be compiled into a FPGA or PLDs. This module takes up 1Hz clock & starts clocking once enabled. Note that it is a simple design which does not keep the time running when powered off.
            This module is divided into two parts namely, rtc and clock divider. The clock divider module receives the global FPGA clock (say 20MHz) and produces 1Hz clock for the rtc module, which keep track of time.



RTC Module definition:
module rtc(rstn,clk_1hz,enable,second,minute,hour);

 Input & output definition:
input rstn; //active low reset
input enable; //active high enable the clock to work
input clk_1hz; //1Hz clock input
output [5:0] second,minute,hour; //hexadecimal output

 Variable definition:
reg [5:0] s,m,h;
reg s60,m60;

 Output assignment:
assign second=s;
assign minute=m;
assign hour=h;

 Clock counting:
/**************    SECONDS    **************/
always @(negedge rstn or posedge clk_1hz) begin
if (rstn == 0) begin
            s = 0;
            s60=0;
 end
else
if(enable == 1) begin
            if (s == 60-1) begin
                         s = 0;
                         s60= ~s60;
              end
            else
                s = s + 1;
end
end


Clock divider block:
module clock_div(rstn,clkin,enable,clk_1hz);
...
...
parameter FREQ=20e+6; //20MHz input clock
parameter COUNT=FREQ/2;

assign clk_1hz=tc;

always @(negedge rstn or posedge clkin) begin
if (rstn == 0) begin
            i = 0;
            tc=0;  end
else
if(enable == 1) begin
  if (i == COUNT-1) begin
             i = 0;
             tc= ~tc;
  end
  else
             i = i + 1;
end
end
..
...

RTC top module:

module RTC_TOP(rstn,enable,clkin,second,minute,hour);
input rstn; //active low reset
input enable; //active high enable the clock to work
input clkin; //20MHz input clock
wire clk_1hz; //1Hz clock input
output [5:0] second,minute,hour; //hexadecimal output

#module_name    instant_name (ports);
clock_div CLOCK_DIV (rstn,clkin,enable,clk_1hz);
rtc RTC (rstn,clk_1hz,enable,second,minute,hour);

endmodule




The codes are self-explained.  If you've any doubts or need any clarifications, plz don't hesitate to ask us through comments or by mail (admin@elecdude.com).


We welcome your valuable comments and suggestion.
It helps us to do better in future.
Thank you.


Friday, 21 March 2014

VLSI - SYNCHRONOUS DUAL PORT RAM VERILOG VHDL CODE


    Here is the code for Dual Port RAM in Verilog & VHDL. This is designed as Dual port write only-read only type.
    The PortA is used for writing data alone to RAM while PortB is used for reading only.

    This will be helpful for image processing applications, where the Control Unit will provide data for Processing Unit.

Block Diagram:
clk         - Clock
addra   - P.A address (4 bit)
addrb   - P.B address(4 bit)
dina      - P.A input data (8 bit)
doutb  - P.A input data (8 bit)
ena     - Enable P.A operations
wea    - Enable P.A Write operation
enb     - Enable P.B operations
DUAL PORT RAM VERILOG CODE:
// // // // // // // // // // // // // // // // // // // // // // //
// Author: ElecDude
//         admin@elecdude.com      
//
// Copyright - 2014 - ElecDude
//
// DISCLAIMER:
//
// THIS SOURCE FILE MAY BE USED AND DISTRIBUTED WITHOUT       
// RESTRICTION PROVIDED THAT THIS COPYRIGHT STATEMENT IS NOT  
// REMOVED FROM THE FILE AND THAT ANY DERIVATIVE WORK CONTAINS
// THE ORIGINAL COPYRIGHT NOTICE AND THE ASSOCIATED DISCLAIMER.
// 
// This is provided without any express or implied warranties,
// including, but not limited to, the implied warranties of merchantability
// and fitnessfor a particular purpose. FOR EDUCATIONAL PURPOSE ONLY.
//
// // // // // // // // // // // // // // // // // // // // // // //
module dpram(dina, dinb,addra, addrb,ena, wrb_a, enb, wrb_b, clk,douta, doutb);
//Definitions
      parameter ADDR_WIDTH = 4; //memory size address width
      parameter DATA_WIDTH = 8; //data bus width
      parameter RAM_DEPTH = 1 << ADDR_WIDTH;
//Input & Output Ports
      input [DATA_WIDTH-1:0] dina, dinb;
      input [ADDR_WIDTH-1:0] addra, addrb;
      input ena, wrb_a, enb, wrb_b, clk;
      output reg [7:0] douta, doutb;
// Declare the mem variable
      reg [7:0] mem[0:RAM_DEPTH-1];
     
// Port A
always @ (posedge clk)  begin
if (ena && wrb_a)  begin
      mem[addra] <= dina;
      douta <= dina;
 end
else if(ena && (!wrb_a)) begin
      douta <= mem[addra];
 end
end
     
// Port B
always @ (posedge clk)  begin
if (enb && wrb_b) begin
      mem[addrb] <= dinb;
      doutb <= dinb;
 end
else if(enb && (!wrb_b)) begin
      doutb <= mem[addrb];
 end
end
     
endmodule


DUAL PORT RAM VHDL CODE:
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  
-- Author: ElecDude
--         admin@elecdude.com      
--
-- Copyright - 2014 - ElecDude
--
-- DISCLAIMER:
--
-- THIS SOURCE FILE MAY BE USED AND DISTRIBUTED WITHOUT       
-- RESTRICTION PROVIDED THAT THIS COPYRIGHT STATEMENT IS NOT  
-- REMOVED FROM THE FILE AND THAT ANY DERIVATIVE WORK CONTAINS
-- THE ORIGINAL COPYRIGHT NOTICE AND THE ASSOCIATED DISCLAIMER.
-- 
-- This is provided without any  express or implied warranties,
-- including, but not limited  to, the implied warranties of merchantability
-- and fitnessfor a particular purpose. FOR EDUCATIONAL PURPOSE ONLY.
--
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

ENTITY dpram is
      GENERIC
      (
            ADRESS_WIDTH: integer := 4;  
            DATA_WIDTH  : integer := 8
      );
      PORT
      (     clk   : in std_logic;
            ena,wea,enb : in std_logic;
            addra,addrb : in std_logic_vector(ADRESS_WIDTH-1 downto 0);
            dina  : in std_logic_vector(DATA_WIDTH-1 downto 0);
            doutb : out std_logic_vector(DATA_WIDTH-1 downto 0)
      );
END dpram;

ARCHITECTURE Behavioral OF dpram IS
constant RAM_SIZE :integer := 2**ADRESS_WIDTH;
TYPE mem_array IS ARRAY (0 TO RAM_SIZE-1) OF std_logic_vector(DATA_WIDTH-1 DOWNTO 0);
signal ram : mem_array;
begin
--conv_std_logic_vector(x,m)
process(clk)
begin
      IF(clk'EVENT AND clk='1') THEN
            IF(ena='1' AND wea='1') THEN
                  ram(conv_integer(addra)) <= dina;
            END IF;
      END IF;
end process;

process(clk)
begin
      IF(clk'EVENT AND clk='1') THEN
            IF(enb='1') THEN
                  doutb <= ram(conv_integer(addrb));
            END IF;
      END IF;
end process;

END Behavioral;



MODELSIM SIMULATION TRANSCRIPT
vlib work
vlog  +acc  "dpram.v"
#vcom +acc  "dpram2.vhd"
vsim -t 1ns  -novopt -lib work dpram
view wave
add wave *
add wave \
{sim:/dpram/mem }
view structure
view signals
run 10ns
force -freeze sim:/dpram/clk 1 15, 0 {65 ns} -r 100
force -freeze sim:/dpram/ena 0 0
force -freeze sim:/dpram/wrb_a 0 0
force -freeze sim:/dpram/wrb_b 0 0
force -freeze sim:/dpram/enb 0 0
force -freeze sim:/dpram/dina 00000000 0
force -freeze sim:/dpram/dinb 00000000 0
force -freeze sim:/dpram/addra 0000 0
force -freeze sim:/dpram/addrb 0000 0
run
force -freeze sim:/dpram/ena 1 0
force -freeze sim:/dpram/wrb_a 1 0
force -freeze sim:/dpram/addra 0000 0
force -freeze sim:/dpram/dina 00000001 0
run
force -freeze sim:/dpram/addra 0001 0
force -freeze sim:/dpram/dina 00000011 0
run
force -freeze sim:/dpram/addra 0010 0
force -freeze sim:/dpram/dina 00000111 0
run
force -freeze sim:/dpram/addra 0011 0
force -freeze sim:/dpram/dina 00001111 0
run
force -freeze sim:/dpram/addra 0100 0
force -freeze sim:/dpram/dina 00011111 0
run
force -freeze sim:/dpram/addra 0101 0
force -freeze sim:/dpram/dina 00011111 0
run
force -freeze sim:/dpram/addra 0110 0
force -freeze sim:/dpram/dina 0101011 0
run
force -freeze sim:/dpram/addra 0111 0
force -freeze sim:/dpram/dina 01110011 0
run
force -freeze sim:/dpram/addra 1000 0
force -freeze sim:/dpram/dina 00111111 0
run
force -freeze sim:/dpram/addra 1001 0
force -freeze sim:/dpram/dina 01111111 0
run
force -freeze sim:/dpram/ena 0 0
force -freeze sim:/dpram/wrb_a 0 0
run
force -freeze sim:/dpram/enb 1 0
force -freeze sim:/dpram/addrb 0000 0
run
force -freeze sim:/dpram/addrb 0010 0
run
force -freeze sim:/dpram/addrb 0100 0
run
force -freeze sim:/dpram/addrb 0110 0
run
force -freeze sim:/dpram/addrb 1000 0
run
force -freeze sim:/dpram/addrb 0010 0
run
force -freeze sim:/dpram/addrb 0110 0
run
force -freeze sim:/dpram/addrb 1000 0
run
force -freeze sim:/dpram/enb 0 0
run
run



SIMULATION WAVEFORM:


Click here to find more on Verilog  -    VHDL


 

Search Here...