Sie sind auf Seite 1von 41

Program mentorski receptą na efektywne kształcenie na makrokierunku

automatyka i robotyka, elektronika i telekomunikacja, informatyka


na Politechnice Śląskiej
Mentoring program - a recipe for efficient education at the Macrocourse on Automatic Control and Robotics, Electronics and
Telecommunication, and Computer Science offered by the Silesian University of Technology

POKL.04.01.02-00-209/11

Materiały dydaktyczne dla przedmiotu


„Microprocessor Systems”

Teaching materials for lecture


„Microprocessor Systems”

Prezentacja współfinansowana przez Unię Europejską ze środków Europejskiego Funduszu Społecznego

Presentation co-financed by the European Union from the financial resources


of the European Social Fund

Prezentacja dystrybuowana bezpłatnie Presentation distributed free of charge


Verilog HDL
Synthesis and Implementation
Combinatorial circuits
Description with use of continues assignment – assign
Description of multiplexer 4 to 1
Description of 8 bit full adder
Description of parameterized W-bit full adder
Description with use of procedural assignment in always
loop
Description of multiplexer 4 to 1
7 segment decoder – complex function description B4 → B7
Description of W-bit ALU that implements ADD, SUB, AND, OR
Continues assignment - MUX 4 to 1
Logic equation implementation
module MUX(Y, SEL, I);
output Y;
input [1:0] SEL;
input [3:0] I;

assign Y =
(~SEL[1] & ~SEL[0] & I[0]) |
(~SEL[1] & SEL[0] & I[1]) |
( SEL[1] & ~SEL[0] & I[2]) |
( SEL[1] & SEL[0] & I[3]);

endmodule
Continues assignment - MUX 4 to 1
Conditional operator <sel>?<expr_1>:<expr_0>

module MUX(Y, SEL, I);


output Y;
input [1:0] SEL;
Input [3:0] I;

assign Y = SEL[1] ?
(SEL[0] ? I[3] : I[2]) :
(SEL[0] ? I[1] : I[0]);

endmodule
Procedural assignment - MUX 4 to 1
Procedural assignment is triggered by all signals that are
arguments of expressions
module MUX(Y, SEL, I);
output Y;
reg Y; //Overwrite output type
input [1:0] SEL;
input [3:0] I;

always @(SEL or I) //Can be replaced by @(*)


