2020年4月23日 星期四

4-bit 3 to 1 multiplexer with priority

4-bit 3 to 1 multiplexer with priority

//---------------------------------------
//4-bit 3 to 1 multiplexer with priority
//---------------------------------------
module MUX_3x1_Priority(y, sel, a, b, c);

input [2:0] sel;
input [3:0] a, b, c;
output reg [3:0] y;

always @ (sel or a or b or c)
 begin
  casez (sel)
   3'bzz1 : y=a;
   3'bz10 : y=b;
   3'b100 : y=c;
   default : y=4'bzzzz;
  endcase
 end
endmodule

// 時間單位 1ns, 時間精確度10 ps
`timescale 10ns/10ps 
module TB;
/*
module MUX_3x1_Priority(y, sel, a, b, c);
input [2:0] sel;
input [3:0] a, b, c;
output reg [3:0] y;
*/

// Inputs
    reg [2:0] sel;
    reg [3:0] a;
    reg [3:0] b;
    reg [3:0] c;


// Outputs
    wire [3:0] y;

// Instantiate the UUT
MUX_3x1_Priority UUT (.y(y), .sel(sel), .a(a), .b(b), .c(c));


 
// Montoring signals
initial $monitor($time, "y=%h, sel=%b, a=%h, b=%h, c=%h", y, sel, a, b, c);

// Initialize Inputs
initial begin
  sel = 3'b000;
  a = 4'b0000;
  b = 4'b1010;
  c = 4'b1111;
end  

always
  #10 sel = sel + 3'h1;

 initial #80 $finish; //Complete simulation after 160 units

endmodule



Common-cathod seven segment display in Verilog

Common-cathod seven segment display in Verilog





//-----------------------------------------
//Common-cathod seven segment display
//using case.....endcase statement
//----------------------------------------- 
module seven_7segDisplay_CA(hex,seg);

input [3:0] hex;
output reg [7:0] seg;

// segment encoding
//      0
//     ---  
//  5 |   | 1
//     ---   <- 6
//  4 |   | 2
//     ---
//      3

always @(hex)
begin
   case (hex)
       // Dot point is always disable
       4'b0001 : seg = 8'b11111001;   //1 = F9H
       4'b0010 : seg = 8'b10100100;   //2 = A4H
       4'b0011 : seg = 8'b10110000;   //3 = B0H
       4'b0100 : seg = 8'b10011001;   //4 = 99H
       4'b0101 : seg = 8'b10010010;   //5 = 92H
       4'b0110 : seg = 8'b10000010;   //6 = 82H
       4'b0111 : seg = 8'b11111000;   //7 = F8H
       4'b1000 : seg = 8'b10000000;   //8 = 80H
       4'b1001 : seg = 8'b10010000;   //9 = 90H
       4'b1010 : seg = 8'b10001000;   //A = 88H
       4'b1011 : seg = 8'b10000011;   //b = 83H
       4'b1100 : seg = 8'b11000110;   //C = C6H
       4'b1101 : seg = 8'b10100001;   //d = A1H
       4'b1110 : seg = 8'b10000110;   //E = 86H
       4'b1111 : seg = 8'b10001110;   //F = 8EH
       default : seg = 8'b11000000;   //0 = C0H
    endcase
end

endmodule

// 時間單位 1ns, 時間精確度10 ps
`timescale 10ns/10ps 
module TB;
/*
module seven_7segDisplay_CA(hex,seg);
input [3:0] hex;
output reg [7:0] seg;
*/

// Inputs
    reg [3:0] hex;

// Outputs
    wire [7:0] seg;

// Instantiate the UUT
seven_7segDisplay_CA UUT (
        .hex(hex), 
        .seg(seg) );

// Initialize Inputs

initial $monitor($time, "seg = %h,  hex = %h", seg, hex);
// Initialize Inputs
initial begin
  hex = 4'h00;
end  

always
  #10 hex = hex + 4'h01;

 initial #160 $finish; //Complete simulation after 160 units

endmodule





4 to 1 multiplexer using case in Verilog

4 to 1 multiplexer using case in Verilog


//--------------------------------------------------
//4 to 1 multiplexer using case....endcase statement
//--------------------------------------------------
module MUX_4x1( s,i, y);

input [1:0] s;   //Selection signal
input [3:0] i;   //4-bit input
output reg y;

always @(s or i)
begin
   case (s)
      2'b00 : y = i[0];
      2'b01 : y = i[1];
      2'b10 : y = i[2];
      2'b11 : y = i[3];
      default : y = 1'b0;
   endcase
end
endmodule

