COE 405 Design and Synthesis of Data Path

  • Slides: 62
Download presentation
COE 405 Design and Synthesis of Data. Path Controllers Dr. Aiman H. El-Maleh Computer

COE 405 Design and Synthesis of Data. Path Controllers Dr. Aiman H. El-Maleh Computer Engineering Department King Fahd University of Petroleum & Minerals

Outline n Design and Synthesis of RISC Stored Program Machine (SPM( n Universal Asynchronous

Outline n Design and Synthesis of RISC Stored Program Machine (SPM( n Universal Asynchronous Receiver Transceiver (UART( 1 -2

RISM SPM Architecture 1 -3

RISM SPM Architecture 1 -3

RISC SPM Instruction Format Short Format Long Format 1 -4

RISC SPM Instruction Format Short Format Long Format 1 -4

RISC SPM Instruction Set 1 -5

RISC SPM Instruction Set 1 -5

Controller ASM Charts 1 -6

Controller ASM Charts 1 -6

Controller ASM Charts 1 -7

Controller ASM Charts 1 -7

Controller ASM Charts 1 -8

Controller ASM Charts 1 -8

Controller ASM Charts 1 -9

Controller ASM Charts 1 -9

Controller ASM Charts 1 -10

Controller ASM Charts 1 -10

RISC SPM Module module RISC_SPM #(parameter word_size=8, Set 1_size=3, Set 2_size=2)( input clk, rst);

RISC SPM Module module RISC_SPM #(parameter word_size=8, Set 1_size=3, Set 2_size=2)( input clk, rst); // Data Nets wire [Set 1_size-1: 0] Sel_Bus_1_Mux; wire [Set 2_size-1: 0] Sel_Bus_2_Mux; wire zero; wire [word_size-1: 0] instruction, address, Bus_1, mem_word; // Control Nets wire Load_R 0, Load_R 1, Load_R 2, Load_R 3, Load_PC, Inc_PC, Load_IR, Load_Add_R, Load_Reg_Y, Load_Reg_Z, write; 1 -11

RISC SPM Module Processing_Unit M 0_Processor (instruction, address, Bus_1, zero, mem_word, Load_R 0, Load_R

RISC SPM Module Processing_Unit M 0_Processor (instruction, address, Bus_1, zero, mem_word, Load_R 0, Load_R 1, Load_R 2, Load_R 3, Load_PC, Inc_PC, Sel_Bus_1_Mux, Sel_Bus_2_Mux, Load_IR, Load_Add_R, Load_Reg_Y, Load_Reg_Z, clk, rst); Control_Unit M 1_Controller (Sel_Bus_2_Mux, Sel_Bus_1_Mux, Load_R 0, Load_R 1, Load_R 2, Load_R 3, Load_PC, Inc_PC, Load_IR, Load_Add_R, Load_Reg_Y, Load_Reg_Z, write, instruction, zero, clk, rst); Memory_Unit M 2_Mem (mem_word, Bus_1, address, clk, write); endmodule 1 -12

Memory Unit Module module Memory_Unit #(parameter word_size=8, memory_size=256)( output [word_size-1: 0] data_out, input [word_size-1:

Memory Unit Module module Memory_Unit #(parameter word_size=8, memory_size=256)( output [word_size-1: 0] data_out, input [word_size-1: 0] data_in, address, input clk, write); reg [word_size-1: 0] memory[memory_size-1: 0]; assign data_out = memory[address]; always @ (posedge clk) if (write) memory[address] <= data_in; endmodule 1 -13

Processing Unit Module module Processing_Unit #(parameter word_size=8, op_size=4, Sel 1_size=3, Sel 2_size=2)( output [word_size-1:

Processing Unit Module module Processing_Unit #(parameter word_size=8, op_size=4, Sel 1_size=3, Sel 2_size=2)( output [word_size-1: 0] instruction, address, Bus_1, output Zflag, input [word_size-1: 0] mem_word, input Load_R 0, Load_R 1, Load_R 2, Load_R 3, Load_PC, Inc_PC, input [Sel 1_size-1: 0] Sel_Bus_1_Mux, input [Sel 2_size-1: 0] Sel_Bus_2_Mux, input Load_IR, Load_Add_R, Load_Reg_Y, Load_Reg_Z, clk, rst); wire [word_size-1: 0] Bus_2; wire [word_size-1: 0] R 0_out, R 1_out, R 2_out, R 3_out; wire [word_size-1: 0] PC_count, Y_value, alu_out; wire alu_zero_flag; wire [op_size-1: 0] opcode = instruction[word_size-1: word_size-op_size]; 1 -14

Processing Unit Module Register_Unit R 0 (R 0_out, Bus_2, Load_R 0, clk , rst);

Processing Unit Module Register_Unit R 0 (R 0_out, Bus_2, Load_R 0, clk , rst); Register_Unit R 1 (R 1_out, Bus_2, Load_R 1, clk , rst); Register_Unit R 2 (R 2_out, Bus_2, Load_R 2, clk , rst); Register_Unit R 3 (R 3_out, Bus_2, Load_R 3, clk , rst); Register_Unit Reg_Y (Y_value, Bus_2, Load_Reg_Y, clk , rst); Register_Unit #(1) Reg_Z (Zflag, alu_zero_flag, Load_Reg_Z, clk , rst); Register_Unit Add_R (address, Bus_2, Load_Add_R, clk , rst); Register_Unit IR (instruction, Bus_2, Load_IR, clk , rst); Program_Counter PC (PC_count, Bus_2, Load_PC, Inc_PC, clk , rst); Multiplexer_5 ch Mux_1 (Bus_1, R 0_out, R 1_out, R 2_out, R 3_out, PC_count, Sel_Bus_1_Mux); Multiplexer_3 ch Mux_2 (Bus_2, alu_out, Bus_1, mem_word, Sel_Bus_2_Mux); Alu_RISC ALU (alu_out, alu_zero_flag, Bus_1, Y_value , opcode); endmodule 1 -15

Register Unit Module module Register_Unit #(parameter word_size=8)( output reg [word_size-1: 0] data_out, input [word_size-1:

Register Unit Module module Register_Unit #(parameter word_size=8)( output reg [word_size-1: 0] data_out, input [word_size-1: 0] data_in, input load, clk, rst); always @ (posedge clk, negedge rst) if (rst == 1'b 0) data_out <= 0; else if (load) data_out <= data_in; endmodule 1 -16

Program Counter Module module Program_Counter #(parameter word_size=8)( output reg [word_size-1: 0] count, input [word_size-1:

Program Counter Module module Program_Counter #(parameter word_size=8)( output reg [word_size-1: 0] count, input [word_size-1: 0] data_in, input Load_PC, Inc_PC, clk, rst); always @ (posedge clk, negedge rst) if (rst == 1'b 0) count <= 0; else if (Load_PC == 1'b 1) count <= data_in; else if (Inc_PC == 1'b 1) count <= count+1; endmodule 1 -17

Multiplexer Modules module Multiplexer_5 ch #(parameter word_size=8)( output [word_size-1: 0] mux_out, input [word_size-1: 0]

Multiplexer Modules module Multiplexer_5 ch #(parameter word_size=8)( output [word_size-1: 0] mux_out, input [word_size-1: 0] data_a, data_b, data_c, data_d, data_e, input [2: 0] sel); assign mux_out = (sel==0) ? data_a : (sel==1) ? data_b : (sel==2) ? data_c : (sel==3) ? data_d : (sel==4) ? data_e : 'bx; endmodule Multiplexer_3 ch #(parameter word_size=8)( output [word_size-1: 0] mux_out, input [word_size-1: 0] data_a, data_b, data_c, input [1: 0] sel); assign mux_out = (sel==0) ? data_a : (sel==1) ? data_b : (sel==2) ? data_c : 'bx; endmodule 1 -18

ALU Module module Alu_RISC #(parameter word_size=8, op_size=4, // opcodes NOP = 4'b 0000, ADD

ALU Module module Alu_RISC #(parameter word_size=8, op_size=4, // opcodes NOP = 4'b 0000, ADD = 4'b 0001, SUB = 4'b 0010, AND = 4'b 0011, NOT = 4'b 0100, RD = 4'b 0101, WR = 4'b 0110, BR = 4'b 0111, BRZ = 4'b 1000)( output reg [word_size-1: 0] alu_out, output alu_zero_flag, input [word_size-1: 0] data_1, data_2, input [op_size-1: 0] sel); 1 -19

ALU Module assign alu_zero_flag = ~| alu_out; always @(sel, data_1, data_2) case(sel) NOP: alu_out

ALU Module assign alu_zero_flag = ~| alu_out; always @(sel, data_1, data_2) case(sel) NOP: alu_out = 0; ADD: alu_out = data_1 + data_2; SUB: alu_out = data_1 - data_2; AND: alu_out = data_1 & data_2; NOT: alu_out = ~ data_2; default: alu_out = 0; endcase endmodule 1 -20

Control Unit Module module Control_Unit #(parameter word_size=8, op_size=4, state_size=4, src_size=2, dest_size=2, Sel 1_size=3, Sel

Control Unit Module module Control_Unit #(parameter word_size=8, op_size=4, state_size=4, src_size=2, dest_size=2, Sel 1_size=3, Sel 2_size=2)( output [Sel 2_size-1: 0] Sel_Bus_2_Mux, output [Sel 1_size-1: 0] Sel_Bus_1_Mux, output reg Load_R 0, Load_R 1, Load_R 2, Load_R 3, Load_PC, Inc_PC, Load_IR, Load_Add_R, Load_Reg_Y, Load_Reg_Z, write, input [word_size-1: 0] instruction, input zero, clk, rst); // State Codes parameter S_idle=0, S_fet 1=1, S_fet 2=2, S_dec=3, S_ex 1=4, S_rd 1=5, S_rd 2=6, S_wr 1=7, S_wr 2=8, S_br 1=9, S_br 2=10, S_halt=11; // Opcodes parameter NOP=0, ADD=1, SUB=2, AND=3, NOT=4, RD=5, WR=6, BR=7, BRZ=8; // Sources and Destination Codes parameter R 0=0, R 1=1, R 2=2, R 3=3; 1 -21

Control Unit Module reg [state_size-1: 0] state, next_state; reg Sel_ALU, Sel_Bus_1, Sel_Mem; reg Sel_R

Control Unit Module reg [state_size-1: 0] state, next_state; reg Sel_ALU, Sel_Bus_1, Sel_Mem; reg Sel_R 0, Sel_R 1, Sel_R 2, Sel_R 3, Sel_PC; reg err_flag; wire [op_size-1: 0] opcode = instruction[word_size-1: word_size-op_size]; wire [src_size-1: 0] src= instruction[src_size+dest_size-1: dest_size]; wire [src_size-1: 0] dest= instruction[dest_size-1: 0]; // Mux selectors assign Sel_Bus_1_Mux[Sel 1_size-1: 0]=Sel_R 0? 0: Sel_R 1? 1: Sel_R 2? 2: Sel_R 3? 3: Sel_PC? 4: 3'bx; assign Sel_Bus_2_Mux[Sel 2_size-1: 0]=Sel_ALU? 0: Sel_Bus_1? 1: Sel_Mem? 2: 2'bx; always @(posedge clk, negedge rst) begin: State_transitions if (rst==0) state<= S_idle; else state<=next_state; end 1 -22

Control Unit Module always @(state, opcode, src, dest, zero) begin: Output_and_next_state Sel_R 0=0; Sel_R

Control Unit Module always @(state, opcode, src, dest, zero) begin: Output_and_next_state Sel_R 0=0; Sel_R 1=0; Sel_R 2=0; Sel_R 3=0; Sel_PC=0; Load_R 0=0; Load_R 1=0; Load_R 2=0; Load_R 3=0; Load_PC=0; Inc_PC=0; Load_IR=0; Load_Add_R=0; Load_Reg_Y=0; Load_Reg_Z=0; write=0; Sel_Bus_1=0; Sel_ALU=0; Sel_Mem=0; err_flag=0; next_state = state; case (state) S_idle: next_state = S_fet 1; S_fet 1: begin next_state = S_fet 2; Sel_PC = 1; Sel_Bus_1=1; Load_Add_R = 1; end 1 -23

Control Unit Module S_fet 2: begin next_state = S_dec; Sel_Mem= 1; Load_IR = 1;

Control Unit Module S_fet 2: begin next_state = S_dec; Sel_Mem= 1; Load_IR = 1; Inc_PC=1; end S_dec: case(opcode) NOP: next_state = S_fet 1; ADD, SUB, AND: begin next_state = S_ex 1; Sel_Bus_1 = 1; Load_Reg_Y=1; case (src) R 0: Sel_R 0=1; R 1: Sel_R 1=1; R 2: Sel_R 2=1; R 3: Sel_R 3=1; default: err_flag=1; endcase end 1 -24

Control Unit Module NOT: begin next_state = S_ex 1; Load_Reg_Z=1; Sel_ALU=1; case (src) R

Control Unit Module NOT: begin next_state = S_ex 1; Load_Reg_Z=1; Sel_ALU=1; case (src) R 0: Sel_R 0=1; R 1: Sel_R 1=1; R 2: Sel_R 2=1; R 3: Sel_R 3=1; default: err_flag=1; endcase (dest) R 0: Load_R 0=1; R 1: Load_R 1=1; R 2: Load_R 2=1; R 3: Load_R 3=1; default: err_flag=1; endcase end // NOT 1 -25

Control Unit Module RD: begin next_state = S_rd 1; Sel_PC=1; Sel_Bus_1 = 1; Load_Add_R=1;

Control Unit Module RD: begin next_state = S_rd 1; Sel_PC=1; Sel_Bus_1 = 1; Load_Add_R=1; end // RD WR: begin next_state = S_wr 1; Sel_PC=1; Sel_Bus_1 = 1; Load_Add_R=1; end // WR 1 -26

Control Unit Module BR: begin next_state = S_br 1; Sel_PC=1; Sel_Bus_1 = 1; Load_Add_R=1;

Control Unit Module BR: begin next_state = S_br 1; Sel_PC=1; Sel_Bus_1 = 1; Load_Add_R=1; end // BR BRZ: if (zero==1) begin next_state = S_br 1; Sel_PC=1; Sel_Bus_1 = 1; Load_Add_R=1; end else begin next_state = S_fet 1; Inc_PC=1; end 1 -27

Control Unit Module default: next_state=S_halt; endcase //opcode S_ex 1: begin next_state=S_fet 1; Load_Reg_Z=1; Sel_ALU=1;

Control Unit Module default: next_state=S_halt; endcase //opcode S_ex 1: begin next_state=S_fet 1; Load_Reg_Z=1; Sel_ALU=1; case (dest) R 0: begin Sel_R 0=1; Load_R 0=1; end R 1: begin Sel_R 1=1; Load_R 1=1; end R 2: begin Sel_R 2=1; Load_R 2=1; end R 3: begin Sel_R 3=1; Load_R 3=1; end default: err_flag=1; endcase end 1 -28

Control Unit Module S_rd 1: begin next_state=S_rd 2; Sel_Mem=1; Load_Add_R=1; Inc_PC=1; end S_rd 2:

Control Unit Module S_rd 1: begin next_state=S_rd 2; Sel_Mem=1; Load_Add_R=1; Inc_PC=1; end S_rd 2: begin next_state=S_fet 1; Sel_Mem=1; case (dest) R 0: Load_R 0=1; R 1: Load_R 1=1; R 2: Load_R 2=1; R 3: Load_R 3=1; default: err_flag=1; endcase end 1 -29

Control Unit Module S_wr 1: begin next_state=S_wr 2; Sel_Mem=1; Load_Add_R=1; Inc_PC=1; end S_wr 2:

Control Unit Module S_wr 1: begin next_state=S_wr 2; Sel_Mem=1; Load_Add_R=1; Inc_PC=1; end S_wr 2: begin next_state=S_fet 1; write=1; case (src) R 0: Sel_R 0=1; R 1: Sel_R 1=1; R 2: Sel_R 2=1; R 3: Sel_R 3=1; default: err_flag=1; endcase end 1 -30

Control Unit Module S_br 1: begin next_state=S_br 2; Sel_Mem=1; Load_Add_R=1; end S_br 2: begin

Control Unit Module S_br 1: begin next_state=S_br 2; Sel_Mem=1; Load_Add_R=1; end S_br 2: begin next_state=S_fet 1; Sel_Mem=1; Load_PC=1; end S_halt: next_state=S_halt; default: next_state=S_idle; endcase endmodule 1 -31

RISC SPM Program Execution module test_RISC_SPM #(parameter word_size=8)(); reg rst; wire clk; reg [8:

RISC SPM Program Execution module test_RISC_SPM #(parameter word_size=8)(); reg rst; wire clk; reg [8: 0] k; Clok_Unit M 1 (clk); module Clock_Unit (output reg clock); parameter delay =0; parameter half_cycle=10; initial begin #delay clock=0; forever #half_cycle clock=~clock; endmodule RISC_SPM M 2 (clk, rst); // define probes wire [word_size-1: 0] word 0, word 1, word 2, word 3, word 4, word 5, word 6, word 7, word 8, word 9, word 10, word 11, word 12, word 13, word 14, word 128, word 129, word 130, word 131, word 132, word 133, word 134, word 135, word 136, word 137, word 138, word 139, word 140, word 255; 1 -32

RISC SPM Program Execution assign word 0=M 2. M 2_MEM. memory[0], word 1=M 2.

RISC SPM Program Execution assign word 0=M 2. M 2_MEM. memory[0], word 1=M 2. M 2_MEM. memory[1], word 2=M 2. M 2_MEM. memory[2], word 3=M 2. M 2_MEM. memory[3], word 4=M 2. M 2_MEM. memory[4], word 5=M 2. M 2_MEM. memory[5], word 6=M 2. M 2_MEM. memory[6], word 7=M 2. M 2_MEM. memory[7], word 8=M 2. M 2_MEM. memory[8], word 9=M 2. M 2_MEM. memory[9], word 10=M 2. M 2_MEM. memory[10], word 11=M 2. M 2_MEM. memory[5], word 12=M 2. M 2_MEM. memory[12], word 13=M 2. M 2_MEM. memory[5], word 14=M 2. M 2_MEM. memory[14], word 255=M 2. M 2_MEM. memory[255], word 128=M 2. M 2_MEM. memory[128], word 129=M 2. M 2_MEM. memory[129], word 130=M 2. M 2_MEM. memory[130], word 131=M 2. M 2_MEM. memory[131], word 132=M 2. M 2_MEM. memory[132], word 133=M 2. M 2_MEM. memory[133], word 134=M 2. M 2_MEM. memory[134], word 135=M 2. M 2_MEM. memory[135], word 136=M 2. M 2_MEM. memory[136], word 137=M 2. M 2_MEM. memory[137], word 138=M 2. M 2_MEM. memory[138], word 139=M 2. M 2_MEM. memory[139], word 140=M 2. M 2_MEM. memory[140]; 1 -33

RISC SPM Program Execution initial #2800 $finish; initial begin: Flush_Memory #2 rst=0; for (k=0;

RISC SPM Program Execution initial #2800 $finish; initial begin: Flush_Memory #2 rst=0; for (k=0; k<=255; k=k+1) M 2_MEM. memory[k]=0; #10 rst=0; end initial begin: Load_program #5 //opcode_src_dest M 2_MEM. memory[0]=8'b 0000_00_00; // NOP M 2_MEM. memory[1]=8'b 0101_00_10; // Read 130 to R 2 M 2_MEM. memory[2]=130; M 2_MEM. memory[3]=8'b 0101_00_11; // Read 131 to R 3 M 2_MEM. memory[4]=131; M 2_MEM. memory[5]=8'b 0101_00_01; M 2_MEM. memory[6]=128; // Read 128 to R 1 1 -34

RISC SPM Program Execution M 2_MEM. memory[7]=8'b 0101_00_00; // Read 129 to R 0

RISC SPM Program Execution M 2_MEM. memory[7]=8'b 0101_00_00; // Read 129 to R 0 M 2_MEM. memory[8]=129; M 2_MEM. memory[9]=8'b 0010_00_01; // Sub R 1 -R 0 to R 1 M 2_MEM. memory[10]=8'b 1000_00_00; // BRZ M 2_MEM. memory[11]=134; M 2_MEM. memory[12]=8'b 0001_10_11; // Add R 2+R 3 to R 3 M 2_MEM. memory[13]=8'b 0111_00_00; // BR M 2_MEM. memory[14]=140; // Load data M 2_MEM. memory[128]=6; M 2_MEM. memory[129]=1; M 2_MEM. memory[130]=2; M 2_MEM. memory[131]=0; M 2_MEM. memory[134]=139; M 2_MEM. memory[139]=8'b 1111_00_00; // HALT M 2_MEM. memory[140]=9; endmodule 1 -35

RISC SPM Program Execution 1 -36

RISC SPM Program Execution 1 -36

Universal Asynchronous Receiver Transmitter (UART) n Most computers and microcontrollers have one or more

Universal Asynchronous Receiver Transmitter (UART) n Most computers and microcontrollers have one or more serial data ports used to communicate with serial input/output devices n The serial communication interface, which receive serial data, is often called a UART (Universal Asynchronous Receiver-Transmitter) n One application of a UART is the modem (modulatordemodulator) that communicates via telephone lines 1 -37

Universal Asynchronous Receiver Transmitter (UART) n Features of UARTs • Data (D) is transmitted

Universal Asynchronous Receiver Transmitter (UART) n Features of UARTs • Data (D) is transmitted one bit at a time • When no data is being transmitted, D remains high • To mark the transmission, D goes low for one bit time, which • • is referred to as the start bit When text is being transmitted, ASCII code is usually used ASCII is 7 -bit in length the 8 th bit is used for parity check 1 -38

Universal Asynchronous Receiver Transmitter (UART) • After 8 bits are transmitted, D must go

Universal Asynchronous Receiver Transmitter (UART) • After 8 bits are transmitted, D must go high for at least one bit • • n time When receiving, the UART detects the start bit, receives the 8 data bits, and converts the data to parallel form when it detects the stop bit The UART must synchronize the incoming bit stream with the local clock The number of bits transmitted per second is often referred to the BAUD rate 1 -39

Block Diagram of a UART 1 -40

Block Diagram of a UART 1 -40

UART Transmitter Input Signals: Load_XMT_datareg: assertion in state idle asserts Load_XMT_DR which loads Data_Bus

UART Transmitter Input Signals: Load_XMT_datareg: assertion in state idle asserts Load_XMT_DR which loads Data_Bus into XMT_datareg Byte Ready: assertion causes Load_XMT_shftreg to assert which loads contents of XMT_data into XMT_shftreg T_byte: assertion initiates transmission of a byte of data including start, stop and parity bits. BC_lt_Bcmax: indicates status of bit counter Output Signals: Load_XMT_DR, Load_XMT_shftreg Start: signals start of transmission by dropping XMT_shftreg[0] to 0 Shift: directs XMT_shftreg to shift by one bit towards LSB and fill with stop bit 1 Clear: clears bit_count 1 -41

UART Transmitter ASMD Chart 1 -42

UART Transmitter ASMD Chart 1 -42

UART Transmitter Operation 1 -43

UART Transmitter Operation 1 -43

UART Transmitter Module module UART_XMTR #(parameter word_size=8) output Serial_out, input [word_size-1: 0] Data_bus, input

UART Transmitter Module module UART_XMTR #(parameter word_size=8) output Serial_out, input [word_size-1: 0] Data_bus, input Load_XMT_datareg, Byte_ready, T_byte, clock, rst_b); Control_Unit M 0 (Load_XMT_DR, Load_XMT_shftreg, start, shift, clear, Load_XMT_datareg, Byte_ready, T_byte, BC_lt_Bcmax, Clock, rst_b); Datapath_Unit M 1 (Serial_out, BC_lt_Bcmax, Data_Bus, Load_XMT_DR, Load_XMT_shftreg, start, shift, clear, Clock, rst_b); endmodule 1 -44

UART Transmitter Datapath Module Datapath_Unit #(word_size=8, size_bit_count=3, all_ones={(word_size+1){1'b 1}})( output Serial_out, BC_lt_Bcmax, input [word_size-1:

UART Transmitter Datapath Module Datapath_Unit #(word_size=8, size_bit_count=3, all_ones={(word_size+1){1'b 1}})( output Serial_out, BC_lt_Bcmax, input [word_size-1: 0] Data_Bus, input Load_XMT_DR, Load_XMT_shftreg, start, shift, clear, Clock, rst_b); reg [word_size-1: 0] XMT_datareg; reg [word_size: 0] XMT_shftreg; reg [size_bit_count: 0] bit_count; assign BC_lt_Bcmax = (bit_count < word_size+1); always @ (posedge Clock, negedge rst_b) if (rst_b==0) begin XMT_shftreg <= all_ones; bit_count<=0; end 1 -45

UART Transmitter Datapath Module else begin: Register_Transfers if (Load_XMT_DR==1'b 1) XMT_datareg<=Data_Bus; if (Load_XMT_shftreg==1'b 1)

UART Transmitter Datapath Module else begin: Register_Transfers if (Load_XMT_DR==1'b 1) XMT_datareg<=Data_Bus; if (Load_XMT_shftreg==1'b 1) XMT_shftreg<={XMT_datareg, 1'b 1}; If (start==1'b 1) XMT_shftreg[0]<=0; If (clear==1'b 1) bit_count <= 0; If (shift==1'b 1) begin XMT_shftreg <= {1'b 1, XMT_shftreg[word_size: 1]}; bit_count <= bit_count+1; end // Register_Transfers endmodule 1 -46

UART Transmitter Control Unit Module Control_Unit #(parameter one_hot_count=3, state_count=one_hot_count, size_bot_count=3, idle=3'b 001, waiting=3'b 010,

UART Transmitter Control Unit Module Control_Unit #(parameter one_hot_count=3, state_count=one_hot_count, size_bot_count=3, idle=3'b 001, waiting=3'b 010, sending=3'b 100, all_one=9'1_111)( output reg Load_XMT_DR, Load_XMT_shftreg, start, shift, clear, input Load_XMT_datareg, Byte_ready, T_byte, BC_lt_Bcmax, Clock, rst_b); reg [state_count-1: 0] state, next_state; always @ (posedge Clock, negedge rst_b) if (rst_b==1’b 0) state<= idle; else state<=next_state; always @ (state, Load_XMT_datareg, Byte_ready, T_byte, BC_lt_Bcmax) begin Load_XMT_DR=0; Load_XMT_shftreg=0; start=0; shift=0; clear=0; next_state=idle; 1 -47

UART Transmitter Control Unit Module case(state) idle: if (Load_XMT_datareg==1'b 1) begin Load_XMT_DR=1; next_state=idle; end

UART Transmitter Control Unit Module case(state) idle: if (Load_XMT_datareg==1'b 1) begin Load_XMT_DR=1; next_state=idle; end else if (Byte_ready==1'b 1) begin Load_XMT_shftreg=1; next_state=waiting; end waiting: if (T_byte==1'b 1) begin start=1; next_state=sending; end else next_state=waiting; sending: if (BC_lt_BCmax==1'b 1) begin shift=1; next_state=sending; end else begin clear=1; next_state=idle; end default: next_state=idle; endcase endmodule 1 -48

UART Transmitter Simulation 1 -49

UART Transmitter Simulation 1 -49

UART Receiver n UART receiver receives serial bit stream of data, removes start bit

UART Receiver n UART receiver receives serial bit stream of data, removes start bit and transfers data in parallel. n Transmitter’s clock is not available to receiver; data is not synchronized with receiver’s clock. n Issue of synchronization is resolved by generating a local clock at higher frequency to sample received data n Cycles of Sample_clock will be counted to ensure that data are sampled in middle of bit time. 1 -50

UART Receiver n Sampling algorithm must: n Frequency of Sample_clock is 8 times of

UART Receiver n Sampling algorithm must: n Frequency of Sample_clock is 8 times of the frequency of the bit clock that transmitted the data. n Arrival of start bit is determined by detection of successive samples of value 0 after the serial input data goes low. n Three additional samples after the first 0 confirm that a valid start bit has arrived. n 8 successive bits will be sampled at approximately the center of their bit. • Verify that a start bit has been received • Generate samples from 8 bits of the data • Load the samples data onto the local bus 1 -51

UART Receiver Block Diagram Input Signals: read_not_ready_in: signals that host is not ready to

UART Receiver Block Diagram Input Signals: read_not_ready_in: signals that host is not ready to receive data Ser_in_0: asserts while Serial_in is 0 SC_eq_3: asserts while Sample_counter=3 SC_lt_7: asserts while Sample_counter<7 BC_eq_8: asserts while Bit_counter=8 Output Signals: read_not_ready_out: receiver received 8 bits clr_Sample_counter: clears Sample_counter inc_Sample_counter: inc. Sample_counter clr_Bit_counter: clears Bit_counter inc_Bit_counter: inc. Bit_counter shift: causes RCV_shftreg to shift towards LSB load: causes RCV_shftreg to transfre data to RCV_datareg Error 1: if host is not ready to receive data after last bit sampled Error 2: if stop bit is missing 1 -52

UART Receiver ASMD Chart 1 -53

UART Receiver ASMD Chart 1 -53

UART Receiver Module module UART_RCVR #(parameter word_size=8, half_word=word_size/2)( output [word_size-1: 0] RCV_datareg, output read_not_ready_out,

UART Receiver Module module UART_RCVR #(parameter word_size=8, half_word=word_size/2)( output [word_size-1: 0] RCV_datareg, output read_not_ready_out, Error 1, Error 2, input Serial_in, read_not_ready_in, Sample_clk, rst_b); Control_Unit M 0 (read_not_ready_out, Error 1, Error 2, clr_Sample_counter, inc_Sample_counter, clr_Bit_counter, inc_Bit_counter, shift, load, read_not_ready_in, Ser_in_0, SC_eq_3, SC_lt_7, BC_eq_8, Sample_clk, rst_b); Datapath_Unit M 1 (RCV_datareg, Ser_in_0, SC_eq_3, SC_lt_7, BC_eq_8, Serial_in, clr_Sample_counter, inc_Sample_counter, clr_Bit_counter, inc_Bit_counter, shift, load, Sample_clk, rst_b); endmodule 1 -54

UART Receiver Datapath Unit Module module Datapath_Unit #(parameter word_size=8, half_word=word_size/2, Num_counter_bits=4)( output reg [word_size-1:

UART Receiver Datapath Unit Module module Datapath_Unit #(parameter word_size=8, half_word=word_size/2, Num_counter_bits=4)( output reg [word_size-1: 0] RCV_datareg, output Ser_in_0, SC_eq_3, SC_lt_7, BC_eq_8, input Serial_in, clr_Sample_counter, inc_Sample_counter, clr_Bit_counter, inc_Bit_counter, shift, load, Sample_clk, rst_b); reg [word_size-1: 0] RCV_shftreg; reg [Num_counter_bits-1: 0] Sample_counter; reg [Num_counter_bits: 0] Bit_counter; assign Ser_in_0 = (Serial_in==1'b 0); assign BC_eq_8 = (Bit_counter == word_size); assign SC_lt_7 = (Sample_counter < word_size-1); assign SC_eq_3 = (Sample_counter == half_word-1); 1 -55

UART Receiver Datapath Unit Module always @ (posedge Sample_clk) if (rst_b==1'b 0) begin Sample_counter

UART Receiver Datapath Unit Module always @ (posedge Sample_clk) if (rst_b==1'b 0) begin Sample_counter <=0; Bit_counter<=0; RCV_datareg<=0; RCV_shftreg<=0; end else begin if (clr_Sample_counter == 1) Sample_counter<=0; else if (inc_Sample_counter == 1) Sample_counter <= Sample_counter+1; if (clr_Bit_counter == 1) Bit_counter<=0; else if (inc_Bit_counter == 1) Bit_counter <= Bit_counter+1; if (shift) RCV_shftreg <= {Serial_in, RCV_shftreg[word_size-1: 1]}; if (load) RCV_datareg <= RCV_shftreg ; endmodule 1 -56

UART Receiver Control Unit Module module Control_Unit #(parameter word_size=8, half_word=word_size/2, Num_state_bits=2, idle=2'b 00, starting=2'b

UART Receiver Control Unit Module module Control_Unit #(parameter word_size=8, half_word=word_size/2, Num_state_bits=2, idle=2'b 00, starting=2'b 01, receiving=2'b 10)( output reg read_not_ready_out, Error 1, Error 2, clr_Sample_counter, inc_Sample_counter, clr_Bit_counter, inc_Bit_counter, shift, load, input read_not_ready_in, Ser_in_0, SC_eq_3, SC_lt_7, BC_eq_8, Sample_clk, rst_b); reg [Num_state_bits-1: 0] state, next_state; always @ (posedge Sample_clk) if (rst_b==1'b 0) state <= idle; else state <= next_state; 1 -57

UART Receiver Control Unit Module always @ (state, Ser_in_0, SC_eq_3, SC_lt_7, read_not_ready_in) begin read_not_ready_out=0;

UART Receiver Control Unit Module always @ (state, Ser_in_0, SC_eq_3, SC_lt_7, read_not_ready_in) begin read_not_ready_out=0; Error 1=0; Error 2=0; clr_Sample_counter=0; inc_Sample_counter=0 ; clr_Bit_counter=0; inc_Bit_counter=0; shift=0; load=0; next_state = idle; case (state) idle: if (Ser_in_0==1'b 1) next_state=starting; else next_state=idle; starting: if (Ser_in_0==1'b 0) begin next_state=idle; clr_Sample_counter=1; end else 1 -58

UART Receiver Control Unit Module if (SC_eq_3==1'b 1) begin next_state=receiving; clr_Sample_counter=1; end else begin

UART Receiver Control Unit Module if (SC_eq_3==1'b 1) begin next_state=receiving; clr_Sample_counter=1; end else begin next_state=starting; inc_Sample_counter=1; end receiving: if (SC_lt_7==1'b 1) begin next_state=receiving; inc_Sample_counter=1; end else begin clr_Sample_counter=1; 1 -59

UART Receiver Control Unit Module if (!BC_eq_8) begin next_state=receiving; inc_Bit_counter=1; shift=1; end else begin

UART Receiver Control Unit Module if (!BC_eq_8) begin next_state=receiving; inc_Bit_counter=1; shift=1; end else begin next_state=idle; clr_Bit_counter=1; read_not_ready_out=1; if (read_not_ready_in==1'b 1) Error 1=1; else if (Ser_in_0==1'b 1) Error 2=1; else load=1; end default: next_state=idle; endcase endmodule 1 -60

UART Receiver Simulation 1 -61

UART Receiver Simulation 1 -61

UART Receiver Simulation 1 -62

UART Receiver Simulation 1 -62