case(SEL)
2’b00: Y = I[0];
2’b01: Y = I[1];
2’b10: Y = I[2];
2’b11: Y = I[3];
endcase
endmodule
Testbench for MUX
`timescale 1ns/100ps
module MUX_TEST;
wire Y;
reg [1:0] SEL;
reg [3:0] I;

MUX UUT(Y.(Y), .SEL(SEL), .I(I)); //Unit under test

//exhaustive test – suitable for small circuits and learning


//Completely unusable in case of large number of inputs e.g.
//32 bits – requires applying 2^32 = 4_294_967_296 vectors!!!
//Including 0,1 and z 3^32 = 1.853e+15
initial begin
repeat(64)
#10 {SEL,I} = {SEL,I} + 1;
end

initial
$monitor(“%t : %d : %b : %b”, $time, SEL, I, Y);

endmodule
Continues assignment - MUX 4 to 1
Parameterized size of multiplexed bus
module MUX(Y, SEL, I0, I1, I2, I3);
parameter W = 4;
output [W-1:0] Y;
input [1:0] SEL;
Input [W-1:0] I0, I1, I2, I3;

assign Y = SEL[1] ?
(SEL[0] ? I_3 : I_2) :
(SEL[0] ? I_1 : I_0);

endmodule
7 segment decoder
Complex function description
We do not know an analytic form of a function
We know a functional description – a tabular form
A case statement
Tabular function representation

module BCD2LED(DATA, BL, LED);


input [3:0] DATA; //Data input
input BL; //Blanking input
output reg [6:0] LED; //7-segment outputs

always @(DATA or BL)


...

endmodule
7 segment decoder – cont.
always @(DATA or BL)
if(BL) LED = 7'b0000000;
else
case(DATA)
4'b0000:LED = 7'b1111110; //0
4'b0001:LED = 7'b0110000;
4'b0010:LED = 7'b1101101;
4'b0011:LED = 7'b1111001;
4'b0100:LED = 7'b0110011;
4'b0101:LED = 7'b1011011;
4'b0110:LED = 7'b1011111;
4'b0111:LED = 7'b1110000;
4'b1000:LED = 7'b1111111;
4'b1001:LED = 7'b1111011; //9
4'b1100:LED = 7'b0111000; //L
4'b1101:LED = 7'b1100111; //P
4'b1110:LED = 7'b0000001; //Minus
default:LED = 7'b0000000; //Blank
endcase
endmodule
Parameterized full adder
Parameterized size of inputs A, B and result S
Concatenation used as LHS to split result into sum and carry
out
Result aware description – better synthesis

module ADD(A, B, Ci, S, Co);


parameter W = 4;
input [W-1:0] A, B;
input Ci;
output [W-1:0] S;
output Co;

assign {Co,S} = A + B + Ci;

endmodule
Parameterized full adder - testbench
module ADD_TEST;
parameter W = 4;
reg [W-1:0] A,B;
wire [W-1:0] S;
wire Co;
integer i;

SUM #(W)S1(.A(A), .B(B), .S(S), .Co(Co));

initial begin
A = {W{1’b0}}; B = {W{1’b0}};
for(i=0; i < w; i = i + 1) begin
repeat(4) {B[i],A[i]} = {B[i],A[i]} + 1;
end
end

initial
$monitor(“%t:\n %b\n %b\n%b:%b”,$time,A,B,Co,S);

endmodule
Parameterized ALU
module ALU(OP, A, B, Ci, Y, Co, Z);
parameter W = 4;
input [W-1:0] A,B;
input Ci;
input [1:0] OP;
output [W-1:0] Y; reg [W-1:0] Y;
output reg Co; //Carry out
output Z; //Zero result

always @(OP or A or B or Ci) begin


case(OP)
2'b00: begin
Y = A & B; Co = 1'b0;
end
2'b01: begin
Y = A | B; Co = 1'b0;
end
2'b10: {Co,Y} = A + B + Ci;
2'b11: {Co,Y} = A - B - Ci;
endcase
end
assign Z = ~|Y;
endmodule
Parameterized ALU - testbench
module ALU_TEST;
parameter W = 16;
reg [W-1:0] A, B;
reg Ci;
wire [W-1:0] Y;
wire Co,Z;
reg [1:0] OP;

ALU #(W)A1(.A(A),.B(B),.Ci(Ci),.Y(Y),.Co(Co),.Z(Z),.OP(OP));

initial begin
A = 16'd0; B = 16'd0; OP = 2'b00; Ci = 1'b0;
#10; A = 16'h05FA; B = 16'hF505;
repeat(4) begin //Cycle through all operations
#10 Ci = 1'b1; #10 Ci = 1'b0;
OP = OP + 1;
end
$finish;
end

endmodule
3-state buffer
3-state buffer enables creating bidirectional bus lines
CTRL signal when deasserted place output of the buffer in
high impedance state
Bus contention appears when more than one buffer is active
at the same time
module BUFT(Y, A, CTRL);
parameter W = 4;
input [W-1:0] A;
output [W-1:0] Y;
input CTRL;

assign Y = CTRL ? A : {W{1’bz}};

endmodule
3-state buffer – testbench structure

`timescale 1ns/100ps
module BUFT_TEST;
parameter W = 8; //Bus width
wire [W-1:0] y; //Bus lines
reg [W-1:0] a1, a2; //Input signals
reg c1, c2; //control signals

//Tested buffers structure


BUFT #(W)B1(.Y(y),.A(a1),.CTRL(c1));
BUFT #(W)B2(.Y(y),.A(a2),.CTRL(c2));
...
3-state buffer – testbench stimulus