// 時間單位 1ns, 時間精確度10 ps
`timescale 10ns/10ps 
module TB;
/*
module MUX_4x1( s,i, y);
input [1:0] s;   //Selection signal
input [3:0] i;   //4-bit input
output reg y;
*/

// Inputs
    reg [1:0] s;
    reg [3:0] i;

// Outputs
    wire y;

// Instantiate the UUT
 MUX_4x1 UUT( 
        .y(y), 
        .s(s), 
        .i(i)  );

// Initialize Inputs
initial
 $monitor ($time,"y=%b, s=%b, i=%b", y, s, i);

initial //Initialize input signals
 begin
    s = 2'b00;
    i = 4'b0101;
 end

initial 
 begin
   #20  s = 2'b01;   //Set selection at different times
   #20  s = 2'b10;
   #20  s = 2'b11;
 end

initial #100 $finish;  //Complete simulation after 120 time units
  
endmodule

1 to 4 Demultiplexer in Verilog

1 to 4 Demultiplexer  in Verilog





//---------------------------------------------------------
//1 to 4 Demultiplexer using nesting if...else..statement
//---------------------------------------------------------
module DeMux_1x4(I, S0, S1 ,y );

input I;
input S0, S1;     //Selection signals
output reg [3:0] y;

always @ (I or S0 or S1)
  begin
    if (S1==1'b0)
      begin
    if (S0==1'b0)
           y = {3'b000, I};    //marge 000 with I to y
        else
           y = {2'b00, I, 1'b0};
  end
    else
      begin 
    if (S0==1'b0)
           y = {1'b0, I, 2'b00};
        else
           y = {I, 3'b000};
  end
  end

endmodule

// 時間單位 1ns, 時間精確度10 ps
`timescale 10ns/10ps 
module TB;
/*
module DeMux_1x4(I, S0, S1 ,y );
input I;
input S0, S1;     //Selection signals
output reg [3:0] y;
*/

// Inputs
    reg I;
    reg S0;
    reg S1;

// Outputs
    wire [3:0] y;

// Instantiate the UUT
DeMux_1x4 UUT (
        .y(y), 
        .I(I), 
        .S0(S0), 
        .S1(S1));

initial $monitor($time, "y = %b,  I = %b,  S0 = %b,  S1 = %b", y, I, S0, S1);
// Initialize Inputs
integer i,j;

initial begin
for (i=0;i<=3;i=i+1) begin
{S1,S0}=i;

for (j=0;j<=1;j=j+1) begin
I=j;
#20;
end
end
#20 
$stop;
end  
endmodule

4x1 MUX in Verilog

4x1 MUX in Verilog
//-------------------------------------------------------
//4-bit multiplexer with if...else if...else if...else...
//-------------------------------------------------------
module MUX_4x1(s, i ,y);

input [1:0] s;   //Select line
input [3:0] i;    //Input data
output reg y;