initial begin
c1 = 1'b0; c2 = 1'b0;
a1 = {W{1'b0}}; a2 = {W{1'b0}}; task BUFT_DIAG;
#5; integer i;
assign c1 = CTRL; assign a1 = DATA; begin
BUFT_DIAG; CTRL = 1'b1;
deassign c1; deassign a1; DATA = {W{1'b0}};
#5; #5 DATA[0] = 1'b1;
assign c2 = CTRL; assign a2 = DATA; for(i=0; i < W; i = i + 1)
BUFT_DIAG; #5 DATA = DATA << 1;
deassign c2; deassign a2; CTRL = 1'b0;
$display("Bus contention test."); DATA[0] = 1'b1;
a1 = {W{1'b1}}; for(i=0; i < W; i = i + 1)
a2 = {W{1'b0}}; #5 DATA = DATA << 1;
#5 c1 = 1'b1; end
#5 c2 = 1'b1; endtask
#5 c1 = 1'b0;
#5 c2 = 1'b0;
#5 $finish;
end
3-state buffer – contention detection

Detection of x values on y bus lines


initial begin
$dumpfile("buft_test.vcd");
$dumpvars();
end

integer i;
always @(y) begin
for(i=0; i < W; i= i + 1)
if(y[i] === 1'bx)
$display("Warning!!! At %t Bus contention detected on
Y[%d] line!", $time,i);
end
3-state buffer – simulation results
Sequential circuits
D type flip-flop
Triggered with rising/falling edge of clock signal
Synchronous set/reset signals
Asynchronous set/reset signals
Counters
Binary up counter
up/down counters
Counters cascade connection
Loadable counter
Finite State Machines
Single always block description
Dual always block description
Avoiding latches in description
sr-latch flip-flop
module NAND(Y,A,B);
output Y;
input A,B;
module SR_LATCH(Q,Qn,C,S,R);
assign Y = ~(A & B) output Q,Qn;
input C,S,R;
endmodule wire SG,RG;

NAND G_S(SG,C,S);
NAND G_R(SR,C,R);
module SR_FF(Q,Qn,Sn,Rn); SR_FF SR(Q,Qn,SG,RG);
output Q,Qn;
input Sn,Rn; endmodule

NAND G1(Q,Qn,Sn);
NAND G2(Qn,Q,Rn);

endmodule
Different D-type flip-flops

module DFF(CLK, D, Q); module LATCH(CLK, D, Q);


input CLK; input CLK;
input D; input D;
output Q; output Q;
reg Q; reg Q;

always @(posedge CLK) always @(CLK or D)


Q <= D; if(CLK) Q = D;

endmodule endmodule
D flip-flop with preset inputs

module DFF(CLK, CLR, D, Q); module LATCH(CLK, CLR, D, Q);


input CLK, CLR; input CLK, CLR;
input D; input D;
output Q; output Q;
reg Q; reg Q;

always @(posedge CLK or always @(CLK or CLR or D)


posedge CLR) if(CLR)
if(CLR) Q = 1’b0;
Q <= 1’b0; else
else if(CLK)
Q <= D; Q = D;

endmodule endmodule
Shift register

module SHF_REG(CLK, CLR, D, Q);


input CLK, CLR;
input D;
output [7:0] Q;
reg [7:0] Q;

always @(posedge CLK or posedge CLR)


if(CLR)
Q <= 8’d0;
else
Q <= {Q[6:0],D};

endmodule
Binary counter
module CNT(CLK, CLR, Q);
input CLK, CLR;
output [3:0] Q;
reg [3:0] Q;

always @(posedge CLK or posedge CLR)


if(CLR)
Q <= 4’d0;
else
Q <= Q + 1;
//Synchronous CLR
always @(posedge CLK)
endmodule
if(CLR)
Q <= 4’d0;
else
Q <= Q + 1;
...
Binary counter - parameterized
module CNT(CLK, CLR, Q);
parameter W = 8
input CLK, CLR;
output [W-1:0] Q;
reg [W-1:0] Q;

always @(posedge CLK or posedge CLR)


if(CLR)
Q <= {W{1’d0}};
else
Q <= Q + 1; //Synchronous CLR
always @(posedge CLK)
endmodule if(CLR)
Q <= {W{1’d0}};
else
Q <= Q + 1;
...
Loadable binary counter
module CNT(CLK, CLR, LD, D, Q);
parameter W = 8
input CLK, CLR, LD;
input [W-1:0] D;
output [W-1:0] Q;
reg [W-1:0] Q;

always @(posedge CLK or posedge CLR)


if(CLR)
Q <= {W{1’d0}}; //Reset
else begin
if(LD)
Q <= D; //Parallel load
else
Q <= Q + 1; //Counting
end

endmodule
Binary Up-Down Counter
Binary up-down counter
CE - Clock enable input
CEO – Clock enable output
DIR – Counting direction input
Generation of CEO
CE dependant
Counting up – max value
Counting down – min value
module CNT(CLK, CLR, CE, DIR, Q, CEO);
parameter W = 8
input CLK, CLR, LD;
input [W-1:0] D;
output [W-1:0] Q;
reg [W-1:0] Q;
...
Binary Up-Down Counter
...
always @(posedge CLK or posedge CLR)
if(CLR)
Q <= {W{1’d0}}; //Reset
else begin
if(CE) begin
if(DIR)
Q <= Q + 1; //Up Counting
else
Q <= Q - 1; //Down Counting
end
end

assign CEO = CE & (DIR ? &Q : ~|Q);

endmodule
BCD counter
module CNT(CLK, CLR, CE, Q, CEO);
input CLK, CLR, CE;
output reg [3:0] Q;
output CEO;

always @(posedge CLK or posedge CLR)


if(CLR)
Q <= 4’d0;
else begin
if(CE) begin
if(Q != 4’d9) //Better Q[3] & Q[0] – but less readable
Q <= Q + 1;
else
Q <= 4’d0;
end
end

assign CEO = CE & (Q == 4’d9); //Clk Enable Out - cascade

endmodule
BCD counter – cascade connection
Connecting 3 instances of BCD counter into modulo 1000
BCD counter
Instances are linked by CE and CEO signals
//Input signals
wire CLK, CLR, CE;
//Internal Clock Enable signal
wire CE_U, CE_D, CE_H;
// Counter outputs
wire [3:0] Q_U, Q_D, Q_H;

//Instance for Units


CNT C_U(.CLK(CLK), .CLR(CLR), .CE(CE), .Q(Q_U), .CEO(CE_U));
//Instance for Decades
CNT C_U(.CLK(CLK), .CLR(CLR), .CE(CE_U), .Q(Q_U), .CEO(CE_D));
// Instance for Hundreds
CNT C_U(.CLK(CLK), .CLR(CLR), .CE(CE_D), .Q(Q_U), .CEO(CE_H));
Frequency divider by integer value
module FREQ_DV(CLK, CE, CO_ZD);
parameter W = 7; //Counter width
parameter INIT = 98; //Counting range - division
input CLK, CE;
output CO_ZD;
reg [W-1:0] CNT;

always @(posedge CLK) begin


if(CE) begin
if(CNT)
CNT = CNT - 1;
else
CNT = INIT;
end
end

assign CO_ZD = CE & ~(|CNT); //Zero detect -> NOR(Q)

endmodule
Digital Frequency Synthesis
Synthesis based on fractional generation of clock pulses
f = f0 (A/2n)
n – bit width of DDS accumulator
A – programmed value in range 1 – 2n-1
f0 – reference frequency
module DDS(CLK, CE, A, CEO);
parameter W = 16; //Accumulator width
input CLK, CE;
input [W-1:0] A;
output reg CEO;
reg [W-1:0] ACC;

always @(posedge CLK) begin


if(CE) begin
{CEO, ACC} <= ACC + A; //Just an accumulator with CY out
end
end
endmodule
Finite State Machine
@else

STOP
M=0
KB_PLAY
KB_PAUSE
KB_STOP
KB_STOP

KB_PLAY

PAUSE PLAY
M=1 M=1
KB_PAUSE

@else @else
FSM implementation – state register
module TapeCTRL(CLK, CLR, KB_STOP, KB_PAUSE, KB_PLAY, M);
input CLK, CLR, KB_STOP, KB_PAUSE, KB_PLAY;
output M;
reg [1:0] Q, NextQ;

parameter STOP = 2’b00,


PAUSE = 2’b01,
PLAY = 2’b11;

//State register
always @(posedge CLK or posedge CLR)
begin
if(CLR)
Q <= STOP;
else
Q <= NextQ;
end
FSM implementation – next state
//Next state function
always @(Q or KB_STOP or KB_PAUSE or KB_PLAY) begin
NextQ = Q; //Safe encoding -> @else
case(Q)
STOP : begin
if(KB_PAUSE) NextQ = PAUSE;
else if(KB_PLAY) NextQ = PLAY;
end
PAUSE: begin
if(KB_STOP) NextQ = STOP;
else if(KB_PLAY) NextQ = PLAY;
end
PLAY : begin
if(KB_STOP) NextQ = STOP;
else if(KB_PAUSE) NextQ = PAUSE;
end
endcase
end
...
FSM implementation – output

//Output decoding – Moore machine – depends on Q (current state)


always @(Q) begin
M = 1’bx; //Use don’t care for better synthesis
case(Q)
STOP : begin
M = 1’b0;
end
PAUSE: begin
M = 1’b1;
end
PLAY : begin
M = 1’b1;
end
endcase
end

endmodule
Memory implementation
Declaration of synchronous memory (synthesizable)
Write data
Read data
module RAM(CLK, WE, A, D, Q);
parameter DW = 8; //Data word size
Parameter AW = 4; //Address word size
input CLK, WE /*Write Enable*/;
input [AW-1:0] A
input [DW-1:0] D;
output [DW-1:0] Q;
reg [W-1:0] MEM [(1 << AW)-1:0];

always @(posedge CLK)


MEM[A] <= D;

assign Q = MEM[A];

endmodule
Memory implementation
Dual pointer memory
FIFO, Multiport addressable register file, etc.
module RAM(CLK, WE, A1, A2, D, Q1, Q2);
parameter DW = 8; //Data word size
Parameter AW = 4; //Address word size
input CLK, WE /*Write Enable*/;
input [AW-1:0] A1, A2;
input [DW-1:0] D;
output [DW-1:0] Q1, Q2;
reg [W-1:0] MEM [(1 << AW)-1:0];

alaways @(posedge CLK) //Only one write source


MEM[A1] <= D;

assign Q1 = MEM[A1];
assign Q2 = MEM[A2];

endmodule
Block RAM – specific part
module RAMB(CLK, RST, EN, WE, ADDR, D, Q);
output reg [7:0] Q;
input [11:0] ADDR;
input [7:0] D;
input EN, CLK, WE, RST;
reg [7:0] MEM [4095:0];

always@(posedge CLK)
if(EN)
if(RST == 1)
Q <= 1'b0;
else begin
if(WE == 1) Q <= D;
else Q <= MEM[ADDR];
end

always @(posedge CLK)


if (EN & WE) MEM[ADDR] = D;

endmodule
Program mentorski receptą na efektywne kształcenie na makrokierunku
automatyka i robotyka, elektronika i telekomunikacja, informatyka
na Politechnice Śląskiej
Mentoring program - a recipe for efficient education at the Macrocourse on Automatic Control and Robotics, Electronics and
Telecommunication, and Computer Science offered by the Silesian University of Technology

POKL.04.01.02-00-209/11

Materiały dydaktyczne dla przedmiotu


„Microprocessor Systems”

Teaching materials for lecture


„Microprocessor Systems”

Prezentacja współfinansowana przez Unię Europejską ze środków Europejskiego Funduszu Społecznego

Presentation co-financed by the European Union from the financial resources


of the European Social Fund

Prezentacja dystrybuowana bezpłatnie Presentation distributed free of charge

Das könnte Ihnen auch gefallen