always @ (s or i)
  begin
    if (s==2'b00)
      y = i[0];
    else if (s==2'b01)
      y = i[1];
    else if (s==2'b10)
      y = i[2];
    else
      y = i[3];
  end

endmodule

// 時間單位 1ns, 時間精確度10 ps
`timescale 10ns/10ps 
module TB;
/*
module mul4_1_if(s, i ,y);
input [1:0] s;   //Select line
input [3:0] i;    //Input data
output reg y;
*/

// Inputs
    reg [1:0] s;
    reg [3:0] i;

// Outputs
    wire y;

// Instantiate the UUT
 MUX_4x1 UUT( 
        .y(y), 
        .s(s), 
        .i(i)  );

// Initialize Inputs
initial
 $monitor ($time,"y=%b, s=%b, i=%b", y, s, i);

initial //Initialize input signals
 begin
    s = 2'b00;
    i = 4'b0101;
 end

initial 
 begin
   #20  s = 2'b01;   //Set selection at different times
   #20  s = 2'b10;
   #20  s = 2'b11;
 end

initial #100 $finish;  //Complete simulation after 120 time units
  
endmodule




2020年4月22日 星期三

4-bit Magnitude Comparator in Verilog

4-bit Magnitude Comparator   in  Verilog





//-----------------------------------------
// 4-bit Comparator  
// (if...else if...else)
//-----------------------------------------
module Comparator( a, b , eq, gt, lt);

// Port Declarations
input [3:0] a, b; //4-bit inputs
output reg eq, gt, lt;  //outputs eq:Equal, gt:Great than, lt:Less than

always @ (a or b)
 begin
   if (a==b)
    begin
     eq = 1'b1; gt = 1'b0; lt = 1'b0;
    end
  else if (a > b)
    begin
     eq = 1'b0; gt = 1'b1; lt = 1'b0;
    end
  else
    begin
     eq = 1'b0; gt = 1'b0; lt = 1'b1;
    end
 end
endmodule

4-bit 2 to 1 multiplexer in Verilog

4-bit 2 to 1 multiplexer in Verilog



//--------------------------------
//4-bit 2 to 1 multiplexer
//--------------------------------
module Mux2x1_4bit( s, a, b, y);

input s;           //Select signal
input [3:0] a, b;  //Input data

output reg [3:0] y;


always @ (s or a or b)
 if (s)
   y = b;
 else
   y = a;

endmodule


// 時間單位 1ns, 時間精確度10 ps
`timescale 10ns/10ps 
module TB;
/*
module Mux2x1_4bit( s, a, b, y);
input s;           //Select signal
input [3:0] a, b;  //Input data
output reg [3:0] y;
*/
// Inputs
    reg s;
    reg [3:0] a;
    reg [3:0] b;

// Outputs
    wire [3:0] y;

// Instantiate the UUT
Mux2x1_4bit UUT (
        .y(y), 
        .s(s), 
        .a(a), 
        .b(b)
        );

// Initialize Inputs

integer i;
initial begin
    b = 4'b1010; s=1'b0;
    for (i=0; i<16; i=i+1) begin
          a = i;
         #35;
    end
    a = 4'b0101; s=1'b1;
    for (i=0; i<16; i=i+1) begin
          b = i;
         #35;
    end
        
    
    #25
     $stop;
end
endmodule



4-bit latch in Verilog

4-bit latch  in Verilog




//------------------------------------
//4-bit latch using if... statement
//------------------------------------
module Latch_4bit(load, din , y);

input load;     //latch signal
input [3:0] din;

output reg [3:0] y;

always @ (din or load)
 begin
  if (load)
    y = din;
 end
endmodule


// 時間單位 1ns, 時間精確度10 ps
`timescale 10ns/10ps 
module TB;
/*
module Latch_4bit(load, din , y);
input load;     //latch signal
input [3:0] din;
output reg [3:0] y;
*/
// Inputs
    reg load;
    reg [3:0]din=4'b0000;

// Outputs
    wire [3:0] y;

// Instantiate the UUT
Latch_4bit UUT (load, din , y);
integer i;
initial begin
    for (i=0; i<32; i=i+1) begin
          {load,din} = i;
         #35;
    end
    #25
     $stop;
end


endmodule


Non-blocking Procedural Assignment in Verilog

Non-blocking Procedural Assignment in Verilog


//--------------------------------------------------
//4-bit register for Non-blocking Procedural Assignment
//--------------------------------------------------
module Nonblocking( CLK, RESET, Din,Qout);
input CLK, RESET;
input Din;
output reg [3:0] Qout;

always @ (posedge CLK or posedge RESET)
//Positive edge CLK and asynchronous RESET
 if (RESET)
   Qout <= 4'b0000;
 else
  begin
   Qout[0] <= Din;
   Qout[1] <= Qout[0];
   Qout[2] <= Qout[1];
   Qout[3] <= Qout[2];
  end
endmodule

//======================================
// 時間單位 1ns, 時間精確度10 ps
`timescale 10ns/10ps 
module TB;
/*
module Nonblocking( CLK, RESET, Din,Qout);
input CLK, RESET;
input Din;
output reg [3:0] Qout;
*/

// Inputs
    reg CLK;
    reg RESET;
    reg Din;


// Outputs
    wire [3:0] Qout;


// Instantiate the UUT
Nonblocking UUT (
        .Qout(Qout), 
        .CLK(CLK), 
        .RESET(RESET), 
        .Din(Din)
        );

initial
 $monitor ($time, "Data in=%b,  CLK=%b,  RESET=%b, Qout=%b", Din, CLK, RESET, Qout);

initial //Initialize input signals
 begin
    CLK = 0;
    RESET = 1;
    Din = 0;
 end

initial 
 begin
   #35  RESET=0;          //Disable RESET at 35 ns
   #50  Din = 1;             //Set Din at different times
   #100 Din = 0;
   #75  Din = 1;
 end

always #10 CLK=~CLK;     //Set clock with a period 20 ns

initial #300 $finish;        //Complete simulation after 400 ns
  
endmodule


Blocking Procedural Assignment in Verilog

Blocking Procedural Assignment in Verilog

//--------------------------------------------------
//4-bit register for Blocking Procedural Assignment
//--------------------------------------------------
module Blocking( CLK, RESET, Din,Qout);

input CLK, RESET;
input Din;

output reg [3:0] Qout;

always @ (posedge CLK or posedge RESET)
//Positive edge CLK and asynchronous RESET
 if (RESET)
   Qout = 4'b0000;
 else
  begin
   Qout[0] = Din;
   Qout[1] = Qout[0];
   Qout[2] = Qout[1];
   Qout[3] = Qout[2];
  end
endmodule


// 時間單位 1ns, 時間精確度10 ps
`timescale 10ns/10ps 
module TB;
/*
module Blocking( CLK, RESET, Din,Qout);
input CLK, RESET;
input Din;
*/

// Inputs
    reg CLK;
    reg RESET;
    reg Din;


// Outputs
    wire [3:0] Qout;


// Instantiate the UUT
    Blocking UUT (
        .Qout(Qout), 
        .CLK(CLK), 
        .RESET(RESET), 
        .Din(Din)
        );

initial
 $monitor ($time, "Data in=%b,  CLK=%b,  RESET=%b, Qout=%b", Din, CLK, RESET, Qout);

initial //Initialize input signals
 begin
    CLK = 0;
    RESET = 1;
    Din = 0;
 end

initial 
 begin
   #35  RESET=0;          //Disable RESET at 35 ns
   #50  Din = 1;             //Set Din at different times
   #150 Din = 0;
   #75  Din = 1;
 end

always #20 CLK=~CLK;     //Set clock with a period 20 ns

initial #400 $finish;        //Complete simulation after 400 ns
  
endmodule






Blocking & Non Blocking

1.        Blocking的語法 =  //循序式的方式執行程式

Exp :

        always@(posedge clock)

        begin

                Data = A&B;                   // blocking會先執行第一行程式

                OUT = A+B;                   // 緊接著再執行第二行程式

        end

注意 : 電路都使用blocking的方式設計會造成電路串連的太長,導致延遲太多時間。



2.        Non blocking的語法 <=  //平行式的方式執行程式

Exp :

        always@(posedge clock)

        begin

                Data <= A&B;         // non blocking會同時執行

                OUT <= A+B;                 //

        end

注意 : 電路都使用non blocking的方式設計會造成電路面積加大(成本提高),因為並行處理的輸出都要額外給予一個暫存器來儲存。



        對於新手而言,該如何準確的判斷哪些時候該選用blocking,哪些時候又該選用non blocking來做處理,有相當程度的困難。因此通常會給予新手一些建議,避免設計電路上的錯誤。

1.        組合邏輯assign電路採用blocking,且必須搭配wire

2.        循序邏輯always電路採用non blocking,且必須搭配reg



組合邏輯à與時間無關,大多作為運算用。(如加、減法器)

循序邏輯à與時間有關,大多作為記憶資料,但不能運算。(如正反器)

8-bit synchronous counter wit asynchronous reset

8-bit synchronous counter wit asynchronous reset

Then a counter with three flip-flops like the circuit above will count from 0 to 7 ie, 2n-1. It has eight different output states representing the decimal numbers 0 to 7 and is called a Modulo-8 or MOD-8 counter. A counter with four flip-flops will count from 0 to 15 and is therefore called a Modulo-16 counter and so on.
An example of this is given as.
  •   3-bit Binary Counter = 23 = 8 (modulo-8 or MOD-8)
  •   4-bit Binary Counter = 24 = 16 (modulo-16 or MOD-16)
  •   8-bit Binary Counter = 28 = 256 (modulo-256 or MOD-256)
  • and so on..
The Modulo number can be increased by adding more flip-flops to the counter and cascading is a method of achieving higher modulus counters. Then the modulo or MOD number can simply be written as: MOD number = 2n

4-bit Modulo-16 Counter

counter waveform
Multi-bit asynchronous counters connected in this manner are also called “Ripple Counters” or ripple dividers because the change of state at each stage appears to “ripple” itself through the counter from the LSB output to its MSB output connection. Ripple counters are available in standard IC form, from the 74LS393 Dual 4-bit counter to the 74HC4060, which is a 14-bit ripple counter with its own built in clock oscillator and produce excellent frequency division of the fundamental frequency.

//--------------------------------------------------
// 8-bit synchronous counter wit asynchronous reset
//--------------------------------------------------
module CNT_8bit(CLK, RESET, COUNT);
    input CLK;
    input RESET;
    output [7:0] COUNT;
    reg [7:0] COUNT;

always @(posedge CLK or posedge RESET)
begin
   if (RESET)
      COUNT <= 8'b0;
   else 
      COUNT <= COUNT + 1;
end
endmodule
//=====================================
// 時間單位 1ns, 時間精確度10 ps
`timescale 10ns/10ps 
module TB;
/*
module CNT_8bit(CLK, RESET, COUNT);
    input CLK;
    input RESET;
    output [7:0] COUNT;
*/

// Inputs
    reg CLK;
    reg RESET;

// Outputs
    wire [7:0] COUNT;

// Bidirs
initial
    $monitor($time, "    COUNT = %d     RESET = %b", COUNT[7:0], RESET);

// Instantiate the UUT
    CNT_8bit uut (
        .CLK(CLK), 
        .RESET(RESET), 
        .COUNT(COUNT)
        );


// Stimulate the RESET signal
initial begin
   RESET = 1'b1;
   #45 RESET = 1'b0;
   #200 RESET = 1'b1;
   #50 RESET = 1'b0;
end

// Set up the clock to toggle every 100 time units
initial begin
     CLK = 1'b0;
forever #10 CLK=~CLK;
end

//Finish the simulation at time 400
initial begin
     #6400 $finish;
end

endmodule




JK Flip Flop in Verilog

JK Flip Flop in Verilog

module JK_FF (j,k,clk,q);
   input j,k,clk;
   output reg q;

   always @ (posedge clk)
      case ({j,k})
         2'b00 :  q <= q;
         2'b01 :  q <= 0;
         2'b10 :  q <= 1;
         2'b11 :  q <= ~q;
      endcase
   
endmodule


 // 時間單位 1ns, 時間精確度10 ps
`timescale 10ns/10ps
module TB;
   reg j,k,clk=1'b0;
   wire q;
 
   JK_FF    UUT ( .j(j),
                  .k(k),
                  .clk(clk),
                  .q(q));
   always #5 clk = ~clk;

   initial begin
      j <= 1;
      k <= 0;
   
      #7  j <= 0;
          k <= 0;
      #27 j <= 0;
          k <= 1;
      #27 j <= 1;
          k <= 1;
      #20 $stop;
   end

   initial
      $monitor ("j=%0d k=%0d q=%0d", j, k, q);
endmodule

Info: ModelSim-Altera Info: # run -all
Info: ModelSim-Altera Info: # j=1 k=0 q=x
Info: ModelSim-Altera Info: # j=1 k=0 q=0
Info: ModelSim-Altera Info: # j=1 k=0 q=1
Info: ModelSim-Altera Info: # j=0 k=0 q=1
Info: ModelSim-Altera Info: # j=0 k=1 q=1
Info: ModelSim-Altera Info: # j=0 k=1 q=0
Info: ModelSim-Altera Info: # j=1 k=1 q=0
Info: ModelSim-Altera Info: # j=1 k=1 q=1
Info: ModelSim-Altera Info: # j=1 k=1 q=0

Verilog Positive Edge Detector

Verilog Positive Edge Detector




module pos_edge_det (sig,clk,pe);
  
input sig;           
// Input signal for which positive edge has to be detected
input clk;            
// Input signal for clock
output pe;           
// Output signal that gives a pulse when a positive edge occurs

reg   sig_dly;  
// Internal signal to store the delayed version of signal

// This always block ensures that sig_dly is exactly 1 clock behind sig
  always @ (posedge clk) begin
    sig_dly <= sig;
  end

    // Combinational logic where sig is AND with delayed, inverted version of sig
    // Assign statement assigns the evaluated expression in the RHS to the internal net pe
  assign pe = sig & ~sig_dly;  
            
endmodule 

// 時間單位 1ns, 時間精確度10 ps
`timescale 10ns/10ps 
module TB;
  reg sig;         // Declare internal TB signal called sig to drive the sig pin of the design
  reg clk;         // Declare internal TB signal called clk to drive clock to the design

  // Instantiate the design in TB and connect with signals in TB
  pos_edge_det UUT(  
.sig(sig),           
.clk(clk),
                .pe(pe));

  // Generate a clock of 100MHz
  always #5 clk = ~clk;           

  // Drive stimulus to the design
  initial begin
    clk <= 0;
    sig <= 0;
    #15 sig <= 1;
    #20 sig <= 0;
    #15 sig <= 1;
    #10 sig <= 0;
    #20 
$stop;
  end  
endmodule




Verilog Tutorial Contents

2024_09 作業3 以Node-Red 為主

 2024_09 作業3  (以Node-Red 為主  Arduino 可能需要配合修改 ) Arduino 可能需要修改的部分 1)mqtt broker  2) 主題Topic (發行 接收) 3) WIFI ssid , password const char br...