├── UART
├── UART TX
│ ├── input_data.txt
│ ├── expected_output.txt
│ ├── MUX.v
│ ├── parity_calc.v
│ ├── serializer.v
│ ├── UART_TX.v
│ ├── FSM.v
│ ├── README.md
│ └── UART_TX_tb.v
└── UART RX
│ ├── stop_check.v
│ ├── start_check.v
│ ├── parity_check.v
│ ├── deserializer.v
│ ├── edge_bit_counter.v
│ ├── data_sampling.v
│ ├── UART_RX.v
│ ├── README.md
│ └── FSM.v
├── BACKEND
├── Synthesis
│ ├── constraints.rpt
│ ├── clocks.rpt
│ ├── power.rpt
│ ├── check_design.rpt
│ └── area.rpt
├── Formal Verification (POST-DFT)
│ ├── aborted_points.rpt
│ ├── failing_points.rpt
│ └── unverified_points.rpt
├── Formal Verification (POST-SYN)
│ ├── aborted_points.rpt
│ ├── failing_points.rpt
│ └── unverified_points.rpt
├── DFT
│ ├── check_design.rpt
│ ├── clocks.rpt
│ ├── power.rpt
│ └── area.rpt
└── README.md
├── Pulse Generator
├── PULSE_GEN.v
├── README.md
└── PULSE_GEN_tb.v
├── Data Synchronizer
├── PULSE_GEN.v
├── sync_bus.v
├── DS_PULSE.v
├── multi_ff.v
├── DATA_SYNC.v
├── README.md
└── DATA_SYNC_tb.v
├── Clock Gate
├── ClkGate_tb.v
├── ClkGate.v
└── README.md
├── Reset Synchronizer
├── RST_SYNC.v
├── README.md
└── RST_SYNC_tb.v
├── Asynchronous FIFO
├── DF_SYNC.v
├── GRAY_CONV.v
├── FIFO_MEM_CNTRL.v
├── FIFO_RD.v
├── FIFO_WR.v
├── ASYNC_FIFO.v
├── ASYNC_FIFO_tb.v
└── README.md
├── ALU
├── ALU.v
└── README.md
├── Register File
├── RegFile.v
├── README.md
└── RegFile_tb.v
├── Clock Divider
├── README.md
├── ClkDiv.v
└── ClkDiv_tb.v
├── System Controller
├── README.md
└── SYS_CTRL.v
├── SYS_TOP_tb.v
├── README.md
└── SYS_TOP.v
/UART/UART TX/input_data.txt:
--------------------------------------------------------------------------------
1 | 01111101
2 | 10100101
3 | 01001111
4 | 01011110
5 | 00101101
6 | 10000000
7 | 10011111
8 | 00010011
9 | 10001101
--------------------------------------------------------------------------------
/UART/UART TX/expected_output.txt:
--------------------------------------------------------------------------------
1 | 01011111001
2 | 01010010101
3 | 01111001011
4 | 00111101001
5 | 01011010011
6 | 00000000101
7 | 0111110011
8 | 0110010001
9 | 0101100011
--------------------------------------------------------------------------------
/BACKEND/Synthesis/constraints.rpt:
--------------------------------------------------------------------------------
1 |
2 | ****************************************
3 | Report : constraint
4 | -all_violators
5 | Design : SYS_TOP
6 | Version: K-2015.06
7 | Date : Mon Sep 25 22:32:08 2023
8 | ****************************************
9 |
10 | This design has no violated constraints.
11 |
12 | 1
13 |
--------------------------------------------------------------------------------
/UART/UART RX/stop_check.v:
--------------------------------------------------------------------------------
1 | module stop_check
2 | ( input wire enable,
3 | input wire sampled_stop_bit,
4 | output reg error );
5 |
6 | always @(*)
7 | begin
8 | if(enable && !sampled_stop_bit)
9 | error = 1'b1;
10 | else
11 | error = 1'b0;
12 | end
13 | endmodule
14 |
15 |
--------------------------------------------------------------------------------
/UART/UART RX/start_check.v:
--------------------------------------------------------------------------------
1 | module start_check
2 | ( input wire enable,
3 | input wire sampled_start_bit,
4 | output reg glitch );
5 |
6 | always @(*)
7 | begin
8 | if(enable && sampled_start_bit)
9 | glitch = 1'b1;
10 | else
11 | glitch = 1'b0;
12 | end
13 | endmodule
14 |
15 |
--------------------------------------------------------------------------------
/BACKEND/Formal Verification (POST-DFT)/aborted_points.rpt:
--------------------------------------------------------------------------------
1 | **************************************************
2 | Report : aborted_points
3 |
4 | Reference : Ref:/WORK/SYS_TOP
5 | Implementation : Imp:/WORK/SYS_TOP
6 | Version : L-2016.03-SP1
7 | Date : Mon Sep 25 23:05:17 2023
8 | **************************************************
9 |
10 | No aborted compare points.
11 |
12 | 1
13 |
--------------------------------------------------------------------------------
/BACKEND/Formal Verification (POST-DFT)/failing_points.rpt:
--------------------------------------------------------------------------------
1 | **************************************************
2 | Report : failing_points
3 |
4 | Reference : Ref:/WORK/SYS_TOP
5 | Implementation : Imp:/WORK/SYS_TOP
6 | Version : L-2016.03-SP1
7 | Date : Mon Sep 25 23:05:17 2023
8 | **************************************************
9 |
10 | No failing compare points.
11 |
12 | 1
13 |
--------------------------------------------------------------------------------
/BACKEND/Formal Verification (POST-SYN)/aborted_points.rpt:
--------------------------------------------------------------------------------
1 | **************************************************
2 | Report : aborted_points
3 |
4 | Reference : Ref:/WORK/SYS_TOP
5 | Implementation : Imp:/WORK/SYS_TOP
6 | Version : L-2016.03-SP1
7 | Date : Mon Sep 25 22:56:38 2023
8 | **************************************************
9 |
10 | No aborted compare points.
11 |
12 | 1
13 |
--------------------------------------------------------------------------------
/BACKEND/Formal Verification (POST-SYN)/failing_points.rpt:
--------------------------------------------------------------------------------
1 | **************************************************
2 | Report : failing_points
3 |
4 | Reference : Ref:/WORK/SYS_TOP
5 | Implementation : Imp:/WORK/SYS_TOP
6 | Version : L-2016.03-SP1
7 | Date : Mon Sep 25 22:56:38 2023
8 | **************************************************
9 |
10 | No failing compare points.
11 |
12 | 1
13 |
--------------------------------------------------------------------------------
/BACKEND/Formal Verification (POST-DFT)/unverified_points.rpt:
--------------------------------------------------------------------------------
1 | **************************************************
2 | Report : unverified_points
3 |
4 | Reference : Ref:/WORK/SYS_TOP
5 | Implementation : Imp:/WORK/SYS_TOP
6 | Version : L-2016.03-SP1
7 | Date : Mon Sep 25 23:05:17 2023
8 | **************************************************
9 |
10 | No unverified compare points.
11 |
12 | 1
13 |
--------------------------------------------------------------------------------
/BACKEND/Formal Verification (POST-SYN)/unverified_points.rpt:
--------------------------------------------------------------------------------
1 | **************************************************
2 | Report : unverified_points
3 |
4 | Reference : Ref:/WORK/SYS_TOP
5 | Implementation : Imp:/WORK/SYS_TOP
6 | Version : L-2016.03-SP1
7 | Date : Mon Sep 25 22:56:38 2023
8 | **************************************************
9 |
10 | No unverified compare points.
11 |
12 | 1
13 |
--------------------------------------------------------------------------------
/BACKEND/DFT/check_design.rpt:
--------------------------------------------------------------------------------
1 |
2 | ****************************************
3 | check_design summary:
4 | Version: K-2015.06
5 | Date: Mon Sep 25 22:59:38 2023
6 | ****************************************
7 |
8 | Name Total
9 | --------------------------------------------------------------------------------
10 | No issues found.
11 | --------------------------------------------------------------------------------
12 |
13 | 1
14 |
--------------------------------------------------------------------------------
/Pulse Generator/PULSE_GEN.v:
--------------------------------------------------------------------------------
1 | module PULSE_GEN (
2 | input wire CLK , // Clock Signal
3 | input wire RST , // Active Low Reset
4 | input wire LVL_SIG , // Level signal
5 | output wire PULSE_SIG ); // Pulse signal
6 |
7 | // register declaration
8 | reg DFF;
9 |
10 | // shifting the input
11 | always @(posedge CLK or negedge RST)
12 | begin
13 | if(!RST)
14 | DFF <= 1'b0;
15 | else
16 | DFF <= LVL_SIG;
17 | end
18 |
19 | // pulse generation
20 | assign PULSE_SIG = (~DFF) & LVL_SIG;
21 |
22 | endmodule
23 |
--------------------------------------------------------------------------------
/Data Synchronizer/PULSE_GEN.v:
--------------------------------------------------------------------------------
1 | module PULSE_GEN (
2 | input wire CLK , // Clock Signal
3 | input wire RST , // Active Low Reset
4 | input wire LVL_SIG , // Level signal
5 | output wire PULSE_SIG ); // Pulse signal
6 |
7 | // register declaration
8 | reg DFF;
9 |
10 | // shifting the input
11 | always @(posedge CLK or negedge RST)
12 | begin
13 | if(!RST)
14 | DFF <= 1'b0;
15 | else
16 | DFF <= LVL_SIG;
17 | end
18 |
19 | // pulse generation
20 | assign PULSE_SIG = (~DFF) & LVL_SIG;
21 |
22 | endmodule
23 |
--------------------------------------------------------------------------------
/Data Synchronizer/sync_bus.v:
--------------------------------------------------------------------------------
1 | module sync_bus #( parameter BUS_WIDTH = 8)
2 | ( input wire RST ,
3 | input wire CLK ,
4 | input wire SEL ,
5 | input wire [BUS_WIDTH-1:0] i_0 ,
6 | input wire [BUS_WIDTH-1:0] i_1 ,
7 | output reg [BUS_WIDTH-1:0] sync_bus );
8 |
9 | wire [BUS_WIDTH-1:0] mux_out;
10 |
11 | assign mux_out = SEL? i_1 : i_0;
12 |
13 | always @(negedge RST or posedge CLK)
14 | begin
15 | if(!RST)
16 | sync_bus <= 'b0;
17 | else
18 | sync_bus <= mux_out;
19 | end
20 |
21 | endmodule
--------------------------------------------------------------------------------
/Data Synchronizer/DS_PULSE.v:
--------------------------------------------------------------------------------
1 | module D
2 | ( input wire CLK ,
3 | input wire RST ,
4 | input wire bus_enable ,
5 | output wire pulse ,
6 | output reg enable_pulse );
7 |
8 | // enable shifting
9 | PULSE_GEN inst_PULSE_GEN (
10 | .CLK(CLK) ,
11 | .RST(RST) ,
12 | .LVL_SIG(bus_enable) ,
13 | .PULSE_SIG(pulse) );
14 |
15 | // passing the enable pulse
16 | always @(negedge RST or posedge CLK)
17 | begin
18 | if(!RST)
19 | enable_pulse <= 1'b0;
20 | else
21 | enable_pulse <= pulse;
22 | end
23 |
24 |
25 | endmodule
26 |
--------------------------------------------------------------------------------
/Clock Gate/ClkGate_tb.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/100ps
2 |
3 | module ClkGate_tb ();
4 |
5 | reg CLK_EN;
6 | reg CLK;
7 | wire GATED_CLK;
8 |
9 | initial
10 | begin
11 | CLK = 0;
12 | CLK_EN = 0;
13 |
14 | #10
15 | @(posedge CLK)
16 | #2
17 | CLK_EN = 1;
18 | #20
19 | CLK_EN = 0;
20 | #28
21 |
22 | @(negedge CLK)
23 | #2
24 | CLK_EN = 1;
25 | #20
26 | CLK_EN = 0;
27 | #3
28 |
29 | @(posedge CLK)
30 | #1
31 | CLK_EN = 1;
32 | #1
33 | CLK_EN = 0;
34 | #3
35 |
36 | @(negedge CLK)
37 | #1
38 | CLK_EN = 1;
39 | #1
40 | CLK_EN = 0;
41 | #3
42 |
43 | #20 $stop;
44 |
45 | end
46 |
47 | always #5 CLK = ~CLK;
48 |
49 | ClkGate DUT ( .CLK_EN(CLK_EN),
50 | .CLK(CLK),
51 | .GATED_CLK(GATED_CLK) );
52 |
53 |
54 | endmodule
--------------------------------------------------------------------------------
/UART/UART TX/MUX.v:
--------------------------------------------------------------------------------
1 | module MUX ( input wire start_bit,
2 | input wire stop_bit,
3 | input wire ser_data,
4 | input wire par_bit,
5 | input wire [1:0] mux_sel,
6 | output reg TX_OUT );
7 |
8 | // mux selector encoding
9 | localparam mux_start = 2'b00;
10 | localparam mux_serial = 2'b01;
11 | localparam mux_parity = 2'b10;
12 | localparam mux_stop = 2'b11;
13 |
14 | always @(*)
15 | begin
16 | case(mux_sel)
17 | mux_start: TX_OUT = start_bit;
18 | mux_serial: TX_OUT = ser_data;
19 | mux_parity: TX_OUT = par_bit;
20 | mux_stop: TX_OUT = stop_bit;
21 |
22 | //default: TX_OUT = 1'b1;
23 |
24 | endcase
25 | end
26 | endmodule
27 |
--------------------------------------------------------------------------------
/Reset Synchronizer/RST_SYNC.v:
--------------------------------------------------------------------------------
1 | module RST_SYNC #( parameter NUM_STAGES = 2)
2 | ( input wire CLK , // Clock Signal
3 | input wire RST , // Active Low Async Reset
4 | output wire SYNC_RST ); // Active Low synchronized Reset
5 |
6 | // intermediate synchronizer FFs
7 | reg [NUM_STAGES-1:0] sync_dff ;
8 |
9 | // generate control loop index
10 | integer i;
11 |
12 | always @(negedge RST or posedge CLK)
13 | begin
14 | if(!RST)
15 | sync_dff <= 'b0;
16 | else
17 | begin
18 | for(i = 0; i < NUM_STAGES; i = i + 1)
19 | begin
20 | if(i==0)
21 | sync_dff[i] <= 1'b1;
22 | else
23 | sync_dff[i] <= sync_dff[i-1];
24 | end
25 | end
26 | end
27 |
28 | // output
29 | assign SYNC_RST = sync_dff[NUM_STAGES-1];
30 |
31 | endmodule
32 |
--------------------------------------------------------------------------------
/UART/UART RX/parity_check.v:
--------------------------------------------------------------------------------
1 | module parity_check #(
2 | parameter WIDTH = 8,
3 | EVEN = 0,
4 | ODD = 1)
5 | (
6 | input [WIDTH-1:0] data,
7 | input wire par_type,
8 | input wire par_bit,
9 | input wire enable,
10 | output reg error );
11 |
12 | wire data_xor;
13 | // calculate parity with the extracted data
14 | always @(*)
15 | begin
16 | if(enable)
17 | case(par_type)
18 | EVEN: begin
19 | if(par_bit == (data_xor))
20 | error = 1'b0;
21 | else
22 | error = 1'b1;
23 | end
24 | ODD: begin
25 | if(par_bit == (~data_xor))
26 | error = 1'b0;
27 | else
28 | error = 1'b1;
29 | end
30 | endcase
31 | else
32 | error = 1'b0;
33 | end
34 |
35 | assign data_xor = ^data;
36 | endmodule
--------------------------------------------------------------------------------
/Clock Gate/ClkGate.v:
--------------------------------------------------------------------------------
1 | module ClkGate #( parameter POST_SYN = 0)
2 | ( input wire CLK , // Clock Signal
3 | input wire CLK_EN , // Clock Enable
4 | output wire GATED_CLK ); // Gated Clock signal
5 |
6 | // latch enable signal declaration
7 | reg CLK_EN_LATCHED;
8 |
9 |
10 | // generate block for post-syn design
11 | generate
12 | case(POST_SYN)
13 | 1'b0:
14 | begin : FOR_SIMULATION
15 | always @(CLK)
16 | begin
17 | if(!CLK)
18 | CLK_EN_LATCHED <= CLK_EN;
19 | end
20 | assign GATED_CLK = CLK & CLK_EN_LATCHED;
21 | end
22 |
23 | 1'b1:
24 | begin : FOR_SYN
25 | TLATNCAX6M U0_CLK_GATE_CELL (
26 | .CK (CLK) ,
27 | .E (CLK_EN) ,
28 | .ECK (GATED_CLK) );
29 | end
30 | endcase
31 | endgenerate
32 | endmodule
--------------------------------------------------------------------------------
/Data Synchronizer/multi_ff.v:
--------------------------------------------------------------------------------
1 | module multi_ff #( parameter BUS_WIDTH = 1, NUM_STAGES = 2)
2 | ( input wire CLK ,
3 | input wire RST ,
4 | input wire [BUS_WIDTH-1:0] ASYNC ,
5 | output wire [BUS_WIDTH-1:0] SYNC );
6 |
7 | // intermediate synchronizer FFs
8 | reg [BUS_WIDTH-1:0] sync_dff [NUM_STAGES-1:0];
9 |
10 | // control loop index
11 | integer i;
12 |
13 | always @(negedge RST or posedge CLK)
14 | begin
15 | if(!RST)
16 | for(i = 0; i < NUM_STAGES; i = i + 1)
17 | sync_dff[i] <= 'b0;
18 | else
19 | begin
20 | for(i = 0; i < NUM_STAGES; i = i + 1)
21 | begin
22 | if(i == 0)
23 | sync_dff[i] <= ASYNC;
24 | else
25 | sync_dff[i] <= sync_dff[i-1];
26 | end
27 | end
28 | end
29 |
30 | // output
31 | assign SYNC = sync_dff[NUM_STAGES-1];
32 | endmodule
33 |
34 |
--------------------------------------------------------------------------------
/Asynchronous FIFO/DF_SYNC.v:
--------------------------------------------------------------------------------
1 | module DF_SYNC #( parameter BUS_WIDTH = 4, NUM_STAGES = 2)
2 | ( input wire CLK ,
3 | input wire RST ,
4 | input wire [BUS_WIDTH-1:0] ASYNC ,
5 | output wire [BUS_WIDTH-1:0] SYNC );
6 |
7 | // intermediate synchronizer FFs
8 | reg [BUS_WIDTH-1:0] sync_dff [NUM_STAGES-1:0];
9 |
10 | // control loop index
11 | integer i;
12 |
13 | always @(negedge RST or posedge CLK)
14 | begin
15 | if(!RST)
16 | for(i = 0; i < NUM_STAGES; i = i + 1)
17 | sync_dff[i] <= 'b0;
18 | else
19 | begin
20 | for(i = 0; i < NUM_STAGES; i = i + 1)
21 | begin
22 | if(i == 0)
23 | sync_dff[i] <= ASYNC;
24 | else
25 | sync_dff[i] <= sync_dff[i-1];
26 | end
27 | end
28 | end
29 |
30 | // output
31 | assign SYNC = sync_dff[NUM_STAGES-1];
32 | endmodule
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Asynchronous FIFO/GRAY_CONV.v:
--------------------------------------------------------------------------------
1 | //******************************************************************************************//
2 | // Description: //
3 | // ------------ //
4 | // It is N-bit Bit-Gray Code Converter //
5 | // //
6 | //******************************************************************************************//
7 |
8 | module GRAY_CONV #( parameter PTR_WIDTH = 4 )
9 | ( input wire [PTR_WIDTH-1:0] bit_ptr ,
10 | output reg [PTR_WIDTH-1:0] gray_ptr );
11 |
12 | // control loop variable
13 | integer i;
14 |
15 | // conversion always block
16 | always @(*)
17 | begin
18 | for(i = 0; i < PTR_WIDTH-1; i = i + 1)
19 | begin
20 | gray_ptr[i] = bit_ptr[i] + bit_ptr[i+1];
21 | end
22 | gray_ptr[PTR_WIDTH-1] = bit_ptr[PTR_WIDTH-1]; // the MSB is kept the same
23 | end
24 | endmodule
25 |
--------------------------------------------------------------------------------
/UART/UART TX/parity_calc.v:
--------------------------------------------------------------------------------
1 | module parity_calc #( parameter WIDTH = 8 )
2 | ( input wire [WIDTH-1:0] P_DATA,
3 | input wire PAR_TYP,
4 | input wire CLK,
5 | input wire RST,
6 | input wire PAR_EN,
7 | input wire Data_Valid,
8 | output reg par_bit );
9 |
10 | reg [WIDTH-1:0] data;
11 |
12 | localparam EVEN = 1'b0;
13 | localparam ODD = 1'b1;
14 |
15 | always @(posedge CLK, negedge RST)
16 | begin
17 | if(!RST)
18 | data <= 'b0;
19 | else if(Data_Valid)
20 | data <= P_DATA;
21 | end
22 |
23 | always @(*)
24 | begin
25 | if(PAR_EN)
26 | par_bit = (PAR_TYP)? ~^data : ^data;
27 | else
28 | par_bit = 1'b0;
29 | end
30 |
31 |
32 | /*always @(posedge CLK, negedge RST)
33 | begin
34 | if(!RST)
35 | begin
36 | data <= 'b0;
37 | par_bit <= 1'b0;
38 | end
39 | else if(PAR_EN)
40 | begin
41 | par_bit <= (PAR_TYP)? ~^data : ^data;
42 | end
43 | else
44 | data <= P_DATA;
45 | end */
46 |
47 | endmodule
48 |
--------------------------------------------------------------------------------
/Data Synchronizer/DATA_SYNC.v:
--------------------------------------------------------------------------------
1 | module DATA_SYNC #( parameter BUS_WIDTH = 8, NUM_STAGES = 2)
2 | ( input wire dest_clk ,
3 | input wire dest_rst ,
4 | input wire bus_enable ,
5 | input wire [BUS_WIDTH-1:0] unsync_bus ,
6 | output wire [BUS_WIDTH-1:0] sync_bus ,
7 | output wire enable_pulse );
8 |
9 | // internal signal declaration
10 | wire x_sync_bus_enable;
11 | wire x_pulse_sel;
12 |
13 | multi_ff U0_multi_ff (
14 | .CLK (dest_clk) ,
15 | .RST (dest_rst) ,
16 | .ASYNC (bus_enable) ,
17 | .SYNC (x_sync_bus_enable) );
18 |
19 |
20 | DS_PULSE U0_DS_PULSE (
21 | .CLK (dest_clk) ,
22 | .RST (dest_rst) ,
23 | .bus_enable (x_sync_bus_enable) ,
24 | .pulse (x_pulse_sel) ,
25 | .enable_pulse (enable_pulse) );
26 |
27 | sync_bus U0_sync_bus (
28 | .CLK (dest_clk) ,
29 | .RST (dest_rst) ,
30 | .SEL (x_pulse_sel) ,
31 | .i_0 (sync_bus) ,
32 | .i_1 (unsync_bus) ,
33 | .sync_bus (sync_bus) );
34 |
35 |
36 | endmodule
37 |
--------------------------------------------------------------------------------
/UART/UART RX/deserializer.v:
--------------------------------------------------------------------------------
1 | module deserializer #(
2 | parameter WIDTH = 8 )
3 | (
4 | input wire clk ,
5 | input wire rst ,
6 | input wire enable ,
7 | input wire sampled_bit ,
8 | input wire success ,
9 | output reg data_valid ,
10 | output reg [WIDTH-1:0] sampled_stream ,
11 | output reg [WIDTH-1:0] parallel_data );
12 |
13 | // shifter and counter always block
14 | always @(posedge clk, negedge rst)
15 | begin
16 | if(!rst)
17 | begin
18 | sampled_stream <= 'b0;
19 | end
20 | else if(enable)
21 | begin
22 | sampled_stream <= {sampled_bit,sampled_stream[7:1]};
23 | end
24 | end
25 |
26 | always @(posedge clk, negedge rst)
27 | begin
28 | if(!rst)
29 | begin
30 | parallel_data <= 'b0;
31 | data_valid <= 'b0;
32 | end
33 | else if(success)
34 | begin
35 | parallel_data <= sampled_stream;
36 | data_valid <= 'b1;
37 | end
38 | else if(!success)
39 | begin
40 | data_valid <= 'b0;
41 | end
42 | end
43 | endmodule
44 |
--------------------------------------------------------------------------------
/UART/UART RX/edge_bit_counter.v:
--------------------------------------------------------------------------------
1 | module edge_bit_counter #(
2 | parameter MAX_PRESCALE = 32 ,
3 | PAR_MAX = 11 ,
4 | PRSC_WIDTH = ($clog2(MAX_PRESCALE)+1) ,
5 | FRAME_WIDTH = ($clog2(PAR_MAX) + 1) )
6 | (
7 | input wire clk ,
8 | input wire rst ,
9 | input wire enable ,
10 | input wire parity_en ,
11 | input wire [PRSC_WIDTH-1:0] prescale ,
12 | output reg [PRSC_WIDTH-2:0] edge_cnt ,
13 | output reg [FRAME_WIDTH-2:0] bit_cnt ,
14 | output wire edge_max );
15 |
16 | // counter max value declaration
17 | wire bit_max;
18 |
19 | // edge sampling counter
20 | always @(posedge clk, negedge rst)
21 | begin
22 | if(!rst)
23 | edge_cnt <= 'b0;
24 | else if(!enable || (enable && edge_max))
25 | edge_cnt <= 'b0;
26 | else
27 | edge_cnt <= edge_cnt + 1'b1;
28 | end
29 |
30 | // bit counter
31 | always @(posedge clk, negedge rst)
32 | begin
33 | if(!rst)
34 | bit_cnt <= 'b0;
35 | else if(!enable || (enable && bit_max && edge_max))
36 | bit_cnt <= 'b0;
37 | else if(edge_max)
38 | bit_cnt <= bit_cnt + 1'b1;
39 | end
40 |
41 | // flag assign statement
42 | assign edge_max = (edge_cnt == prescale - 1);
43 | assign bit_max = (parity_en)? (bit_cnt == 'b1010) : (bit_cnt == 'b1001);
44 |
45 | endmodule
46 |
--------------------------------------------------------------------------------
/BACKEND/Synthesis/clocks.rpt:
--------------------------------------------------------------------------------
1 |
2 | ****************************************
3 | Report : clocks
4 | Design : SYS_TOP
5 | Version: K-2015.06
6 | Date : Mon Sep 25 22:32:08 2023
7 | ****************************************
8 |
9 | Attributes:
10 | d - dont_touch_network
11 | f - fix_hold
12 | p - propagated_clock
13 | G - generated_clock
14 | g - lib_generated_clock
15 |
16 | Clock Period Waveform Attrs Sources
17 | --------------------------------------------------------------------------------
18 | ALU_CLK 10.00 {0 5} G {U0_ALU/CLK}
19 | REF_CLK 10.00 {0 5} {i_ref_clk}
20 | RX_CLK 270.00 {0 135} G {U0_UART_RX/i_clk}
21 | TX_CLK 8640.00 {0 4320} G {U0_UART_TX/CLK}
22 | UART_CLK 270.00 {0 135} {i_uart_clk}
23 | --------------------------------------------------------------------------------
24 |
25 | Generated Master Generated Master Waveform
26 | Clock Source Source Clock Modification
27 | --------------------------------------------------------------------------------
28 | ALU_CLK i_ref_clk {U0_ALU/CLK} REF_CLK divide_by(1)
29 | RX_CLK i_uart_clk {U0_UART_RX/i_clk}
30 | UART_CLK divide_by(1)
31 | TX_CLK i_uart_clk {U0_UART_TX/CLK}
32 | UART_CLK divide_by(32)
33 | --------------------------------------------------------------------------------
34 | 1
35 |
--------------------------------------------------------------------------------
/BACKEND/DFT/clocks.rpt:
--------------------------------------------------------------------------------
1 |
2 | ****************************************
3 | Report : clocks
4 | Design : SYS_TOP
5 | Version: K-2015.06
6 | Date : Mon Sep 25 23:00:27 2023
7 | ****************************************
8 |
9 | Attributes:
10 | d - dont_touch_network
11 | f - fix_hold
12 | p - propagated_clock
13 | G - generated_clock
14 | g - lib_generated_clock
15 |
16 | Clock Period Waveform Attrs Sources
17 | --------------------------------------------------------------------------------
18 | ALU_CLK 10.00 {0 5} G {U0_ALU/CLK}
19 | REF_CLK 10.00 {0 5} {i_ref_clk}
20 | RX_CLK 271.27 {0 135.633} G {U0_UART_RX/i_clk}
21 | SCAN_CLK 100.00 {0 50} {scan_clk}
22 | TX_CLK 8680.54 {0 4340.27} G {U0_UART_TX/CLK}
23 | UART_CLK 271.27 {0 135.633} {i_uart_clk}
24 | --------------------------------------------------------------------------------
25 |
26 | Generated Master Generated Master Waveform
27 | Clock Source Source Clock Modification
28 | --------------------------------------------------------------------------------
29 | ALU_CLK i_ref_clk {U0_ALU/CLK} REF_CLK divide_by(1)
30 | RX_CLK i_uart_clk {U0_UART_RX/i_clk}
31 | UART_CLK divide_by(1)
32 | TX_CLK i_uart_clk {U0_UART_TX/CLK}
33 | UART_CLK divide_by(32)
34 | --------------------------------------------------------------------------------
35 | 1
36 |
--------------------------------------------------------------------------------
/UART/UART TX/serializer.v:
--------------------------------------------------------------------------------
1 | module serializer #( parameter WIDTH = 8,
2 | COUNT_BITS = ($clog2(WIDTH)+1) )
3 | ( input wire [WIDTH-1:0] P_DATA,
4 | input wire ser_en,
5 | input wire CLK,
6 | input wire RST,
7 | output reg ser_data,
8 | output reg ser_done );
9 |
10 | reg [COUNT_BITS-1:0] counter; // combinational logic output counter
11 | reg [COUNT_BITS-1:0] counter_r; // sequential logic output counter
12 | reg [WIDTH-1:0] data;
13 |
14 | // serializer sequential always block
15 | always @(posedge CLK, negedge RST)
16 | begin
17 | if(!RST)
18 | begin
19 | ser_data <= 1'b1;
20 | data <= 'b0;
21 | end
22 | else if(!ser_en)
23 | begin
24 | ser_data <= 1'b1;
25 | data <= P_DATA;
26 | end
27 | else if(ser_en && !ser_done)
28 | {data[WIDTH-2:0],ser_data} <= data;
29 | end
30 |
31 | // counter sequential always block
32 | always @(posedge CLK, negedge RST)
33 | begin
34 | if(!RST)
35 | counter_r <= WIDTH;
36 | else
37 | counter_r <= counter;
38 | end
39 |
40 | // counter combinational always block
41 | always @(*)
42 | begin
43 | if(ser_en && counter_r)
44 | begin
45 | counter = counter_r - 1'b1;
46 | ser_done = 1'b0;
47 | end
48 | else if (ser_en && !counter_r)
49 | begin
50 | counter = 1'b0;
51 | ser_done = 1'b1;
52 | end
53 | else
54 | begin
55 | counter = WIDTH;
56 | ser_done = 1'b0;
57 | end
58 | end
59 | endmodule
--------------------------------------------------------------------------------
/Asynchronous FIFO/FIFO_MEM_CNTRL.v:
--------------------------------------------------------------------------------
1 | //******************************************************************************************//
2 | // Description: //
3 | // ------------ //
4 | // It's the FIFO memory buffer that is accessed by both the write and read clock domains. //
5 | // This buffer is most likely a synchronous dual-port RAM or register file //
6 | // //
7 | //******************************************************************************************//
8 |
9 | module FIFO_MEM_CNTRL #( parameter DATA_WIDTH = 8, parameter MEM_DEPTH = 8, parameter PTR_WIDTH = ($clog2(MEM_DEPTH)+1) )
10 | ( input wire [DATA_WIDTH-1:0] W_data ,
11 | input wire W_clk_en ,
12 | input wire [PTR_WIDTH-2:0] W_addr ,
13 | input wire [PTR_WIDTH-2:0] R_addr ,
14 | input wire W_clk ,
15 | input wire W_rst ,
16 | output wire [DATA_WIDTH-1:0] R_data );
17 |
18 | // FIFO Memory declaration
19 | reg [DATA_WIDTH-1:0] MEM [MEM_DEPTH-1:0];
20 |
21 | // control loop index
22 | integer i;
23 |
24 | // write-port memory
25 | always @(posedge W_clk or negedge W_rst)
26 | begin
27 | if(!W_rst)
28 | begin
29 | for(i = 0; i < MEM_DEPTH; i = i + 1)
30 | begin
31 | MEM[i] <= 'b0;
32 | end
33 | end
34 | else if(W_clk_en)
35 | MEM[W_addr] <= W_data;
36 | end
37 |
38 | // read-port memory
39 | assign R_data = MEM[R_addr];
40 | endmodule
41 |
42 |
--------------------------------------------------------------------------------
/Reset Synchronizer/README.md:
--------------------------------------------------------------------------------
1 | # Reset Synchronizer Block
2 |
3 | ## Overview
4 | The Reset Synchronizer block is a crucial component in our Low Power Configurable Multi-Clock Digital System design. It addresses the challenges associated with asynchronous reset signals by ensuring synchronized de-assertion with respect to the clock domain.
5 |
6 | ## Block Description
7 | In digital circuits, asynchronous reset signals can pose timing challenges during de-assertion, potentially violating the recovery and removal times of Flip-Flops. The Reset Synchronizer effectively manipulates the asynchronous reset signal to achieve synchronous de-assertion, enhancing the reliability of the reset operation.
8 |
9 | ## Block Interface
10 | The Reset Synchronizer block has the following interface:
11 |
12 | 
13 |
14 | - **Inputs:**
15 | - `RST`: Asynchronous reset signal that requires synchronization.
16 | - `CLK`: Clock signal for the sequential elements within the Reset Synchronizer.
17 |
18 | - **Outputs:**
19 | - `SYNC_RST`: The synchronized reset signal with controlled de-assertion timing.
20 |
21 | > For a better understanding of how the Reset Synchronizer block is implemented in RTL (Register-Transfer Level) code, please refer to the [`RESET_SYNC.v`](.RESET_SYNC.v) file in this repository.
22 |
23 | ## Parameterized Number of Synchronization Stages
24 | One notable feature of the Reset Synchronizer block is its parameterized number of synchronization stages. This flexibility allows you to adapt the block to your specific design requirements, ensuring optimal synchronization performance.
25 |
26 | ## [Testbench](./RST_SYNC_tb.v)
27 | 
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Asynchronous FIFO/FIFO_RD.v:
--------------------------------------------------------------------------------
1 | //******************************************************************************************//
2 | // Description: //
3 | // ------------ //
4 | // It is responsible for calculation of read address (raddr) and generation of empty flag //
5 | // //
6 | //******************************************************************************************//
7 |
8 | module FIFO_RD #( parameter PTR_WIDTH = 4 )
9 | ( input wire CLK ,
10 | input wire RST ,
11 | input wire rinc ,
12 | input wire [PTR_WIDTH-1:0] wptr_conv ,
13 | input wire [PTR_WIDTH-1:0] rptr_conv ,
14 | output reg [PTR_WIDTH-1:0] rptr ,
15 | output wire [PTR_WIDTH-2:0] raddr ,
16 | output reg empty );
17 |
18 | // empty flag declaration
19 | wire EMPTY_FLAG;
20 |
21 | // empty calculation always block
22 | always @(posedge CLK or negedge RST)
23 | begin
24 | if(!RST)
25 | empty <= 1'b1;
26 | else if(EMPTY_FLAG)
27 | empty <= 1'b1;
28 | else
29 | empty <= 1'b0;
30 | end
31 |
32 | // read address increment always block
33 | always @(posedge CLK or negedge RST)
34 | begin
35 | if(!RST)
36 | rptr <= 'b0;
37 | else if(!empty && rinc)
38 | rptr <= rptr + 1'b1;
39 | end
40 |
41 | // the read address is the LSBs of the pointer
42 | assign raddr = rptr[PTR_WIDTH-2:0];
43 |
44 | // empty flag condition
45 | assign EMPTY_FLAG = (rptr_conv == wptr_conv); //when both pointers, including the MSBs are equal
46 | endmodule
47 |
--------------------------------------------------------------------------------
/UART/UART RX/data_sampling.v:
--------------------------------------------------------------------------------
1 | module data_sampling #(
2 | parameter MAX_PRESCALE = 32 ,
3 | PRSC_WIDTH = ($clog2(MAX_PRESCALE)+1) )
4 | (
5 | input wire clk ,
6 | input wire rst ,
7 | input wire enable ,
8 | input wire serial_data ,
9 | input wire [PRSC_WIDTH-1:1] prescale ,
10 | input wire [PRSC_WIDTH-2:0] counter ,
11 | output wire sampled_bit );
12 |
13 | // internal signals
14 | reg first_sample, second_sample, third_sample; // sampled data
15 | wire [PRSC_WIDTH-1:0] sampling_1, sampling_2, sampling_3 ; // sampling time
16 |
17 | // sampling always block
18 | always @(posedge clk, negedge rst)
19 | begin
20 | if(!rst)
21 | begin
22 | first_sample <= 1'b0;
23 | second_sample <= 1'b0;
24 | third_sample <= 1'b0;
25 | end
26 | else if(enable)
27 | begin
28 | case(counter)
29 | sampling_1: first_sample <= serial_data;
30 | sampling_2: second_sample <= serial_data;
31 | sampling_3: third_sample <= serial_data;
32 | endcase
33 | end
34 | else
35 | begin
36 | first_sample <= 1'b0;
37 | second_sample <= 1'b0;
38 | third_sample <= 1'b0;
39 | end
40 | end
41 |
42 | // sampled data using Karnaugh map
43 | assign sampled_bit = (second_sample & third_sample) |
44 | (first_sample & third_sample) |
45 | (first_sample & second_sample);
46 |
47 | // calculate sampling time
48 | assign sampling_1 = (prescale)-1'b1;
49 | assign sampling_2 = (prescale) ;
50 | assign sampling_3 = (prescale)+1'b1;
51 |
52 | endmodule
53 |
--------------------------------------------------------------------------------
/Pulse Generator/README.md:
--------------------------------------------------------------------------------
1 | # Pulse Generator Block
2 |
3 | ## Overview
4 | The Pulse Generator block is a fundamental component in our Low Power Configurable Multi-Clock Digital System design. It serves the essential function of generating precise pulses based on control signals, enabling synchronized actions within our digital system.
5 |
6 | ## Block Description
7 | In digital systems, generating accurate and controlled pulses is crucial for synchronizing various operations. The Pulse Generator block efficiently creates pulses based on specific control signals, facilitating precise timing and coordination within the system.
8 |
9 | ## Block Interface
10 | The Pulse Generator block has the following interface:
11 |
12 |
13 |
14 |
15 |
16 | - **Inputs:**
17 | - `CLK`: Clock signal for the sequential elements within the Pulse Generator.
18 | - `RST`: Asynchronous active-low reset signal to initialize and clear the pulse generation process.
19 | - `LVL_SIGNAL`: Control signal that determines the pulse characteristics.
20 |
21 | - **Outputs:**
22 | - `PULSE_SIGNAL`: The generated pulse signal with controlled characteristics based on the `LVL_SIGNAL` input.
23 |
24 | > For a better understanding of how the Pulse Generator block is implemented in RTL (Register-Transfer Level) code, please refer to the [`PULSE_GEN.v`](.PULSE_GEN.v) file in this repository.
25 |
26 | ## Key Functionality
27 | The Pulse Generator block's primary function is to create precise pulses based on the `LVL_SIGNAL` input. It offers flexibility and control over pulse characteristics, making it an essential component for coordinating actions within our digital system.
28 |
29 | ## [Testbench](./PULSE_GEN_tb.v)
30 | 
31 |
--------------------------------------------------------------------------------
/Asynchronous FIFO/FIFO_WR.v:
--------------------------------------------------------------------------------
1 | //******************************************************************************************//
2 | // Description: //
3 | // ------------ //
4 | // It is responsible for calculation of write address (raddr) and generation of full flag //
5 | // //
6 | //******************************************************************************************//
7 |
8 | module FIFO_WR #( parameter PTR_WIDTH = 4 )
9 | ( input wire CLK ,
10 | input wire RST ,
11 | input wire winc ,
12 | input wire [PTR_WIDTH-1:0] wptr_conv ,
13 | input wire [PTR_WIDTH-1:0] rptr_conv ,
14 | output reg [PTR_WIDTH-1:0] wptr ,
15 | output wire [PTR_WIDTH-2:0] waddr ,
16 | output reg full );
17 |
18 | // full flag declaration
19 | wire FULL_FLAG;
20 |
21 | // full calculation always block
22 | always @(posedge CLK or negedge RST)
23 | begin
24 | if(!RST)
25 | full <= 1'b0;
26 | else if(FULL_FLAG)
27 | full <= 1'b1;
28 | else
29 | full <= 1'b0;
30 | end
31 |
32 | // write address increment always block
33 | always @(posedge CLK or negedge RST)
34 | begin
35 | if(!RST)
36 | wptr <= 'b0;
37 | else if(winc)
38 | wptr <= wptr + 1'b1;
39 | end
40 |
41 | // the write address is the LSBs of the pointer
42 | assign waddr = wptr[PTR_WIDTH-2:0];
43 |
44 | // empty flag condition
45 | assign FULL_FLAG = (rptr_conv[PTR_WIDTH-1] != wptr_conv[PTR_WIDTH-1])
46 | &&
47 | (rptr_conv[PTR_WIDTH-2] != wptr_conv[PTR_WIDTH-2])
48 | &&
49 | (rptr_conv[PTR_WIDTH-3:0] == wptr_conv[PTR_WIDTH-3:0]); //when both pointers, except the MSBs, are equal
50 | endmodule
51 |
--------------------------------------------------------------------------------
/UART/UART TX/UART_TX.v:
--------------------------------------------------------------------------------
1 | module UART_TX #( parameter WIDTH = 8 )
2 | ( input wire [WIDTH-1:0] P_DATA,
3 | input wire DATA_VALID,
4 | input wire PAR_EN,
5 | input wire PAR_TYP,
6 | input wire CLK,
7 | input wire RST,
8 | output wire TX_OUT,
9 | output wire Busy );
10 |
11 | // internal signals declaration
12 | wire ser_done;
13 | wire ser_data;
14 | wire ser_en;
15 | wire par_bit;
16 | wire [1:0] mux_sel;
17 |
18 |
19 | // module instantiations
20 | serializer U0_serializer ( .P_DATA(P_DATA),
21 | .ser_en(ser_en),
22 | .CLK(CLK),
23 | .RST(RST),
24 | .ser_data(ser_data),
25 | .ser_done(ser_done) );
26 |
27 | FSM U0_FSM ( .Data_Valid(DATA_VALID),
28 | .PAR_EN(PAR_EN),
29 | .ser_done(ser_done),
30 | .CLK(CLK),
31 | .RST(RST),
32 | .ser_en(ser_en),
33 | .busy(Busy),
34 | .mux_sel(mux_sel) );
35 |
36 |
37 | parity_calc U0_parity_calc ( .P_DATA(P_DATA),
38 | .PAR_TYP(PAR_TYP),
39 | .CLK(CLK),
40 | .RST(RST),
41 | .Data_Valid(!Busy),
42 | .PAR_EN(PAR_EN),
43 | .par_bit(par_bit) );
44 |
45 | MUX U0_MUX ( .start_bit(1'b0),
46 | .stop_bit(1'b1),
47 | .ser_data(ser_data),
48 | .par_bit(par_bit),
49 | .mux_sel(mux_sel),
50 | .TX_OUT(TX_OUT) );
51 | endmodule
--------------------------------------------------------------------------------
/ALU/ALU.v:
--------------------------------------------------------------------------------
1 |
2 | module ALU #( parameter OPRND_WIDTH = 8, OUT_WIDTH = 2 * OPRND_WIDTH, CTRL_WIDTH = 4)
3 | ( input wire CLK , // Clock Signal
4 | input wire RST , // Active Low Reset
5 | input wire Enable , // ALU Enable
6 | input wire [OPRND_WIDTH-1:0] A , // Operand A
7 | input wire [OPRND_WIDTH-1:0] B , // Operand B
8 | input wire [ CTRL_WIDTH-1:0] ALU_FUN , // ALU Function
9 | output reg [ OUT_WIDTH-1:0] ALU_OUT , // ALU Result
10 | output reg OUT_VALID ); // ALU Result Valid
11 |
12 | // calculated result
13 | reg [OUT_WIDTH-1:0] ALU_RESULT;
14 |
15 | // combinational always block implementing gate-level ALU
16 | always @(*)
17 | begin
18 | if(Enable)
19 | case(ALU_FUN)
20 | // arithmatic cases
21 | 4'b0000: ALU_RESULT = A + B; // adition
22 | 4'b0001: ALU_RESULT = A - B; // subtraction
23 | 4'b0010: ALU_RESULT = A * B; // multiplication
24 | 4'b0011: ALU_RESULT = A / B; // division
25 |
26 | // logical cases
27 | 4'b0100: ALU_RESULT = A & B; // AND
28 | 4'b0101: ALU_RESULT = A | B; // OR
29 | 4'b0110: ALU_RESULT = ~(A & B); // NAND
30 | 4'b0111: ALU_RESULT = ~(A | B); // NOR
31 |
32 | // comparsion cases
33 | 4'b1000: ALU_RESULT = 'b0;
34 | 4'b1001: ALU_RESULT = (A==B)? 'd1:'d0;
35 | 4'b1010: ALU_RESULT = (A>B)? 'd2:'d0;
36 | 4'b1011: ALU_RESULT = (A>1; // shift A right
40 | 4'b1101: ALU_RESULT = A<<1; // shift A left
41 | 4'b1110: ALU_RESULT = B>>1; // shift B right
42 | 4'b1111: ALU_RESULT = B<<1; // shift B left
43 |
44 | default: ALU_RESULT = 'b0;
45 | endcase
46 | else
47 | ALU_RESULT = 'b0;
48 | end
49 |
50 | // registering the alu out
51 | always @(posedge CLK or negedge RST)
52 | begin
53 | if(!RST)
54 | begin
55 | ALU_OUT <= 'b0;
56 | OUT_VALID <= 1'b0;
57 | end
58 | else if(Enable)
59 | begin
60 | ALU_OUT <= ALU_RESULT;
61 | OUT_VALID <= 1'b1;
62 | end
63 | end
64 | endmodule
65 |
--------------------------------------------------------------------------------
/Pulse Generator/PULSE_GEN_tb.v:
--------------------------------------------------------------------------------
1 | module PULSE_GEN_tb ();
2 |
3 | /*******************************************************************/
4 | ///////////////////// TB Signals Declaration ////////////////////////
5 | /*******************************************************************/
6 | parameter CLK_PERIOD = 10, HALF_PERIOD = 5;
7 | parameter HIGH = 1, LOW = 0;
8 |
9 |
10 | // interface ports
11 | reg CLK ;
12 | reg RST ;
13 | reg LVL_SIG ;
14 | wire PULSE_SIG ;
15 |
16 | /*******************************************************************/
17 | ////////////////////////// Initial Block ////////////////////////////
18 | /*******************************************************************/
19 | initial
20 | begin
21 | $dumpfile(".vcd");
22 | $dumpvars;
23 |
24 | initialize();
25 | reset();
26 |
27 | LVL_SIG = HIGH;
28 |
29 | #(3*CLK_PERIOD);
30 | LVL_SIG = LOW;
31 | #CLK_PERIOD
32 | #2
33 | LVL_SIG = HIGH;
34 |
35 | #(3*CLK_PERIOD);
36 | LVL_SIG = LOW;
37 | #CLK_PERIOD
38 | #5
39 | LVL_SIG = HIGH;
40 | #(3*CLK_PERIOD) $stop;
41 | end
42 |
43 | /*******************************************************************/
44 | ////////////////////////////// TASKS ////////////////////////////////
45 | /*******************************************************************/
46 | task reset;
47 | begin
48 | RST = LOW;
49 | #HALF_PERIOD
50 | RST = HIGH;
51 | #HALF_PERIOD;
52 | end
53 | endtask
54 | /********************************/
55 | task initialize;
56 | begin
57 | CLK = LOW;
58 | RST = LOW;
59 | LVL_SIG = LOW;
60 | end
61 | endtask
62 | /********************************/
63 |
64 | /*******************************************************************/
65 | ///////////////////////// Clock Generator ///////////////////////////
66 | /*******************************************************************/
67 | always #HALF_PERIOD CLK = ~CLK;
68 |
69 | /*******************************************************************/
70 | //////////////////////// DUT Instantiation //////////////////////////
71 | /*******************************************************************/
72 | PULSE_GEN DUT (
73 | .CLK(CLK) ,
74 | .RST(RST) ,
75 | .LVL_SIG(LVL_SIG) ,
76 | .PULSE_SIG(PULSE_SIG) );
77 |
78 | endmodule
79 |
--------------------------------------------------------------------------------
/Clock Gate/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Clock Gate Block
3 |
4 | ## Overview
5 | The Clock Gate block plays a pivotal role in my Low Power Configurable Multi-Clock Digital System design. It employs the widely adopted technique of Clock Gating to efficiently reduce dynamic power consumption by selectively disabling the clock signal during idle periods.
6 |
7 | ## Block Description
8 | In modern digital systems, optimizing power consumption is paramount. The Clock Gate block offers an effective solution by allowing me to control the clock signal, turning it off when a specific block is in an idle state.
9 |
10 | ## Block Interface
11 | The Clock Gate block has the following interface:
12 |
13 | 
14 |
15 | - **Inputs:**
16 | - `CLK_EN`: Clock Enable signal, determining whether the clock should be gated or not.
17 | - `CLK`: The primary clock signal.
18 |
19 | - **Outputs:**
20 | - `GATED_CLK`: The clock signal, gated or disabled when `CLK_EN` indicates an idle state.
21 |
22 | > To gain a deeper insight into how the Clock Gate block is implemented in RTL (Register-Transfer Level) code, please refer to the [`ClkGate.v`](.ClkGate.v) file in this repository.
23 |
24 | ## Key Functionality
25 | The Clock Gate block's primary function is to efficiently manage power consumption by controlling the clock signal based on the `CLK_EN` input. This enables me to reduce dynamic power consumption during idle periods of specific blocks within my digital system.
26 |
27 | ## Understanding the RTL code
28 | For a detailed understanding of how the Clock Gate is implemented in Verilog, please refer to the [`ClkGate.v`](.ClkGate.v) file in this repository.
29 | - the Clock Gating Cell is implemented using a LATCH and an AND gate, but due to wire delay, it might cause errors. thus, the RTL code is used only in simulation as there's no wire delay in simulation. but during synthesis this design is replaced by ICG (integrated clock gating) full custom standard cell, which resolves the problem of wire delay
30 | - My code uses generated case statement to define the modelling of the cell, depending on the current stage of the flow, whether we're at the RTL designing phase or we're at the synthesis phase
31 |
32 | ## [Testbench](./ClkGate_tb.v)
33 | 
34 |
--------------------------------------------------------------------------------
/Register File/RegFile.v:
--------------------------------------------------------------------------------
1 | module RegFile #( parameter BUS_WIDTH = 8, DEPTH = 8, ADDR_WIDTH = 4, PAR_EN = 1, PAR_TYPE = 0, PRESCALE = 32, DIV_RATIO = 32 )
2 | ( input wire CLK , // Clock Signal
3 | input wire RST , // Active Low Reset
4 | input wire WrEn , // Write Enable
5 | input wire RdEn , // Read Enable
6 | input wire [ADDR_WIDTH-1:0] Address , // Address bus
7 | input wire [BUS_WIDTH-1 :0] WrData , // Write Data Bus
8 | output wire [BUS_WIDTH-1 :0] REG0 , // Register at Address 0x0
9 | output wire [BUS_WIDTH-1 :0] REG1 , // Register at Address 0x1
10 | output wire [BUS_WIDTH-1 :0] REG2 , // Register at Address 0x2
11 | output wire [BUS_WIDTH-1 :0] REG3 , // Register at Address 0x3
12 | output reg [BUS_WIDTH-1 :0] RdData , // Read Data Bus
13 | output reg RdData_Valid ); // Read Data Valid
14 |
15 | // Memory declaration
16 | reg [BUS_WIDTH-1:0] MEM [DEPTH-1:0];
17 |
18 | // control loop index
19 | integer i;
20 |
21 | // sequential always block
22 | always @(posedge CLK or negedge RST)
23 | begin
24 | if(!RST)
25 | begin : MEMORY_CLEARING
26 | for(i = 0; i < DEPTH; i = i + 1)
27 | begin
28 | if(i == 2)
29 | begin
30 | MEM[i][0] <= PAR_EN;
31 | MEM[i][1] <= PAR_TYPE;
32 | MEM[i][7:2] <= PRESCALE;
33 | end
34 | else if(i == 3)
35 | MEM[i][7:0] <= DIV_RATIO;
36 | else
37 | MEM[i] <= 'b0;
38 | end
39 | RdData <= 'b0;
40 | RdData_Valid <= 1'b0;
41 | end
42 |
43 | else if (WrEn && !RdEn)
44 | begin : WRITING
45 | MEM[Address] <= WrData;
46 | end
47 |
48 | else if (!WrEn && RdEn)
49 | begin : READING
50 | RdData <= MEM[Address];
51 | RdData_Valid <= 1'b1;
52 | end
53 |
54 | else
55 | begin : NOT_READING
56 | RdData_Valid <= 1'b0;
57 | end
58 | end
59 |
60 | // assign statements
61 | assign REG0 = MEM['h0];
62 | assign REG1 = MEM['h1];
63 | assign REG2 = MEM['h2];
64 | assign REG3 = MEM['h3];
65 |
66 | endmodule
--------------------------------------------------------------------------------
/Clock Divider/README.md:
--------------------------------------------------------------------------------
1 | # Clock Divider (Frequency Divider) Block
2 |
3 | ## Overview
4 | The Clock Divider (Frequency Divider) block is a vital component within our Low Power Configurable Multi-Clock Digital System. Its purpose is to take an input clock signal of a certain frequency and generate an output clock signal with a different frequency, achieving frequency division as needed.
5 |
6 | ## Block Description
7 | In digital systems, managing clock frequencies is crucial for proper operation. The Clock Divider block provides the capability to divide the input clock frequency to match the specific requirements of our digital design.
8 |
9 | ## Block Interface
10 | The Clock Divider block has the following interface:
11 |
12 |
13 |
14 |
15 |
16 | - **Inputs:**
17 | - `I_ref_clk`: Reference clock frequency input.
18 | - `I_rst_n`: Active-low asynchronous reset signal.
19 | - `I_clk_en`: Clock Divider Block Enable signal.
20 | - `I_div_ratio`: The desired divided ratio (an integer value).
21 |
22 | - **Output:**
23 | - `o_div_clk`: The generated clock signal with the divided or multiplied frequency.
24 |
25 | > For a detailed look at the Verilog implementation of the Clock Divider block, please refer to the [`ClkDiv.v`](./ClkDiv.v) file in this repository.
26 |
27 | ## Key Functionality
28 | The Clock Divider block's primary function is to adjust the clock period based on the input divided ratio. This flexibility ensures that our digital system operates with the precise timing required for its various components.
29 |
30 | ## Expected Waveforms
31 | 
32 |
33 | ## [Testbench](./ClkDiv_tb.v)
34 | 
35 |
36 | ```
37 | # [PASSED]: div ratio = 0, clock period = 10ns, div clock period = 10ns
38 | # [PASSED]: div ratio = 1, clock period = 10ns, div clock period = 10ns
39 | # [PASSED]: div ratio = 2, clock period = 10ns, div clock period = 20ns
40 | # [PASSED]: div ratio = 3, clock period = 10ns, div clock period = 30ns
41 | # [PASSED]: div ratio = 4, clock period = 10ns, div clock period = 40ns
42 | # [PASSED]: div ratio = 5, clock period = 10ns, div clock period = 50ns
43 | # [PASSED]: div ratio = 6, clock period = 10ns, div clock period = 60ns
44 | # [PASSED]: div ratio = 7, clock period = 10ns, div clock period = 70ns
45 | # [PASSED]: div ratio = 8, clock period = 10ns, div clock period = 80ns
46 | # [PASSED]: div ratio = 9, clock period = 10ns, div clock period = 90ns
47 | ```
48 |
49 |
--------------------------------------------------------------------------------
/Reset Synchronizer/RST_SYNC_tb.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/10ps
2 | /*******************************************************************/
3 | // To try different No. of Stages,
4 | // you can changes the parameter values in line 15 and re-run
5 | /*******************************************************************/
6 |
7 | module RST_SYNC_tb();
8 |
9 |
10 | /*******************************************************************/
11 | ///////////////////// TB Signals Declaration ////////////////////////
12 | /*******************************************************************/
13 | parameter CLK_PERIOD = 10 , HALF_PERIOD = 5;
14 | parameter HIGH = 1 , LOW = 0;
15 | parameter NUM_STAGES = 2;
16 |
17 | defparam DUT.NUM_STAGES = NUM_STAGES;
18 |
19 |
20 | // interface ports
21 | reg CLK ;
22 | reg RST ;
23 | wire SYNC_RST ;
24 |
25 | /*******************************************************************/
26 | ////////////////////////// Initial Block ////////////////////////////
27 | /*******************************************************************/
28 | initial
29 | begin
30 | $dumpfile("BIT_SYNC.vcd");
31 | $dumpvars;
32 |
33 | initialize();
34 | reset();
35 |
36 | latency_test();
37 |
38 | #(2*CLK_PERIOD) $stop;
39 | end
40 |
41 | /*******************************************************************/
42 | ////////////////////////////// TASKS ////////////////////////////////
43 | /*******************************************************************/
44 | task reset;
45 | begin
46 | RST = LOW;
47 | #HALF_PERIOD
48 | RST = HIGH;
49 | #HALF_PERIOD;
50 | end
51 | endtask
52 | /********************************/
53 | task initialize;
54 | begin
55 | CLK = LOW;
56 | RST = HIGH;
57 | end
58 | endtask
59 | /********************************/
60 | task latency_test;
61 | integer first_time, second_time, period;
62 | begin
63 | #(3*CLK_PERIOD)
64 | @(posedge CLK)
65 | //#(0.2*CLK_PERIOD)
66 | RST = LOW;
67 | @(negedge CLK)
68 | #(0.9*HALF_PERIOD);
69 | RST = HIGH;
70 | end
71 | endtask
72 |
73 | /*******************************************************************/
74 | ///////////////////////// Clock Generator ///////////////////////////
75 | /*******************************************************************/
76 | always #HALF_PERIOD CLK = ~CLK;
77 |
78 | /*******************************************************************/
79 | //////////////////////// DUT Instantiation //////////////////////////
80 | /*******************************************************************/
81 | RST_SYNC DUT ( .CLK (CLK) ,
82 | .RST (RST) ,
83 | .SYNC_RST (SYNC_RST) );
84 |
85 | endmodule
--------------------------------------------------------------------------------
/Clock Divider/ClkDiv.v:
--------------------------------------------------------------------------------
1 | module ClkDiv #( parameter RATIO_WIDTH = 8 )
2 | ( input wire i_ref_clk ,
3 | input wire i_rst_n ,
4 | input wire i_clk_en ,
5 | input wire [RATIO_WIDTH-1:0] i_div_ratio ,
6 | output reg o_div_clk );
7 |
8 | reg flag; // for non-50% duty cycle in case of odd ratio
9 | reg div_clk;
10 | reg [RATIO_WIDTH-1:0] counter;
11 |
12 | wire [RATIO_WIDTH-1:0] half;
13 | wire CLK_DIV_EN; // the actual enable signal for the divider
14 | wire odd; // defining the type of the ratio
15 | wire even_toggle; // condition when the even ratio toggles
16 | wire odd_toggle_high; // condition when the odd ratio toggles HL
17 | wire odd_toggle_low; // condition when the odd ratio toggles LH
18 | wire toggling_conditions; // conditions of toggeling combined
19 |
20 |
21 | // generating for ratio = 0 or 1
22 | always @(*)
23 | begin
24 | if(CLK_DIV_EN)
25 | o_div_clk = div_clk;
26 | else
27 | o_div_clk = i_ref_clk;
28 | end
29 |
30 | // sequential always block
31 | always @(posedge i_ref_clk, negedge i_rst_n)
32 | begin
33 | // reset state
34 | if(!i_rst_n) begin
35 | div_clk <= 0;
36 | counter <= 0;
37 | flag <= 0;
38 | end
39 | // enabled state
40 | else if(CLK_DIV_EN)
41 | begin
42 | if(toggling_conditions)
43 | begin
44 | div_clk <= ~div_clk;
45 | flag <= ~flag;
46 | counter <= 'b0;
47 | end
48 | else
49 | begin
50 | counter <= counter+1'b1;
51 | end
52 | end
53 |
54 | // not enabled state
55 | else
56 | begin
57 | div_clk <= 'b0;
58 | end
59 | end
60 |
61 | // corner case resolve
62 | assign CLK_DIV_EN = (i_clk_en && // if clock divider is enabled
63 | (i_div_ratio != 'b0) && // if the divider ratio not equal zero
64 | (i_div_ratio != 'b1) ); // if the divider ratio not equal one
65 |
66 | // whether the ratio odd or even
67 | assign odd = (i_div_ratio[0]);
68 |
69 | // whether the counter reaches half of the ratio
70 | assign half = (i_div_ratio/2) - 'b1;
71 |
72 | assign even_toggle = (!odd) && (counter == half);
73 | assign odd_toggle_high = (odd) && (flag) && (counter == half);
74 | assign odd_toggle_low = (odd) && (!flag) &&( counter == (half+'b1));
75 | assign toggling_conditions = even_toggle || odd_toggle_high || odd_toggle_low;
76 |
77 | endmodule
78 |
79 |
80 |
--------------------------------------------------------------------------------
/Asynchronous FIFO/ASYNC_FIFO.v:
--------------------------------------------------------------------------------
1 | module ASYNC_FIFO #( parameter DATA_WIDTH = 8, parameter MEM_DEPTH = 8, parameter PTR_WIDTH = ($clog2(MEM_DEPTH)+1) )
2 | ( input wire i_Wclk ,
3 | input wire i_Wrst_n ,
4 | input wire i_Winc ,
5 | input wire i_Rclk ,
6 | input wire i_Rrst_n ,
7 | input wire i_Rinc ,
8 | input wire [DATA_WIDTH-1:0] i_Wdata ,
9 | output wire o_full ,
10 | output wire [DATA_WIDTH-1:0] o_Rdata ,
11 | output wire o_empty );
12 |
13 | // internal signal declaration
14 | wire [PTR_WIDTH-2:0] x_waddr , x_raddr;
15 | wire [PTR_WIDTH-1:0] x_wptr , x_rptr;
16 | wire [PTR_WIDTH-1:0] x_wptr_conv , x_rptr_conv;
17 | wire [PTR_WIDTH-1:0] x_wq2_rptr , x_rq2_wptr;
18 |
19 | // FIFO memory buffer
20 | FIFO_MEM_CNTRL #( .DATA_WIDTH(DATA_WIDTH), .MEM_DEPTH(MEM_DEPTH), .PTR_WIDTH(PTR_WIDTH) ) U0_FIFO_MEM_CNTRL (
21 | .W_clk_en ((!o_full)&i_Winc) ,
22 | .W_data (i_Wdata) ,
23 | .W_addr (x_waddr) ,
24 | .W_clk (i_Wclk) ,
25 | .W_rst (i_Wrst_n) ,
26 | .R_data (o_Rdata) ,
27 | .R_addr (x_raddr) );
28 |
29 | // FIFO empty and read address generator
30 | FIFO_RD #( .PTR_WIDTH(PTR_WIDTH) ) U0_FIFO_RD (
31 | .CLK (i_Rclk) ,
32 | .RST (i_Rrst_n) ,
33 | .rinc (i_Rinc) ,
34 | .wptr_conv (x_rq2_wptr) ,
35 | .rptr_conv (x_rptr_conv) ,
36 | .rptr (x_rptr) ,
37 | .raddr (x_raddr) ,
38 | .empty (o_empty) );
39 |
40 | // FIFO full and write address generator
41 | FIFO_WR #( .PTR_WIDTH(PTR_WIDTH) ) U0_FIFO_WR (
42 | .CLK (i_Wclk) ,
43 | .RST (i_Wrst_n) ,
44 | .winc (i_Winc) ,
45 | .wptr_conv (x_wptr_conv) ,
46 | .rptr_conv (x_wq2_rptr) ,
47 | .wptr (x_wptr) ,
48 | .waddr (x_waddr) ,
49 | .full (o_full) );
50 |
51 | // Write-to-Read Synchronizer
52 | DF_SYNC #(.BUS_WIDTH(PTR_WIDTH)) U0_DF_SYNC (
53 | .CLK (i_Rclk) ,
54 | .RST (i_Rrst_n) ,
55 | .ASYNC (x_wptr_conv) ,
56 | .SYNC (x_rq2_wptr) );
57 |
58 | // Read-to-Write Synchronizer
59 | DF_SYNC #(.BUS_WIDTH(PTR_WIDTH)) U1_DF_SYNC (
60 | .CLK (i_Wclk) ,
61 | .RST (i_Wrst_n) ,
62 | .ASYNC (x_rptr_conv) ,
63 | .SYNC (x_wq2_rptr) );
64 |
65 | // Write-PTR Gray Converter
66 | GRAY_CONV #(.PTR_WIDTH(PTR_WIDTH)) U0_GRAY_CONV (
67 | .bit_ptr (x_wptr) ,
68 | .gray_ptr (x_wptr_conv) );
69 |
70 | // Read-PTR Gray Converter
71 | GRAY_CONV #(.PTR_WIDTH(PTR_WIDTH)) U1_GRAY_CONV (
72 | .bit_ptr (x_rptr) ,
73 | .gray_ptr (x_rptr_conv) );
74 |
75 | endmodule
76 |
--------------------------------------------------------------------------------
/Data Synchronizer/README.md:
--------------------------------------------------------------------------------
1 | # Data Synchronizer Block
2 |
3 | ## Overview
4 | The Data Synchronizer block is a critical component in our multi-clock domain mini-processor design. It plays a vital role in managing data synchronization across different clock domains, solving the complex challenge of Clock Domain Crossing (CDC).
5 |
6 | ## Block Description
7 | The Data Synchronizer employs a Synchronized MUX-Select Synchronization Scheme, which effectively synchronizes multiple bits and ensures reliable data transfer between asynchronous clock domains.
8 |
9 | ## Block Interface
10 | The Data Synchronizer block has the following interface:
11 |
12 |
13 |
14 |
15 |
16 | - **Inputs:**
17 | - `unsync_bus`: The unsynchronized data bus to be synchronized across clock domains.
18 | - `bus_enable`: Control signal indicating when data synchronization is required.
19 | - `CLK`: Clock signal for the sequential elements within the Data Synchronizer.
20 | - `RST`: Asynchronous active-low reset signal to clear the internal state.
21 |
22 | - **Outputs:**
23 | - `sync_bus`: The synchronized data bus, ensuring that data arrives reliably in the destination clock domain.
24 | - `enable_pulse`: Control signal indicating the synchronization process has occurred, enabling subsequent actions in the design.
25 |
26 | > For a better understanding of how the Data Synchronizer block is implemented in RTL (Register-Transfer Level) code, please refer to the [`DATA_SYNC.v`](.DATA_SYNC.v) file in this repository.
27 |
28 | ## Elaborated Design
29 | The Data Synchronizer block comprises the following key components:
30 |
31 | ### Multi Flip-Flop Enable Synchronizer ([multi_ff.v](./multi_ff.v))
32 | This component ensures that data is correctly synchronized across clock domains while minimizing metastability issues.
33 |
34 | 
35 |
36 | ### Pulse Generator Block ([DS_PULSE.v](./DS_PULSE.v))
37 | Responsible for generating a pulse signal (`enable_pulse`) that signifies the successful synchronization of data.
38 |
39 | 
40 |
41 | ## Synchronized MUX-Select Synchronization Scheme ([sync_bus.v](./sync_bus.v))
42 | The Data Synchronizer employs a unique synchronization scheme that overcomes Clock Domain Crossing challenges. This scheme ensures data integrity and consistency between different clock domains, making it a crucial component in our design.
43 |
44 | 
45 |
46 | ## [Testbench](./DATA_SYNC_tb.v)
47 |
48 | 
49 |
50 | ```
51 | [PASSED] Bus Width = 8, No. of Stages = 2
52 | ```
53 |
--------------------------------------------------------------------------------
/UART/UART TX/FSM.v:
--------------------------------------------------------------------------------
1 | module FSM #( parameter WIDTH = 8 )
2 | ( input wire Data_Valid,
3 | input wire PAR_EN,
4 | input wire ser_done,
5 | input wire CLK,
6 | input wire RST,
7 | output reg ser_en,
8 | output reg busy,
9 | output reg [1:0] mux_sel );
10 |
11 | // FSM States Registers
12 | reg [2:0] current_state, next_state;
13 |
14 | // state encoding
15 | localparam IDLE = 3'b000;
16 | localparam start_bit = 3'b001;
17 | localparam ser_data = 3'b010;
18 | localparam parity_bit = 3'b011;
19 | localparam stop_bit = 3'b100;
20 |
21 | // mux selector encoding
22 | localparam mux_start = 2'b00;
23 | localparam mux_serial = 2'b01;
24 | localparam mux_parity = 2'b10;
25 | localparam mux_stop = 2'b11;
26 |
27 | // state transition always block
28 | always @(posedge CLK, negedge RST)
29 | begin
30 | if(!RST)
31 | current_state <= IDLE;
32 | else
33 | current_state <= next_state;
34 | end
35 |
36 | // next state logic always block
37 | always @(*)
38 | begin
39 | case(current_state)
40 | IDLE: begin
41 | if(Data_Valid)
42 | next_state = start_bit;
43 | else
44 | next_state = IDLE;
45 | end
46 | start_bit: begin
47 | next_state = ser_data;
48 | end
49 | ser_data: begin
50 | if(ser_done)
51 | begin
52 | if(PAR_EN)
53 | next_state = parity_bit;
54 | else
55 | next_state = stop_bit;
56 | end
57 | else
58 | next_state = ser_data;
59 | end
60 | parity_bit: begin
61 | next_state = stop_bit;
62 | end
63 | stop_bit: begin
64 | // This condition allows the UART TX to receive two successive bytes or more without returning to IDLE
65 | /*if(Data_Valid):
66 | next_state = start_bit;
67 | else*/
68 | next_state = IDLE;
69 | end
70 | default begin
71 | next_state = IDLE;
72 | end
73 | endcase
74 | end
75 |
76 | // output logic always block
77 | always @(*)
78 | begin
79 | case(current_state)
80 | IDLE: begin
81 | busy = 1'b0;
82 | ser_en = 1'b0;
83 | mux_sel = mux_stop;
84 | end
85 | start_bit: begin
86 | busy = 1'b1;
87 | ser_en = 1'b1;
88 | mux_sel = mux_start;
89 | end
90 | ser_data: begin
91 | busy = 1'b1;
92 | ser_en = 1'b1;
93 | mux_sel = mux_serial;
94 | end
95 | parity_bit: begin
96 | busy = 1'b1;
97 | ser_en = 1'b0;
98 | mux_sel = mux_parity;
99 | end
100 | stop_bit: begin
101 | busy = 1'b1;
102 | ser_en = 1'b0;
103 | mux_sel = mux_stop;
104 | end
105 | default begin
106 | busy = 1'b0;
107 | ser_en = 1'b0;
108 | mux_sel = mux_stop;
109 | end
110 | endcase
111 | end
112 | endmodule
113 |
--------------------------------------------------------------------------------
/Data Synchronizer/DATA_SYNC_tb.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ns
2 | /*******************************************************************/
3 | // To try different Bus Width & No. of Stages,
4 | // you can changes the parameter values in line 15 and re-run
5 | /*******************************************************************/
6 |
7 | module DATA_SYNC_tb();
8 |
9 |
10 | /*******************************************************************/
11 | ///////////////////// TB Signals Declaration ////////////////////////
12 | /*******************************************************************/
13 | parameter CLK_PERIOD = 10 , HALF_PERIOD = 5;
14 | parameter HIGH = 1 , LOW = 0;
15 | parameter BUS_WIDTH = 8 , NUM_STAGES = 2;
16 |
17 | defparam DUT.BUS_WIDTH = BUS_WIDTH;
18 | defparam DUT.NUM_STAGES = NUM_STAGES;
19 |
20 |
21 | // interface ports
22 | reg CLK ;
23 | reg RST ;
24 | reg bus_enable ;
25 | reg [BUS_WIDTH-1:0] unsync_bus ;
26 | wire [BUS_WIDTH-1:0] sync_bus ;
27 | wire enable_bus ;
28 |
29 | // test value
30 | reg [BUS_WIDTH-1:0] test_var;
31 |
32 |
33 | /*******************************************************************/
34 | ////////////////////////// Initial Block ////////////////////////////
35 | /*******************************************************************/
36 | initial
37 | begin
38 | $dumpfile("BIT_SYNC.vcd");
39 | $dumpvars;
40 |
41 | initialize();
42 | reset();
43 |
44 | test_var = 'haa;
45 | latency_test(test_var);
46 |
47 | #(2*CLK_PERIOD) $stop;
48 | end
49 |
50 | /*******************************************************************/
51 | ////////////////////////////// TASKS ////////////////////////////////
52 | /*******************************************************************/
53 | task reset;
54 | begin
55 | RST = LOW;
56 | #HALF_PERIOD
57 | RST = HIGH;
58 | #HALF_PERIOD;
59 | end
60 | endtask
61 | /********************************/
62 | task initialize;
63 | begin
64 | CLK = HIGH;
65 | RST = HIGH;
66 | bus_enable = LOW;
67 | unsync_bus = LOW;
68 | end
69 | endtask
70 | /********************************/
71 | task latency_test;
72 | input [BUS_WIDTH-1:0] test_value;
73 |
74 | begin
75 | reset();
76 | @(posedge CLK)
77 | //#(0.3*CLK_PERIOD)
78 | unsync_bus = test_value;
79 | bus_enable = HIGH;
80 | #CLK_PERIOD
81 | #(NUM_STAGES*CLK_PERIOD)
82 | #HALF_PERIOD
83 |
84 | if(sync_bus == test_value)
85 | $display("[PASSED] Bus Width = %0d, No. of Stages = %0d",BUS_WIDTH,NUM_STAGES);
86 | else
87 | $display("[FAILED] Bus Width = %0d, No. of Stages = %0d",BUS_WIDTH,NUM_STAGES);
88 | end
89 | endtask
90 |
91 | /*******************************************************************/
92 | ///////////////////////// Clock Generator ///////////////////////////
93 | /*******************************************************************/
94 | always #HALF_PERIOD CLK = ~CLK;
95 |
96 | /*******************************************************************/
97 | //////////////////////// DUT Instantiation //////////////////////////
98 | /*******************************************************************/
99 | DATA_SYNC DUT (
100 | .dest_clk (CLK) ,
101 | .dest_rst (RST) ,
102 | .bus_enable (bus_enable) ,
103 | .unsync_bus (unsync_bus) ,
104 | .sync_bus (sync_bus) ,
105 | .enable_pulse (enable_bus) );
106 |
107 | endmodule
108 |
--------------------------------------------------------------------------------
/System Controller/README.md:
--------------------------------------------------------------------------------
1 | # System Controller Block
2 |
3 | ## Overview
4 | The System Controller is the central hub of our Low Power Configurable Multi-Clock Digital System. It orchestrates various operations based on commands received from the master via the UART_RX interface and ensures the results are communicated back to the master through the UART_TX interface. This versatile component handles a wide range of operations, including ALU and Register File operations.
5 |
6 | ## Block Description
7 | The System Controller is the brain behind our digital system, responsible for interpreting and executing a multitude of commands from the master. These commands encompass ALU operations, Register File operations, and more.
8 |
9 | ## Supported Operations
10 | The System Controller supports a comprehensive set of operations, including but not limited to:
11 | - Arithmetic and Logic Unit (ALU) Operations:
12 | - Addition
13 | - Subtraction
14 | - Multiplication
15 | - Division
16 | - Logical Operations (AND, OR, NAND, NOR, XOR, XNOR)
17 | - Comparisons (A = B, A > B)
18 | - Bit Shifting (A >> 1, A << 1)
19 | - Register File Operations:
20 | - Register File Write
21 | - Register File Read
22 |
23 | ## Supported Commands
24 | To execute these operations, the System Controller interprets various commands, including:
25 | 1. Register File Write Command (3 frames)
26 | 2. Register File Read Command (2 frames)
27 | 3. ALU Operation Command with Operand (4 frames)
28 | 4. ALU Operation Command with No Operand (2 frames)
29 |
30 | ## Operation Workflow
31 | The workflow of the System Controller is as follows:
32 | 1. The master (testbench) sends different commands (Register File Operations, ALU Operations) via UART_RX.
33 | 2. The System Controller receives these command frames.
34 | 3. The System Controller processes the commands, performing the requested operations using the ALU and Register File.
35 | 4. Once the operation is completed, the System Controller sends the result back to the master through UART_TX.
36 |
37 | ## Block Interface
38 |
39 | 
40 | > Not all the ports are included in the photo
41 |
42 | ### Inputs
43 |
44 | The System Controller block receives the following inputs:
45 |
46 | - **Clock and Reset Signals:**
47 | - `CLK`: The Clock Signal.
48 | - `RST`: Active Low Reset.
49 |
50 | - **ALU Inputs:**
51 | - `ALU_OUT`: ALU Result Bus (Width: ALU_WIDTH).
52 | - `OUT_Valid`: ALU Result Valid Signal.
53 |
54 | - **UART_RX Inputs:**
55 | - `RX_P_Data`: UART_RX Data Bus (Width: DATA_BUS_WIDTH).
56 | - `RX_D_VLD`: RX Data Valid Signal.
57 |
58 | - **Register File Inputs:**
59 | - `RdData`: Read Data Bus (Width: DATA_BUS_WIDTH).
60 | - `RdData_Valid`: Read Data Valid Signal.
61 |
62 | - **Clock Divider and Prescale Configuration:**
63 | - `Prescale_RX`: Configuration for Prescale Values (Width: DATA_BUS_WIDTH-3).
64 | - `FIFO_FULL`: FIFO Full Flag Signal.
65 |
66 | - **ALU Control Signals:**
67 | - `ALU_EN`: ALU Enable Signal.
68 | - `ALU_FUN`: ALU Function Signal (Width: ALUFN_WIDTH).
69 |
70 | - **Clock Management:**
71 | - `CLK_EN`: Clock Gate Enable Signal.
72 |
73 | - **Address and Memory Access:**
74 | - `Address`: Address Bus (Width: ADDR_WIDTH).
75 | - `WrEn`: Write Enable Signal.
76 | - `RdEn`: Read Enable Signal.
77 |
78 | ### Outputs
79 |
80 | The System Controller block provides the following outputs:
81 |
82 | - **Data Transfer:**
83 | - `WrData`: Write Data Bus (Width: DATA_BUS_WIDTH).
84 | - `TX_P_Data`: UART_TX Data Bus (Width: DATA_BUS_WIDTH).
85 | - `TX_D_VLD`: TX Data Valid Signal.
86 |
87 | - **Clock Divider Control:**
88 | - `clk_div_en`: Clock Divider Enable Signal.
89 |
90 | - **Clock Divider Output:**
91 | - `ClkDiv_RX`: Clock Divider Ratio for RX (Width: DATA_BUS_WIDTH-3).
92 |
--------------------------------------------------------------------------------
/Clock Divider/ClkDiv_tb.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ns
2 |
3 | module ClkDiv_tb ();
4 |
5 | /*******************************************/
6 | /*************** PARAMETERS ****************/
7 | /*******************************************/
8 | parameter MAX_RATIO = 10;
9 | parameter RATIO_BIT = ($clog2(MAX_RATIO)+1);
10 | parameter CLK_PERIOD = 10;
11 | parameter HALF_PERIOD = 5;
12 | parameter HIGH = 1;
13 | parameter LOW = 0;
14 |
15 | /*******************************************************/
16 | /*************** TB SIGNAL DECLARATIONS ****************/
17 | /*******************************************************/
18 | reg [RATIO_BIT-1:0] DIV_RATIO;
19 | reg CLK;
20 | reg RST;
21 | reg ENABLE;
22 | wire CLK_OUT;
23 | wire CLK_NEG;
24 |
25 | integer i;
26 |
27 | assign CLK_NEG = ~CLK_OUT;
28 |
29 | /**********************************************/
30 | /*************** INITIAL BLOCK ****************/
31 | /**********************************************/
32 | initial
33 | begin
34 | $dumpfile("ClkDiv.vcd");
35 | $dumpvars;
36 | initialize;
37 | reset;
38 |
39 | repeat(MAX_RATIO)
40 | begin
41 | divide_by(i);
42 | i = i + 1;
43 | end
44 |
45 | #(5*CLK_PERIOD) $stop;
46 | end
47 |
48 | /**************************************/
49 | /*************** TASKS ****************/
50 | /**************************************/
51 |
52 | /////////////
53 | task reset;
54 | begin
55 | RST = LOW;
56 | #HALF_PERIOD;
57 | RST = HIGH;
58 | #HALF_PERIOD;
59 | end
60 | endtask
61 |
62 | //////////////////
63 | task initialize;
64 | begin
65 | DIV_RATIO = LOW;
66 | CLK = LOW;
67 | ENABLE = LOW;
68 | i = LOW;
69 | end
70 | endtask
71 |
72 | ///////////////////
73 | task divide_by;
74 | input [RATIO_BIT-1:0] ratio;
75 | begin
76 | reset;
77 | DIV_RATIO = ratio;
78 | ENABLE = HIGH;
79 | #(ratio*CLK_PERIOD);
80 | calc_period;
81 | #(ratio*CLK_PERIOD);
82 | ENABLE = LOW;
83 | end
84 | endtask
85 | ///////////////////
86 | task calc_period;
87 | real period,first,last;
88 | begin
89 | first = 0;
90 | last = 0;
91 | period = 0;
92 | if( (DIV_RATIO == 0 || DIV_RATIO == 1) )
93 | begin
94 | @(posedge CLK_OUT)
95 | first = $realtime;
96 | @(posedge CLK_OUT)
97 | last = $realtime;
98 | @(negedge CLK_OUT)
99 | period = last - first;
100 | $display("[PASSED]: div ratio = %0d, clock period = %0dns, div clock period = %0dns",DIV_RATIO,CLK_PERIOD,period);
101 | end
102 |
103 | else
104 | begin
105 | wait(CLK_OUT);
106 | first = $realtime;
107 | wait(!CLK_OUT);
108 | wait(CLK_OUT);
109 | last = $realtime;
110 | wait(!CLK_OUT);
111 | period = last - first;
112 |
113 | if(period == DIV_RATIO*CLK_PERIOD)
114 | $display("[PASSED]: div ratio = %0d, clock period = %0dns, div clock period = %0dns",DIV_RATIO,CLK_PERIOD,period);
115 | else
116 | $display("[FAILED]: div ratio = %0d",DIV_RATIO);
117 | end
118 | end
119 | endtask
120 |
121 | /************************************************/
122 | /*************** CLOCK GENERATOR ****************/
123 | /************************************************/
124 | always #HALF_PERIOD CLK = ~CLK;
125 |
126 | /**************************************************/
127 | /*************** DUT INSTANTIATION ****************/
128 | /**************************************************/
129 | ClkDiv #(.RATIO_WIDTH(RATIO_BIT)) DUT ( .i_ref_clk(CLK),
130 | .i_rst_n(RST),
131 | .i_clk_en(ENABLE),
132 | .i_div_ratio(DIV_RATIO),
133 | .o_div_clk(CLK_OUT) );
134 | endmodule
135 |
136 |
137 |
--------------------------------------------------------------------------------
/Register File/README.md:
--------------------------------------------------------------------------------
1 | # Register File Block
2 |
3 | ## Overview
4 | The Register File is a critical component of our multi-clock domain mini-processor system. It serves as the primary storage for our processor's registers, enabling efficient data retrieval and manipulation during program execution.
5 | The Register File consists of 8 registers, each register of 16-bit width.
6 |
7 |
8 | ## Block Description
9 | The Register File block is responsible for the following key functions:
10 |
11 | - **Register Storage:** It provides storage for a set of registers, each capable of holding data of a specific width.
12 |
13 | - **Read Access:** The block supports read operations, allowing the processor to access the contents of registers as needed for computations.
14 |
15 | - **Write Access:** It also enables write operations, allowing the processor to update the contents of registers when required.
16 |
17 | - **Register Indexing:** The block accepts register address inputs, indicating the target registers for read or write operations.
18 |
19 | ## Block Interface
20 | The Register File block has the following interface:
21 |
22 | 
23 |
24 | - **Inputs:**
25 | - `WrData`: 8-bits Data input for write operations.
26 | - `WrEn`: Control signal enabling write operations.
27 | - `RdEn`: Control signal enabling read operations.
28 | - `Address`: Register address input for read or write operations.
29 | - `CLK`: Clock signal for sequential elements.
30 | - `RST`: Active-low asynchronous reset signal to clear the sequential elements.
31 |
32 | - **Outputs:**
33 | - `RdData`: Data output for read operations.
34 | - `RdData_Valid`: Status flag indicating that the data read from the register is valid.
35 | - `REG0`: The register contents at address 0x0, used by the system to store ALU Operand A
36 | - `REG1`: The register contents at address 0x1, used by the system to store ALU Operand B
37 | - `REG2`: The register contents at address 0x2, used by the system to store UART Config
38 | - `REG3`: The register contents at address 0x3, used by the system to store Div Ratio
39 |
40 | > For a better understanding of how the Rgister File block is implemented in RTL (Register-Transfer Level) code, please refer to the [`RegFile.v`](./RegFile.v) file in this repository.
41 |
42 |
43 | ## Usage
44 | To effectively utilize the Register File block within our system, follow these steps:
45 |
46 | 1. Use the `Address` input to specify which registers you want to read data from or write data into.
47 |
48 | 2. The `RdData` output will provide the data stored in the specified register when the `RdEn` signal is asserted.
49 |
50 | 3. To update the contents of a register, set the `Address` input to the target register, provide the data to be written in `WrData`, and assert the `WrEn` signal.
51 |
52 | 4. Only one operation (read or write) can be evaluated at a time.
53 |
54 | ## Elaborated Design
55 |
56 | 
57 |
58 | ## [Testbench](./RegFile_tb.v)
59 |
60 | 
61 |
62 | ```
63 | /******************** Writing Testcases **************************/
64 | [PASSED]: Write in Address 000
65 | [PASSED]: Write in Address 001
66 | [PASSED]: Write in Address 010
67 | [PASSED]: Write in Address 011
68 | [PASSED]: Write in Address 100
69 | [PASSED]: Write in Address 101
70 | [PASSED]: Write in Address 110
71 | [PASSED]: Write in Address 111
72 | /******************** Reading Testcases **************************/
73 | [PASSED]: Read from Address 000
74 | [PASSED]: Read from Address 001
75 | [PASSED]: Read from Address 010
76 | [PASSED]: Read from Address 011
77 | [PASSED]: Read from Address 100
78 | [PASSED]: Read from Address 101
79 | [PASSED]: Read from Address 110
80 | [PASSED]: Read from Address 111
81 | /******************** Enables Testcases **************************/
82 | [PASSED]: Writing rejected when WrEn = 1 RdEn = 1
83 | [PASSED]: Reading rejected when WrEn = 1 RdEn = 1
84 | [PASSED]: Writing rejected when WrEn = 0 RdEn = 0
85 | [PASSED]: Reading rejected when WrEn = 0 RdEn = 0
86 | ```
87 |
88 |
89 |
--------------------------------------------------------------------------------
/UART/UART RX/UART_RX.v:
--------------------------------------------------------------------------------
1 | module UART_RX #(parameter WIDTH = 8 ,
2 | PAR_MAX = 11 ,
3 | MAX_PRESCALE = 32 ,
4 | FRAME_WIDTH = ($clog2(PAR_MAX) + 1) ,
5 | PRSC_WIDTH = ($clog2(MAX_PRESCALE)+1) )(
6 |
7 | input wire i_clk ,
8 | input wire i_rst_n ,
9 | input wire [PRSC_WIDTH-1:0] i_prescale ,
10 | input wire i_serial_data ,
11 | input wire i_parity_enable ,
12 | input wire i_parity_type ,
13 | output wire o_data_valid ,
14 | output wire o_parity_error ,
15 | output wire o_stop_error ,
16 | output wire [WIDTH-1:0] o_parallel_data );
17 |
18 | // internal signal declaration
19 | wire [FRAME_WIDTH-2:0] x_bit_cnt ; // from edge_bit_counter to FSM
20 | wire [PRSC_WIDTH-2:0] x_edge_cnt ; // from edge_bit_counter to data_sampling
21 | wire x_samp_done ; // from edge_bit_counter to FSM
22 | wire x_sampled_bit ; // from data_sampling to parity_check, start_check, stop_check & deserializer
23 | //wire o_parity_error ; // from parity_check to FSM
24 | //wire o_stop_error ; // from stop_check to FSM
25 | wire x_strt_glitch ; // from start_check to FSM
26 | wire x_samp_cnt_en ; // from FSM to data_sampling & edge_bit_counter
27 | wire x_deser_en ; // from FSM to deserializer
28 | wire x_success_sig ; // from FSM to deserializer
29 | wire x_par_chk_en ; // from FSM to parity_check
30 | wire x_strt_chk_en ; // from FSM to start_check
31 | wire x_stp_chk_en ; // from FSM to stop_check
32 | wire [WIDTH-1:0] x_sampled_data; // from deserializer to parity_check
33 |
34 | UART_RX_FSM U0_FSM (
35 | .clk (i_clk) ,
36 | .rst (i_rst_n) ,
37 | .RX_IN (i_serial_data) ,
38 | .bit_cnt (x_bit_cnt) ,
39 | .done_sampling (x_samp_done) ,
40 | .par_en (i_parity_enable) ,
41 | .par_err (o_parity_error) ,
42 | .start_glitch (x_strt_glitch) ,
43 | .stop_err (o_stop_error) ,
44 | .par_check_en (x_par_chk_en) ,
45 | .start_check_en (x_strt_chk_en) ,
46 | .stop_check_en (x_stp_chk_en) ,
47 | .samp_cnt_en (x_samp_cnt_en) ,
48 | .deser_en (x_deser_en) ,
49 | .data_valid (x_success_sig) );
50 |
51 | edge_bit_counter U0_edge_bit_counter (
52 | .clk (i_clk) ,
53 | .rst (i_rst_n) ,
54 | .enable (x_samp_cnt_en) ,
55 | .prescale (i_prescale) ,
56 | .parity_en (i_parity_enable) ,
57 | .bit_cnt (x_bit_cnt) ,
58 | .edge_max (x_samp_done) ,
59 | .edge_cnt (x_edge_cnt) );
60 |
61 | data_sampling U0_data_sampling (
62 | .clk (i_clk) ,
63 | .rst (i_rst_n) ,
64 | .serial_data (i_serial_data) ,
65 | .counter (x_edge_cnt) ,
66 | .enable (x_samp_cnt_en) ,
67 | .sampled_bit (x_sampled_bit) ,
68 | .prescale (i_prescale[PRSC_WIDTH-1:1]));
69 |
70 |
71 | deserializer U0_deserializer (
72 | .clk (i_clk) ,
73 | .rst (i_rst_n) ,
74 | .sampled_bit (x_sampled_bit) ,
75 | .enable (x_deser_en) ,
76 | .success (x_success_sig) ,
77 | .data_valid (o_data_valid) ,
78 | .sampled_stream (x_sampled_data) ,
79 | .parallel_data (o_parallel_data) );
80 |
81 |
82 | start_check U0_start_check (
83 | .enable (x_strt_chk_en) ,
84 | .sampled_start_bit (x_sampled_bit) ,
85 | .glitch (x_strt_glitch) );
86 |
87 | stop_check U0_stop_check (
88 | .enable (x_stp_chk_en) ,
89 | .sampled_stop_bit (x_sampled_bit) ,
90 | .error (o_stop_error) );
91 |
92 | parity_check U0_parity_check (
93 | .data (x_sampled_data) ,
94 | .par_type (i_parity_type) ,
95 | .par_bit (x_sampled_bit) ,
96 | .enable (x_par_chk_en) ,
97 | .error (o_parity_error) );
98 |
99 |
100 | endmodule
101 |
--------------------------------------------------------------------------------
/Asynchronous FIFO/ASYNC_FIFO_tb.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/100ps
2 |
3 | module ASYNC_FIFO_tb ();
4 |
5 | /*******************************************************************/
6 | ///////////////////// TB Signals Declaration ////////////////////////
7 | /*******************************************************************/
8 | parameter DATA_WIDTH = 8 , MEM_in_DEPTH = 8 , PTR_WIDTH = ($clog2(MEM_in_DEPTH)+1);
9 | parameter W_CLK_PERIOD = 10 , W_HALF_PERIOD = 5 ;
10 | parameter R_CLK_PERIOD = 25 , R_HALF_PERIOD = 12.5 ;
11 | parameter HIGH = 1 , LOW = 0 ;
12 |
13 | defparam DUT.MEM_DEPTH = MEM_in_DEPTH;
14 | // interface ports
15 | reg W_CLK ;
16 | reg W_RST ;
17 | reg W_INC ;
18 | reg R_CLK ;
19 | reg R_RST ;
20 | reg R_INC ;
21 | reg [DATA_WIDTH-1:0] W_DATA ;
22 | wire FULL ;
23 | wire [DATA_WIDTH-1:0] R_DATA ;
24 | wire EMPTY ;
25 |
26 | // testing MEM_inory
27 | reg [DATA_WIDTH-1:0] MEM_in [2*MEM_in_DEPTH-1:0];
28 | reg [DATA_WIDTH-1:0] MEM_out [2*MEM_in_DEPTH-1:0];
29 | integer i,j,o;
30 |
31 | /*******************************************************************/
32 | ////////////////////////// Initial Block ////////////////////////////
33 | /*******************************************************************/
34 | initial
35 | begin
36 | $dumpfile("ASYNC_FIFO.vcd");
37 | $dumpvars;
38 |
39 | initialize();
40 | for(i = 0; i < 2*MEM_in_DEPTH; i = i + 1)
41 | begin
42 | MEM_in[i] = $random %(2**DATA_WIDTH - 1);
43 | end
44 | end
45 |
46 | // read initial block
47 | initial
48 | begin
49 | r_reset();
50 | for(j = 0; j < 2*MEM_in_DEPTH; j = j + 1)
51 | begin
52 | wait(!EMPTY)
53 | @(negedge R_CLK)
54 | MEM_out[j] = R_DATA;
55 | R_INC = HIGH;
56 | #R_CLK_PERIOD
57 | R_INC = LOW;
58 | #R_CLK_PERIOD;
59 | end
60 | #(R_CLK_PERIOD)
61 | for(o = 0; o < 2*MEM_in_DEPTH; o = o + 1)
62 | begin
63 | if(MEM_out[o] == MEM_in[o])
64 | $display("MEMORY[%2d]: CAPTURE PASSED",o);
65 | else
66 | $display("MEMORY[%2d]: CAPTURE FAILED",o);
67 | end
68 | #(10*R_CLK_PERIOD) $stop;
69 | end
70 |
71 | // write initial block
72 | initial
73 | begin
74 | w_reset();
75 | for(i = 0; i < 2*MEM_in_DEPTH; i = i + 1)
76 | begin
77 | wait(!FULL)
78 | @(negedge W_CLK)
79 | W_INC = HIGH;
80 | W_DATA = MEM_in[i];
81 | #W_CLK_PERIOD
82 | W_INC = LOW;
83 | #W_CLK_PERIOD;
84 | end
85 | end
86 |
87 | /*******************************************************************/
88 | ////////////////////////////// TASKS ////////////////////////////////
89 | /*******************************************************************/
90 | task w_reset;
91 | begin
92 | W_RST = LOW;
93 | #W_HALF_PERIOD
94 | W_RST = HIGH;
95 | #W_HALF_PERIOD;
96 | end
97 | endtask
98 | /********************************/
99 | task r_reset;
100 | begin
101 | R_RST = LOW;
102 | #R_HALF_PERIOD
103 | R_RST = HIGH;
104 | #R_HALF_PERIOD;
105 | end
106 | endtask
107 | /********************************/
108 | task initialize;
109 | begin
110 | W_CLK = LOW;
111 | W_RST = LOW;
112 | W_INC = LOW;
113 | R_CLK = LOW;
114 | R_RST = LOW;
115 | R_INC = LOW;
116 | W_DATA = LOW;
117 | end
118 | endtask
119 | /********************************/
120 |
121 | /*******************************************************************/
122 | ///////////////////////// Clock Generator ///////////////////////////
123 | /*******************************************************************/
124 | always #W_HALF_PERIOD W_CLK = ~W_CLK;
125 | always #R_HALF_PERIOD R_CLK = ~R_CLK;
126 |
127 | /*******************************************************************/
128 | //////////////////////// DUT Instantiation //////////////////////////
129 | /*******************************************************************/
130 |
131 | ASYNC_FIFO DUT (
132 | .i_Wclk (W_CLK) ,
133 | .i_Wrst_n (W_RST) ,
134 | .i_Winc (W_INC) ,
135 | .i_Rclk (R_CLK) ,
136 | .i_Rrst_n (R_RST) ,
137 | .i_Rinc (R_INC) ,
138 | .i_Wdata (W_DATA) ,
139 | .o_full (FULL) ,
140 | .o_Rdata (R_DATA) ,
141 | .o_empty (EMPTY) );
142 |
143 | endmodule
144 |
--------------------------------------------------------------------------------
/BACKEND/Synthesis/power.rpt:
--------------------------------------------------------------------------------
1 | Loading db file '/home/IC/tsmc_fb_cl013g_sc/aci/sc-m/synopsys/scmetro_tsmc_cl013g_rvt_ss_1p08v_125c.db'
2 | Information: Propagating switching activity (low effort zero delay simulation). (PWR-6)
3 | Warning: Design has unannotated primary inputs. (PWR-414)
4 | Warning: Design has unannotated sequential cell outputs. (PWR-415)
5 |
6 | ****************************************
7 | Report : power
8 | -hier
9 | -analysis_effort low
10 | Design : SYS_TOP
11 | Version: K-2015.06
12 | Date : Mon Sep 25 22:32:08 2023
13 | ****************************************
14 |
15 |
16 | Library(s) Used:
17 |
18 | scmetro_tsmc_cl013g_rvt_ss_1p08v_125c (File: /home/IC/tsmc_fb_cl013g_sc/aci/sc-m/synopsys/scmetro_tsmc_cl013g_rvt_ss_1p08v_125c.db)
19 |
20 |
21 | Operating Conditions: scmetro_tsmc_cl013g_rvt_ss_1p08v_125c Library: scmetro_tsmc_cl013g_rvt_ss_1p08v_125c
22 | Wire Load Model Mode: top
23 |
24 |
25 | Global Operating Voltage = 1.08
26 | Power-specific unit information :
27 | Voltage Units = 1V
28 | Capacitance Units = 1.000000pf
29 | Time Units = 1ns
30 | Dynamic Power Units = 1mW (derived from V,C,T units)
31 | Leakage Power Units = 1pW
32 |
33 |
34 | --------------------------------------------------------------------------------
35 | Switch Int Leak Total
36 | Hierarchy Power Power Power Power %
37 | --------------------------------------------------------------------------------
38 | SYS_TOP 1.01e-02 0.302 1.35e+07 0.326 100.0
39 | U0_ClkGate (ClkGate) 3.07e-03 5.07e-03 2.04e+04 8.16e-03 2.5
40 | U0_UART_TX (UART_TX) 2.04e-04 1.58e-04 5.95e+05 9.58e-04 0.3
41 | U0_MUX (MUX) 0.000 0.000 2.27e+04 2.27e-05 0.0
42 | U0_parity_calc (parity_calc) 0.000 4.67e-05 2.20e+05 2.67e-04 0.1
43 | U0_FSM (FSM) 0.000 1.75e-05 1.01e+05 1.18e-04 0.0
44 | U0_serializer (serializer) 0.000 7.53e-05 2.43e+05 3.18e-04 0.1
45 | U0_PULSE_GEN (PULSE_GEN_0) 0.000 5.85e-06 1.35e+04 1.93e-05 0.0
46 | U1_ClkDiv (ClkDiv) 7.22e-05 7.99e-04 6.32e+05 1.50e-03 0.5
47 | add_74 (ClkDiv_DW01_inc_1) 0.000 0.000 8.96e+04 8.96e-05 0.0
48 | add_50 (ClkDiv_DW01_inc_0) 5.44e-06 1.93e-05 9.73e+04 1.22e-04 0.0
49 | U0_ClkDiv (ClkDiv_RATIO_WIDTH6) 2.18e-04 5.31e-04 4.95e+05 1.24e-03 0.4
50 | U1_RST_SYNC (RST_SYNC_1) 8.12e-06 2.66e-04 2.35e+04 2.98e-04 0.1
51 | U0_RST_SYNC (RST_SYNC_0) 2.59e-05 4.49e-03 2.53e+04 4.54e-03 1.4
52 | U0_ASYNC_FIFO (ASYNC_FIFO_DATA_WIDTH8_MEM_DEPTH8_PTR_WIDTH4)
53 | 2.22e-03 0.112 2.14e+06 0.116 35.7
54 | U1_GRAY_CONV (GRAY_CONV_PTR_WIDTH4_1)
55 | 0.000 0.000 3.94e+04 3.94e-05 0.0
56 | U0_GRAY_CONV (GRAY_CONV_PTR_WIDTH4_0)
57 | 0.000 0.000 3.94e+04 3.94e-05 0.0
58 | U1_DF_SYNC (DF_SYNC_BUS_WIDTH4_1) 0.000 1.16e-02 8.27e+04 1.17e-02 3.6
59 | U0_DF_SYNC (DF_SYNC_BUS_WIDTH4_0) 0.000 4.68e-05 7.19e+04 1.19e-04 0.0
60 | U0_FIFO_WR (FIFO_WR_PTR_WIDTH4) 0.000 7.23e-03 1.72e+05 7.41e-03 2.3
61 | U0_FIFO_RD (FIFO_RD_PTR_WIDTH4) 0.000 2.89e-05 1.79e+05 2.08e-04 0.1
62 | U0_FIFO_MEM_CNTRL (FIFO_MEM_CNTRL_DATA_WIDTH8_MEM_DEPTH8_PTR_WIDTH4)
63 | 1.82e-03 9.30e-02 1.54e+06 9.63e-02 29.6
64 | U0_RegFile (RegFile_BUS_WIDTH8_DEPTH8_ADDR_WIDTH4_PAR_EN1_PAR_TYPE0_PRESCALE32_DIV_RATIO32)
65 | 1.92e-03 0.116 1.78e+06 0.120 36.8
66 | U0_ALU (ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4)
67 | 0.000 2.47e-02 5.69e+06 3.04e-02 9.3
68 | div_24 (ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW_div_uns_1)
69 | 0.000 0.000 2.53e+06 2.53e-03 0.8
70 | mult_23 (ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW02_mult_0)
71 | 0.000 0.000 1.65e+06 1.65e-03 0.5
72 | add_21 (ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW01_add_0)
73 | 0.000 0.000 2.17e+05 2.17e-04 0.1
74 | sub_22 (ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW01_sub_0)
75 | 0.000 0.000 2.43e+05 2.43e-04 0.1
76 | U0_SYS_CTRL (SYS_CTRL_ALU_WIDTH16_ADDR_WIDTH4_DATA_BUS_WIDTH8_ALUFN_WIDTH4)
77 | 0.000 1.80e-02 6.22e+05 1.86e-02 5.7
78 | U0_DATA_SYNC (DATA_SYNC_BUS_WIDTH8) 0.000 1.74e-02 1.72e+05 1.75e-02 5.4
79 | U0_sync_bus (sync_bus) 0.000 1.16e-02 1.26e+05 1.17e-02 3.6
80 | U0_DS_pulse (DS_pulse) 0.000 2.89e-03 2.52e+04 2.92e-03 0.9
81 | inst_PULSE_GEN (PULSE_GEN_1) 0.000 1.45e-03 1.48e+04 1.46e-03 0.4
82 | U0_multi_ff (multi_ff) 0.000 2.89e-03 2.07e+04 2.91e-03 0.9
83 | U0_UART_RX (UART_RX_WIDTH8) 8.38e-04 2.66e-03 1.25e+06 4.75e-03 1.5
84 | U0_parity_check (parity_check) 0.000 0.000 1.15e+05 1.15e-04 0.0
85 | U0_stop_check (stop_check) 0.000 0.000 1.32e+04 1.32e-05 0.0
86 | U0_start_check (start_check) 0.000 0.000 2.78e+03 2.78e-06 0.0
87 | U0_deserializer (deserializer) 0.000 9.74e-04 2.37e+05 1.21e-03 0.4
88 | U0_data_sampling (data_sampling) 5.76e-05 2.82e-04 3.67e+05 7.06e-04 0.2
89 | U0_edge_bit_counter (edge_bit_counter)
90 | 2.09e-04 8.11e-04 3.37e+05 1.36e-03 0.4
91 | U0_FSM (UART_RX_FSM) 2.80e-04 5.77e-04 1.73e+05 1.03e-03 0.3
92 | 1
93 |
--------------------------------------------------------------------------------
/SYS_TOP_tb.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/1ps
2 |
3 | module SYS_TOP_tb ();
4 |
5 | /*******************************************************************/
6 | ///////////////////// TB Signals Declaration ////////////////////////
7 | /*******************************************************************/
8 | parameter PRESCALE = 32;
9 | parameter BUS_WIDTH = 8 , FRAME = 11;
10 | parameter REF_CLK_PERIOD = 20, REF_HALF_PERIOD = (REF_CLK_PERIOD/2);
11 | parameter RX_CLK_PERIOD = 271.267, RX_HALF_PERIOD = (RX_CLK_PERIOD/2);
12 | parameter TX_CLK_PERIOD = (PRESCALE*RX_CLK_PERIOD), TX_HALF_PERIOD = (TX_CLK_PERIOD/2);
13 | parameter HIGH = 1, LOW = 0;
14 |
15 | // interface ports
16 | reg REF_CLK ;
17 | reg URX_CLK ;
18 | reg UTX_CLK ;
19 | reg RST ;
20 | reg RX_IN ;
21 | wire TX_OUT ;
22 | wire PAR_ERR ;
23 | wire STP_ERR ;
24 |
25 | // integers
26 | integer i,j;
27 |
28 | // registers
29 | reg [BUS_WIDTH-1:0] read_data;
30 | reg [FRAME-1:0] test_out;
31 |
32 | /*******************************************************************/
33 | ////////////////////////// Initial Block ////////////////////////////
34 | /*******************************************************************/
35 | initial
36 | begin
37 | $dumpfile("SYS_TOP.vcd");
38 | $dumpvars;
39 |
40 | initialize();
41 | reset();
42 |
43 | @(negedge UTX_CLK)
44 |
45 | /**************************** CONFIG TESTCASE ***************************/
46 |
47 | /************************ REG FILE WRITE TESTCASE ***********************/
48 | // testcase (1)
49 | write_test('b10101010100,'b11000001000,'b11100011110); // 0xAA - 0x4 - 0x8F
50 | // testcase (2)
51 | write_test('b10101010100,'b10000001010,'b10101001010); // 0xAA - 0x5 - 0xA5
52 | // testcase (3)
53 | write_test('b10101010100,'b11000001110,'b11101111000); // 0xAA - 0x7 - 0xBC
54 |
55 |
56 | /************************ REG FILE READ TESTCASE ************************/
57 | // testcase (1)
58 | read_test('b10101110110,'b11000001000); // 0xBB - 0x4
59 | // testcase (2)
60 | read_test('b10101110110,'b10000001010); // 0xBB - 0x5
61 | // testcase (3)
62 | read_test('b10101110110,'b11000001110); // 0xBB - 0x7
63 |
64 | /******** ALU OPERATION WITH OPERAND TESTCASE ********/
65 | ALU_O_test('b10110011000,'b11011001000,'b11001100100,'b10000000000); // 0xCC - 100 - 50 - 0x0
66 |
67 | /***************** ALU OPERATION WITH NO OPERAND TESTCASE ****************/
68 | ALU_NO_test('b10110111010, 'b11000000010); // 0xDD - 0x1
69 | ALU_NO_test('b10110111010, 'b11000000100); // 0xDD - 0x2
70 | ALU_NO_test('b10110111010, 'b10000000110); // 0xDD - 0x3
71 |
72 | #(50*TX_CLK_PERIOD) $stop;
73 |
74 | end
75 |
76 | /*******************************************************************/
77 | ////////////////////////////// TASKS ////////////////////////////////
78 | /*******************************************************************/
79 | task reset;
80 | begin
81 | RST = LOW;
82 | #RX_HALF_PERIOD
83 | RST = HIGH;
84 | #RX_HALF_PERIOD;
85 | end
86 | endtask
87 | /********************************/
88 | task initialize;
89 | begin
90 | REF_CLK = LOW;
91 | URX_CLK = LOW;
92 | UTX_CLK = LOW;
93 | RST = LOW;
94 | RX_IN = HIGH;
95 | end
96 | endtask
97 | /********************************/
98 | task write_test;
99 | input [FRAME-1:0] CMD,addr,data;
100 | begin
101 | passing_input(CMD);
102 | passing_input(addr);
103 | passing_input(data);
104 | end
105 | endtask
106 | /********************************/
107 | task read_test;
108 | input [FRAME-1:0] CMD,addr;
109 | begin
110 | passing_input(CMD);
111 | passing_input(addr);
112 | end
113 | endtask
114 | /********************************/
115 | task passing_input;
116 | input [FRAME-1:0] frame;
117 | begin
118 | for(i = 0; i < FRAME; i = i + 1)
119 | begin
120 | RX_IN = frame[i];
121 | #(TX_CLK_PERIOD);
122 | end
123 | end
124 | endtask
125 | /********************************/
126 | task ALU_O_test;
127 | input [FRAME-1:0] CMD,Operand_A,Operand_B,ALU_FUNC;
128 | begin
129 | passing_input(CMD);
130 | passing_input(Operand_A);
131 | passing_input(Operand_B);
132 | passing_input(ALU_FUNC);
133 | end
134 | endtask
135 | /********************************/
136 | task ALU_NO_test;
137 | input [FRAME-1:0] CMD,ALU_FUNC;
138 | begin
139 | passing_input(CMD);
140 | passing_input(ALU_FUNC);
141 | end
142 | endtask
143 | /*******************************************************************/
144 | ///////////////////////// Clock Generator ///////////////////////////
145 | /*******************************************************************/
146 | always #REF_HALF_PERIOD REF_CLK = ~REF_CLK;
147 | always #RX_HALF_PERIOD URX_CLK =~URX_CLK;
148 | always #TX_HALF_PERIOD UTX_CLK =~UTX_CLK;
149 |
150 | /*******************************************************************/
151 | //////////////////////// DUT Instantiation //////////////////////////
152 | /*******************************************************************/
153 |
154 | SYS_TOP #() DUT (
155 | .i_ref_clk (REF_CLK) ,
156 | .i_uart_clk (URX_CLK) ,
157 | .i_rst_n (RST) ,
158 | .i_rx_in (RX_IN) ,
159 | .o_parity_err (PAR_ERR) ,
160 | .o_stop_err (STP_ERR) ,
161 | .o_tx_out (TX_OUT) );
162 |
163 | endmodule
164 |
--------------------------------------------------------------------------------
/UART/UART TX/README.md:
--------------------------------------------------------------------------------
1 | # UART TX (Transmitter) Block
2 |
3 | ## Overview
4 | The UART TX (Transmitter) block is a crucial part of our multi-clock domain system. It's responsible for transmitting data to a master device through the UART interface. Whether it's sending commands, results, or any other information, the UART TX block ensures efficient and accurate data transmission.
5 |
6 | ## Block Description
7 | The UART TX block performs the following key functions:
8 |
9 | - **Data Transmission:** It receives data to be transmitted on the `P_DATA` bus when the `DATA_VALID` signal is high.
10 |
11 | - **Configuration:** The block allows for configuration of frame parity bit generation (`PAR_EN`) and parity type (`PAR_TYP`) for data integrity.
12 |
13 | - **Status Indication:** It provides a `TX_OUT` serial data output signal to transmit data and a `BUSY` signal to indicate ongoing transmission.
14 |
15 | ## Block Interface
16 | The UART TX block has the following interface:
17 |
18 | 
19 |
20 | - **Inputs:**
21 | - `CLK`: Clock signal for sequential elements.
22 | - `RST`: Active-low asynchronous reset signal to clear registers.
23 | - `PAR_TYPE`: Configuration signal for parity type (0 for even, 1 for odd).
24 | - `PAR_EN`: Configuration signal to enable/disable the frame parity bit (0 for disable, 1 for enable).
25 | - `P_DATA`: Parallel 8-bits Data to be transmitted.
26 | - `DATA_VALID`: Signal indicating that `P_DATA` contains valid data for transmission.
27 |
28 | - **Outputs:**
29 | - `TX_OUT`: Serial data output signal for transmitting data. (high when idle)
30 | - `BUSY`: Output signal indicating ongoing transmission (high for transmission, low for idle).
31 |
32 | > For a better understanding of how the UART TX block is implemented in RTL (Register-Transfer Level) code, please refer to the [`UART_TX.v`](./UART_TX.v) file in this repository.
33 |
34 | ## Specifications
35 | To effectively use the UART TX block, consider the following specifications:
36 |
37 | - UART TX only accepts new data on the `P_DATA` bus when the `DATA_VALID` signal is high.
38 |
39 | - The block is cleared using the asynchronous active low reset signal `RST`.
40 |
41 | - The `DATA_VALID` signal remains high for only 1 clock cycle to indicate valid data.
42 |
43 | - The `BUSY` signal is high as long as the UART TX block is transmitting a frame; otherwise, it's low.
44 |
45 | - During UART TX processing, no new data is accepted on the `P_DATA` bus, even if `DATA_VALID` is high.
46 |
47 | - `TX_OUT` is high in the IDLE case when no transmission is occurring.
48 |
49 | - Configuration:
50 | - `PAR_EN` (Parity Configuration):
51 | - 0: Disables the frame parity bit.
52 | - 1: Enables the frame parity bit.
53 | - `PAR_TYP` (Parity Type Configuration):
54 | - 0: Specifies even parity.
55 | - 1: Specifies odd parity.
56 |
57 | ## Elaborated Design
58 | The UART TX block is composed of four primary blocks, each serving a unique function:
59 |
60 | 
61 |
62 | ### 1. Serializer ([serializer.v](./serializer.v))
63 | The Serializer block is responsible for converting parallel data received on the `P_DATA` bus into a serial frame for transmission. It performs the task of serializing the data efficiently.
64 |
65 | 
66 |
67 | ### 2. Parity Calculator ([parity_calc.v](./parity_calc.v))
68 | The Parity Calculator block determines the parity bit for the serial frame, ensuring data integrity during transmission. Depending on the configuration, it calculates and inserts either an even or odd parity bit into the frame.
69 |
70 | 
71 |
72 | ### 3. MUX (Multiplexer) ([MUX.v](./MUX.v))
73 | The MUX block selects the appropriate bit from the serial frame for output, facilitating the serial data transmission. It plays a critical role in the serialization process.
74 |
75 |
76 |
77 |
78 |
79 | ### 4. FSM (Finite State Machine) ([FSM.v](./FSM.v))
80 | The FSM block controls the flow of data transmission, ensuring that data is sent in the correct order and at the right time. It orchestrates the operation of the entire UART TX block.
81 |
82 | 
83 |
84 |
85 | ## [Testbench](./UART_TX_tb.v)
86 |
87 | 
88 |
89 | ```
90 | # /********** Even Parity Testcases **********/
91 | # MISMATCH: 00000000000 -> EVEN PARITY TESTCASE [PASSED]
92 | # MISMATCH: 00000000000 -> EVEN PARITY TESTCASE [PASSED]
93 | # MISMATCH: 00000000000 -> EVEN PARITY TESTCASE [PASSED]
94 | # /********** Odd Parity Testcases **********/
95 | # MISMATCH: 00000000000 -> ODD PARITY TESTCASE [PASSED]
96 | # MISMATCH: 00000000000 -> ODD PARITY TESTCASE [PASSED]
97 | # MISMATCH: 00000000000 -> ODD PARITY TESTCASE [PASSED]
98 | # /********** NO Parity Testcases **********/
99 | # MISMATCH: 0000000000 -> NO PARITY TESTCASE [PASSED]
100 | # MISMATCH: 0000000000 -> NO PARITY TESTCASE [PASSED]
101 | # MISMATCH: 0000000000 -> NO PARITY TESTCASE [PASSED]
102 | # /**** Passing New Data While Transmission ****/
103 | # MISMATCH: 00000000000 -> IGNORING INPUT TESTCASE [PASSED]
104 | ```
105 |
106 |
107 |
--------------------------------------------------------------------------------
/ALU/README.md:
--------------------------------------------------------------------------------
1 | # Arithmetic Logic Unit (ALU) Block
2 |
3 | ## Overview
4 | The Arithmetic Logic Unit (ALU) is a fundamental component of our multi-clock domain system. It plays a critical role in executing various arithmetic and logic operations, enabling the processor to perform tasks such as addition, subtraction, logical AND, logical OR, and more.
5 |
6 | ## Block Description
7 | The ALU block is responsible for the following key functions:
8 |
9 | - **Arithmetic Operations:** It performs basic arithmetic operations like addition and subtraction on input data.
10 |
11 | - **Logical Operations:** It executes logical operations, including AND, OR, NAND, and NOR, to manipulate data.
12 |
13 | - **Comparison:** The ALU compares input values and generates flags to indicate conditions such as equality, less than, and greater than.
14 |
15 | - **Shift Operations** the ALU also supports shift operations. These operations allow for the movement of bits within data operands. These shift operations are valuable for tasks such as data manipulation and scaling within the processor.
16 |
17 | ## Block Interface
18 | The ALU block has the following interface:
19 |
20 |
21 |
22 |
23 |
24 | - **Inputs:**
25 | - `A` and `B`: Input 8-bits data operands for the selected operation.
26 | - `ALU Func`: 4-bits Control signal specifying the operation to be performed.
27 | - `Enable`: Control signal enabling the ALU to function and accept the inputs.
28 | - `CLK`: Clock Signal for sequential elements.
29 | - `RST`: Active-low Asynchronous reset signal to clear the sequential elements.
30 |
31 | - **Outputs:**
32 | - `ALU OUT`: The 16-bits result of the operation.
33 | - `OUT_VALID`: Status flag to indicate that the `ALU OUT` is ready
34 |
35 | > For a better understanding of how the ALU block is implemented in RTL (Register-Transfer Level) code, please refer to the [`ALU.v`](./ALU.v) file in this repository.
36 |
37 | ## ALU Function Table
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | | ALU_FUN |
49 | OPERATION |
50 | ALU_OUT |
51 |
52 |
53 |
54 |
55 | | 0000 |
56 | Arithmetic
|
57 | Addition |
58 | A+B |
59 |
60 |
61 | | 0001 |
62 | Subtraction |
63 | A-B |
64 |
65 |
66 | | 0010 |
67 | Multiplication |
68 | A*B |
69 |
70 |
71 | | 0011 |
72 | Division |
73 | A/B |
74 |
75 |
76 | | 0100 |
77 | Logic
|
78 | AND |
79 | A&B |
80 |
81 |
82 | | 0101 |
83 | OR |
84 | A|B |
85 |
86 |
87 | | 0110 |
88 | NAND |
89 | ~(A&B) |
90 |
91 |
92 | | 0111 |
93 | NOR |
94 | ~(A|B) |
95 |
96 |
97 | | 1000 |
98 | Compare
|
99 | NOP |
100 | 0 |
101 |
102 |
103 | | 1001 |
104 | if A==B ? |
105 | 1 : 0 |
106 |
107 |
108 | | 1010 |
109 | if A > B ? |
110 | 2 : 0 |
111 |
112 |
113 | | 1011 |
114 | if A < B ? |
115 | 3 : 0 |
116 |
117 |
118 | | 1100 |
119 | Shift
|
120 | LSR to A |
121 | A >> 1 |
122 |
123 |
124 | | 1101 |
125 | LSL to A |
126 | A << 1 |
127 |
128 |
129 | | 1110 |
130 | LSR to B |
131 | B >> 1 |
132 |
133 |
134 | | 1111 |
135 | LSL to B |
136 | B << 1 |
137 |
138 |
139 |
140 |
141 | ## Elaborated Design
142 |
143 | 
144 |
145 | ## [Testbench](./ALU_tb.v)
146 | 
147 |
148 | ```
149 | [PASSED] TESTCASE- 1: ADDITION
150 | [PASSED] TESTCASE- 2: SUBTRACTION
151 | [PASSED] TESTCASE- 3: MULTIPLICATION
152 | [PASSED] TESTCASE- 4: DIVISION
153 | [PASSED] TESTCASE- 5: LOGICAL AND
154 | [PASSED] TESTCASE- 6: LOGICAL OR
155 | [PASSED] TESTCASE- 7: LOGICAL NAND
156 | [PASSED] TESTCASE- 8: LOGICAL NOR
157 | [PASSED] TESTCASE- 9: NOP
158 | [PASSED] TESTCASE-10: EQUALITY
159 | [PASSED] TESTCASE-11: GREATER THAN
160 | [PASSED] TESTCASE-12: LESS THAN
161 | [PASSED] TESTCASE-13: A-SHIFT RIGHT
162 | [PASSED] TESTCASE-14: A-SHIFT LEFT
163 | [PASSED] TESTCASE-15: B-SHIFT RIGHT
164 | [PASSED] TESTCASE-16: B-SHIFT LEFT
165 | [PASSED] TESTCASE-17: RESET
166 | ```
167 |
--------------------------------------------------------------------------------
/BACKEND/Synthesis/check_design.rpt:
--------------------------------------------------------------------------------
1 |
2 | ****************************************
3 | check_design summary:
4 | Version: K-2015.06
5 | Date: Mon Sep 25 22:31:48 2023
6 | ****************************************
7 |
8 | Name Total
9 | --------------------------------------------------------------------------------
10 | Inputs/Outputs 14
11 | Feedthrough (LINT-29) 1
12 | Shorted outputs (LINT-31) 9
13 | Constant outputs (LINT-52) 4
14 |
15 | Cells 25
16 | Cells do not drive (LINT-1) 15
17 | Connected to power or ground (LINT-32) 2
18 | Nets connected to multiple pins on same cell (LINT-33) 8
19 | --------------------------------------------------------------------------------
20 |
21 | Warning: In design 'ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4', cell 'C352' does not drive any nets. (LINT-1)
22 | Warning: In design 'ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4', cell 'C353' does not drive any nets. (LINT-1)
23 | Warning: In design 'ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4', cell 'C354' does not drive any nets. (LINT-1)
24 | Warning: In design 'ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4', cell 'C355' does not drive any nets. (LINT-1)
25 | Warning: In design 'ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4', cell 'C372' does not drive any nets. (LINT-1)
26 | Warning: In design 'ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4', cell 'C374' does not drive any nets. (LINT-1)
27 | Warning: In design 'ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4', cell 'C376' does not drive any nets. (LINT-1)
28 | Warning: In design 'ClkDiv_RATIO_WIDTH6', cell 'C112' does not drive any nets. (LINT-1)
29 | Warning: In design 'ClkDiv', cell 'C126' does not drive any nets. (LINT-1)
30 | Warning: In design 'edge_bit_counter', cell 'C98' does not drive any nets. (LINT-1)
31 | Warning: In design 'edge_bit_counter', cell 'C110' does not drive any nets. (LINT-1)
32 | Warning: In design 'data_sampling', cell 'C66' does not drive any nets. (LINT-1)
33 | Warning: In design 'FIFO_RD_PTR_WIDTH4', cell 'C54' does not drive any nets. (LINT-1)
34 | Warning: In design 'FIFO_WR_PTR_WIDTH4', cell 'C54' does not drive any nets. (LINT-1)
35 | Warning: In design 'serializer', cell 'B_4' does not drive any nets. (LINT-1)
36 | Warning: In design 'GRAY_CONV_PTR_WIDTH4', input port 'bit_ptr[3]' is connected directly to output port 'gray_ptr[3]'. (LINT-29)
37 | Warning: In design 'SYS_CTRL_ALU_WIDTH16_ADDR_WIDTH4_DATA_BUS_WIDTH8_ALUFN_WIDTH4', output port 'ClkDiv_RX[5]' is connected directly to output port 'ClkDiv_RX[3]'. (LINT-31)
38 | Warning: In design 'SYS_CTRL_ALU_WIDTH16_ADDR_WIDTH4_DATA_BUS_WIDTH8_ALUFN_WIDTH4', output port 'ClkDiv_RX[5]' is connected directly to output port 'ClkDiv_RX[4]'. (LINT-31)
39 | Warning: In design 'SYS_CTRL_ALU_WIDTH16_ADDR_WIDTH4_DATA_BUS_WIDTH8_ALUFN_WIDTH4', output port 'ALU_EN' is connected directly to output port 'CLK_EN'. (LINT-31)
40 | Warning: In design 'FIFO_RD_PTR_WIDTH4', output port 'rptr[2]' is connected directly to output port 'raddr[2]'. (LINT-31)
41 | Warning: In design 'FIFO_RD_PTR_WIDTH4', output port 'rptr[1]' is connected directly to output port 'raddr[1]'. (LINT-31)
42 | Warning: In design 'FIFO_RD_PTR_WIDTH4', output port 'rptr[0]' is connected directly to output port 'raddr[0]'. (LINT-31)
43 | Warning: In design 'FIFO_WR_PTR_WIDTH4', output port 'wptr[2]' is connected directly to output port 'waddr[2]'. (LINT-31)
44 | Warning: In design 'FIFO_WR_PTR_WIDTH4', output port 'wptr[1]' is connected directly to output port 'waddr[1]'. (LINT-31)
45 | Warning: In design 'FIFO_WR_PTR_WIDTH4', output port 'wptr[0]' is connected directly to output port 'waddr[0]'. (LINT-31)
46 | Warning: In design 'UART_TX', a pin on submodule 'U0_MUX' is connected to logic 1 or logic 0. (LINT-32)
47 | Pin 'start_bit' is connected to logic 0.
48 | Warning: In design 'UART_TX', a pin on submodule 'U0_MUX' is connected to logic 1 or logic 0. (LINT-32)
49 | Pin 'stop_bit' is connected to logic 1.
50 | Warning: In design 'DATA_SYNC_BUS_WIDTH8', the same net is connected to more than one pin on submodule 'U0_sync_bus'. (LINT-33)
51 | Net 'sync_bus[7]' is connected to pins 'i_0[7]', 'sync_bus[7]''.
52 | Warning: In design 'DATA_SYNC_BUS_WIDTH8', the same net is connected to more than one pin on submodule 'U0_sync_bus'. (LINT-33)
53 | Net 'sync_bus[6]' is connected to pins 'i_0[6]', 'sync_bus[6]''.
54 | Warning: In design 'DATA_SYNC_BUS_WIDTH8', the same net is connected to more than one pin on submodule 'U0_sync_bus'. (LINT-33)
55 | Net 'sync_bus[5]' is connected to pins 'i_0[5]', 'sync_bus[5]''.
56 | Warning: In design 'DATA_SYNC_BUS_WIDTH8', the same net is connected to more than one pin on submodule 'U0_sync_bus'. (LINT-33)
57 | Net 'sync_bus[4]' is connected to pins 'i_0[4]', 'sync_bus[4]''.
58 | Warning: In design 'DATA_SYNC_BUS_WIDTH8', the same net is connected to more than one pin on submodule 'U0_sync_bus'. (LINT-33)
59 | Net 'sync_bus[3]' is connected to pins 'i_0[3]', 'sync_bus[3]''.
60 | Warning: In design 'DATA_SYNC_BUS_WIDTH8', the same net is connected to more than one pin on submodule 'U0_sync_bus'. (LINT-33)
61 | Net 'sync_bus[2]' is connected to pins 'i_0[2]', 'sync_bus[2]''.
62 | Warning: In design 'DATA_SYNC_BUS_WIDTH8', the same net is connected to more than one pin on submodule 'U0_sync_bus'. (LINT-33)
63 | Net 'sync_bus[1]' is connected to pins 'i_0[1]', 'sync_bus[1]''.
64 | Warning: In design 'DATA_SYNC_BUS_WIDTH8', the same net is connected to more than one pin on submodule 'U0_sync_bus'. (LINT-33)
65 | Net 'sync_bus[0]' is connected to pins 'i_0[0]', 'sync_bus[0]''.
66 | Warning: In design 'SYS_CTRL_ALU_WIDTH16_ADDR_WIDTH4_DATA_BUS_WIDTH8_ALUFN_WIDTH4', output port 'ClkDiv_RX[5]' is connected directly to 'logic 0'. (LINT-52)
67 | Warning: In design 'SYS_CTRL_ALU_WIDTH16_ADDR_WIDTH4_DATA_BUS_WIDTH8_ALUFN_WIDTH4', output port 'ClkDiv_RX[4]' is connected directly to 'logic 0'. (LINT-52)
68 | Warning: In design 'SYS_CTRL_ALU_WIDTH16_ADDR_WIDTH4_DATA_BUS_WIDTH8_ALUFN_WIDTH4', output port 'ClkDiv_RX[3]' is connected directly to 'logic 0'. (LINT-52)
69 | Warning: In design 'SYS_CTRL_ALU_WIDTH16_ADDR_WIDTH4_DATA_BUS_WIDTH8_ALUFN_WIDTH4', output port 'clk_div_en' is connected directly to 'logic 1'. (LINT-52)
70 | 1
71 |
--------------------------------------------------------------------------------
/BACKEND/Synthesis/area.rpt:
--------------------------------------------------------------------------------
1 |
2 | ****************************************
3 | Report : area
4 | Design : SYS_TOP
5 | Version: K-2015.06
6 | Date : Mon Sep 25 22:32:07 2023
7 | ****************************************
8 |
9 | Library(s) Used:
10 |
11 | scmetro_tsmc_cl013g_rvt_ss_1p08v_125c (File: /home/IC/tsmc_fb_cl013g_sc/aci/sc-m/synopsys/scmetro_tsmc_cl013g_rvt_ss_1p08v_125c.db)
12 |
13 | Number of ports: 777
14 | Number of nets: 2599
15 | Number of cells: 1797
16 | Number of combinational cells: 1449
17 | Number of sequential cells: 306
18 | Number of macros/black boxes: 0
19 | Number of buf/inv: 325
20 | Number of references: 16
21 |
22 | Combinational area: 13563.821097
23 | Buf/Inv area: 1342.614725
24 | Noncombinational area: 7436.743919
25 | Macro/Black Box area: 0.000000
26 | Net Interconnect area: undefined (No wire load specified)
27 |
28 | Total cell area: 21000.565016
29 | Total area: undefined
30 |
31 | Hierarchical area distribution
32 | ------------------------------
33 |
34 | Global cell area Local cell area
35 | ------------------- -----------------------------
36 | Hierarchical cell Absolute Percent Combi- Noncombi- Black-
37 | Total Total national national boxes Design
38 | -------------------------------- ---------- ------- ---------- --------- ------ ------------------------------------------------------------------------------
39 | SYS_TOP 21000.5650 100.0 24.7107 0.0000 0.0000 SYS_TOP
40 | U0_ALU 7034.3127 33.5 1361.4419 441.2625 0.0000 ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4
41 | U0_ALU/add_21 244.7536 1.2 244.7536 0.0000 0.0000 ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW01_add_0
42 | U0_ALU/div_24 2558.1458 12.2 2558.1458 0.0000 0.0000 ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW_div_uns_1
43 | U0_ALU/mult_23 2159.2445 10.3 1918.0210 0.0000 0.0000 ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW02_mult_0
44 | U0_ALU/mult_23/FS_1 241.2235 1.1 241.2235 0.0000 0.0000 ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW01_add_1
45 | U0_ALU/sub_22 269.4643 1.3 269.4643 0.0000 0.0000 ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW01_sub_0
46 | U0_ASYNC_FIFO 3919.5877 18.7 12.9437 0.0000 0.0000 ASYNC_FIFO_DATA_WIDTH8_MEM_DEPTH8_PTR_WIDTH4
47 | U0_ASYNC_FIFO/U0_DF_SYNC 207.0992 1.0 0.0000 207.0992 0.0000 DF_SYNC_BUS_WIDTH4_0
48 | U0_ASYNC_FIFO/U0_FIFO_MEM_CNTRL 2885.2684 13.7 1228.4748 1656.7936 0.0000 FIFO_MEM_CNTRL_DATA_WIDTH8_MEM_DEPTH8_PTR_WIDTH4
49 | U0_ASYNC_FIFO/U0_FIFO_RD 267.1109 1.3 137.6739 129.4370 0.0000 FIFO_RD_PTR_WIDTH4
50 | U0_ASYNC_FIFO/U0_FIFO_WR 260.0507 1.2 130.6137 129.4370 0.0000 FIFO_WR_PTR_WIDTH4
51 | U0_ASYNC_FIFO/U0_GRAY_CONV 40.0078 0.2 40.0078 0.0000 0.0000 GRAY_CONV_PTR_WIDTH4_0
52 | U0_ASYNC_FIFO/U1_DF_SYNC 207.0992 1.0 0.0000 207.0992 0.0000 DF_SYNC_BUS_WIDTH4_1
53 | U0_ASYNC_FIFO/U1_GRAY_CONV 40.0078 0.2 40.0078 0.0000 0.0000 GRAY_CONV_PTR_WIDTH4_1
54 | U0_ClkDiv 747.2045 3.6 540.1053 207.0992 0.0000 ClkDiv_RATIO_WIDTH6
55 | U0_ClkGate 24.7107 0.1 0.0000 24.7107 0.0000 ClkGate
56 | U0_DATA_SYNC 395.3712 1.9 0.0000 0.0000 0.0000 DATA_SYNC_BUS_WIDTH8
57 | U0_DATA_SYNC/U0_DS_pulse 57.6583 0.3 0.0000 25.8874 0.0000 DS_pulse
58 | U0_DATA_SYNC/U0_DS_pulse/inst_PULSE_GEN
59 | 31.7709 0.2 5.8835 25.8874 0.0000 PULSE_GEN_1
60 | U0_DATA_SYNC/U0_multi_ff 51.7748 0.2 0.0000 51.7748 0.0000 multi_ff
61 | U0_DATA_SYNC/U0_sync_bus 285.9381 1.4 78.8389 207.0992 0.0000 sync_bus
62 | U0_PULSE_GEN 31.7709 0.2 5.8835 25.8874 0.0000 PULSE_GEN_0
63 | U0_RST_SYNC 51.7748 0.2 0.0000 51.7748 0.0000 RST_SYNC_0
64 | U0_RegFile 3344.1814 15.9 1400.2730 1943.9084 0.0000 RegFile_BUS_WIDTH8_DEPTH8_ADDR_WIDTH4_PAR_EN1_PAR_TYPE0_PRESCALE32_DIV_RATIO32
65 | U0_SYS_CTRL 1061.3834 5.1 746.0278 315.3556 0.0000 SYS_CTRL_ALU_WIDTH16_ADDR_WIDTH4_DATA_BUS_WIDTH8_ALUFN_WIDTH4
66 | U0_UART_RX 2179.2484 10.4 7.0602 0.0000 0.0000 UART_RX_WIDTH8
67 | U0_UART_RX/U0_FSM 327.1226 1.6 223.5730 103.5496 0.0000 UART_RX_FSM
68 | U0_UART_RX/U0_data_sampling 511.8645 2.4 434.2023 77.6622 0.0000 data_sampling
69 | U0_UART_RX/U0_deserializer 603.6471 2.9 163.5613 440.0858 0.0000 deserializer
70 | U0_UART_RX/U0_edge_bit_counter 594.2335 2.8 361.2469 232.9866 0.0000 edge_bit_counter
71 | U0_UART_RX/U0_parity_check 114.1399 0.5 114.1399 0.0000 0.0000 parity_check
72 | U0_UART_RX/U0_start_check 5.8835 0.0 5.8835 0.0000 0.0000 start_check
73 | U0_UART_RX/U0_stop_check 15.2971 0.1 15.2971 0.0000 0.0000 stop_check
74 | U0_UART_TX 1163.7563 5.5 10.5903 0.0000 0.0000 UART_TX
75 | U0_UART_TX/U0_FSM 180.0351 0.9 102.3729 77.6622 0.0000 FSM
76 | U0_UART_TX/U0_MUX 36.4777 0.2 36.4777 0.0000 0.0000 MUX
77 | U0_UART_TX/U0_parity_calc 394.1945 1.9 187.0953 207.0992 0.0000 parity_calc
78 | U0_UART_TX/U0_serializer 542.4587 2.6 205.9225 336.5362 0.0000 serializer
79 | U1_ClkDiv 970.7775 4.6 494.2140 258.8740 0.0000 ClkDiv
80 | U1_ClkDiv/add_50 107.0797 0.5 107.0797 0.0000 0.0000 ClkDiv_DW01_inc_0
81 | U1_ClkDiv/add_74 110.6098 0.5 110.6098 0.0000 0.0000 ClkDiv_DW01_inc_1
82 | U1_RST_SYNC 51.7748 0.2 0.0000 51.7748 0.0000 RST_SYNC_1
83 | -------------------------------- ---------- ------- ---------- --------- ------ ------------------------------------------------------------------------------
84 | Total 13563.8211 7436.7439 0.0000
85 |
86 | 1
87 |
--------------------------------------------------------------------------------
/BACKEND/DFT/power.rpt:
--------------------------------------------------------------------------------
1 | Information: Propagating switching activity (low effort zero delay simulation). (PWR-6)
2 | Warning: Design has unannotated primary inputs. (PWR-414)
3 | Warning: Design has unannotated sequential cell outputs. (PWR-415)
4 |
5 | ****************************************
6 | Report : power
7 | -hier
8 | -analysis_effort low
9 | Design : SYS_TOP
10 | Version: K-2015.06
11 | Date : Mon Sep 25 23:00:26 2023
12 | ****************************************
13 |
14 |
15 | Library(s) Used:
16 |
17 | scmetro_tsmc_cl013g_rvt_ss_1p08v_125c (File: /home/IC/tsmc_fb_cl013g_sc/aci/sc-m/synopsys/scmetro_tsmc_cl013g_rvt_ss_1p08v_125c.db)
18 |
19 |
20 | Operating Conditions: scmetro_tsmc_cl013g_rvt_ss_1p08v_125c Library: scmetro_tsmc_cl013g_rvt_ss_1p08v_125c
21 | Wire Load Model Mode: top
22 |
23 |
24 | Global Operating Voltage = 1.08
25 | Power-specific unit information :
26 | Voltage Units = 1V
27 | Capacitance Units = 1.000000pf
28 | Time Units = 1ns
29 | Dynamic Power Units = 1mW (derived from V,C,T units)
30 | Leakage Power Units = 1pW
31 |
32 |
33 | --------------------------------------------------------------------------------
34 | Switch Int Leak Total
35 | Hierarchy Power Power Power Power %
36 | --------------------------------------------------------------------------------
37 | SYS_TOP 2.51e-02 0.112 1.32e+07 0.150 100.0
38 | U0_ClkGate (ClkGate) 3.79e-05 4.61e-04 2.09e+04 5.20e-04 0.3
39 | U0_UART_TX (UART_TX_test_1) 2.11e-04 3.00e-03 7.08e+05 3.92e-03 2.6
40 | U0_MUX (MUX) 1.26e-07 4.22e-07 2.28e+04 2.33e-05 0.0
41 | U0_parity_calc (parity_calc_test_1)
42 | 6.83e-06 1.00e-03 2.56e+05 1.27e-03 0.8
43 | U0_FSM (FSM_test_1) 1.79e-06 3.77e-04 1.16e+05 4.96e-04 0.3
44 | U0_serializer (serializer_test_1) 2.02e-04 1.62e-03 3.10e+05 2.13e-03 1.4
45 | U0_PULSE_GEN (PULSE_GEN_test_1) 2.29e-08 1.20e-04 1.80e+04 1.38e-04 0.1
46 | U1_ClkDiv (ClkDiv_test_1) 5.25e-04 4.15e-03 6.83e+05 5.35e-03 3.6
47 | add_74 (ClkDiv_DW01_inc_1) 3.12e-05 4.66e-05 8.90e+04 1.67e-04 0.1
48 | add_50 (ClkDiv_DW01_inc_0) 2.97e-05 4.32e-05 9.67e+04 1.70e-04 0.1
49 | U0_ClkDiv (ClkDiv_RATIO_WIDTH6_test_1)
50 | 2.95e-04 3.64e-03 5.37e+05 4.47e-03 3.0
51 | U1_RST_SYNC (RST_SYNC_test_1) 1.10e-05 7.77e-04 2.88e+04 8.17e-04 0.5
52 | U0_RST_SYNC (RST_SYNC_test_0) 8.60e-06 7.06e-04 2.86e+04 7.43e-04 0.5
53 | U0_ASYNC_FIFO (ASYNC_FIFO_DATA_WIDTH8_MEM_DEPTH8_PTR_WIDTH4_test_1)
54 | 9.71e-04 2.31e-02 2.39e+06 2.65e-02 17.6
55 | U1_GRAY_CONV (GRAY_CONV_PTR_WIDTH4_1)
56 | 0.000 0.000 3.94e+04 3.94e-05 0.0
57 | U0_GRAY_CONV (GRAY_CONV_PTR_WIDTH4_0)
58 | 5.11e-06 1.05e-05 3.96e+04 5.52e-05 0.0
59 | U1_DF_SYNC (DF_SYNC_BUS_WIDTH4_test_1)
60 | 3.29e-06 2.23e-03 1.05e+05 2.34e-03 1.6
61 | U0_DF_SYNC (DF_SYNC_BUS_WIDTH4_test_0)
62 | 3.00e-07 1.04e-03 1.08e+05 1.15e-03 0.8
63 | U0_FIFO_WR (FIFO_WR_PTR_WIDTH4_test_1)
64 | 1.23e-04 1.83e-03 1.88e+05 2.14e-03 1.4
65 | U0_FIFO_RD (FIFO_RD_PTR_WIDTH4_test_1)
66 | 5.54e-07 6.36e-04 2.05e+05 8.41e-04 0.6
67 | U0_FIFO_MEM_CNTRL (FIFO_MEM_CNTRL_DATA_WIDTH8_MEM_DEPTH8_PTR_WIDTH4_test_1)
68 | 8.40e-04 1.74e-02 1.69e+06 1.99e-02 13.2
69 | U0_RegFile (RegFile_BUS_WIDTH8_DEPTH8_ADDR_WIDTH4_PAR_EN1_PAR_TYPE0_PRESCALE32_DIV_RATIO32_test_1)
70 | 1.83e-03 2.21e-02 1.92e+06 2.59e-02 17.2
71 | U0_ALU (ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_test_1)
72 | 4.64e-04 3.27e-02 4.35e+06 3.75e-02 24.9
73 | mult_23 (ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW02_mult_0)
74 | 4.11e-05 2.36e-05 1.66e+06 1.72e-03 1.1
75 | add_21 (ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW01_add_0)
76 | 6.28e-06 5.78e-05 2.10e+05 2.74e-04 0.2
77 | sub_22 (ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW01_sub_0)
78 | 7.50e-06 5.80e-05 2.48e+05 3.13e-04 0.2
79 | div_24 (ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW_div_uns_0)
80 | 5.08e-05 2.38e-04 1.24e+06 1.53e-03 1.0
81 | U0_SYS_CTRL (SYS_CTRL_ALU_WIDTH16_ADDR_WIDTH4_DATA_BUS_WIDTH8_ALUFN_WIDTH4_test_1)
82 | 1.05e-03 4.80e-03 6.67e+05 6.51e-03 4.3
83 | U0_DATA_SYNC (DATA_SYNC_BUS_WIDTH8_test_1)
84 | 2.21e-05 3.29e-03 2.07e+05 3.52e-03 2.3
85 | U0_sync_bus (sync_bus_test_1) 1.23e-05 2.17e-03 1.49e+05 2.33e-03 1.5
86 | U0_DS_pulse (DS_pulse_test_1) 8.21e-06 5.58e-04 3.13e+04 5.97e-04 0.4
87 | inst_PULSE_GEN (PULSE_GEN_test_0)
88 | 3.94e-06 2.77e-04 1.77e+04 2.99e-04 0.2
89 | U0_multi_ff (multi_ff_test_1) 1.62e-06 5.68e-04 2.64e+04 5.96e-04 0.4
90 | U0_UART_RX (UART_RX_WIDTH8_test_1) 1.18e-03 9.97e-03 1.46e+06 1.26e-02 8.4
91 | U0_parity_check (parity_check) 2.31e-05 8.48e-05 1.14e+05 2.22e-04 0.1
92 | U0_stop_check (stop_check) 0.000 0.000 1.31e+04 1.31e-05 0.0
93 | U0_start_check (start_check) 0.000 0.000 2.93e+03 2.93e-06 0.0
94 | U0_deserializer (deserializer_test_1)
95 | 7.00e-05 4.24e-03 3.49e+05 4.65e-03 3.1
96 | U0_data_sampling (data_sampling_test_1)
97 | 2.15e-04 1.23e-03 3.82e+05 1.83e-03 1.2
98 | U0_edge_bit_counter (edge_bit_counter_test_1)
99 | 5.20e-04 3.01e-03 4.05e+05 3.93e-03 2.6
100 | U0_FSM (UART_RX_FSM_test_1) 3.56e-04 1.41e-03 1.89e+05 1.96e-03 1.3
101 | U7_mux2X1 (mux2X1_7) 2.45e-03 2.02e-04 2.35e+04 2.67e-03 1.8
102 | U6_mux2X1 (mux2X1_0) 5.18e-03 2.59e-04 2.35e+04 5.46e-03 3.6
103 | U5_mux2X1 (mux2X1_2) 1.11e-04 8.75e-05 1.15e+04 2.10e-04 0.1
104 | U4_mux2X1 (mux2X1_3) 3.66e-03 1.84e-03 1.15e+04 5.52e-03 3.7
105 | U3_mux2X1 (mux2X1_4) 2.67e-04 7.03e-05 1.14e+04 3.49e-04 0.2
106 | U2_mux2X1 (mux2X1_5) 9.64e-06 2.21e-06 1.29e+04 2.47e-05 0.0
107 | U1_mux2X1 (mux2X1_6) 5.21e-04 1.93e-04 1.15e+04 7.26e-04 0.5
108 | U0_mux2X1 (mux2X1_1) 4.01e-03 2.66e-04 1.14e+04 4.29e-03 2.8
109 | 1
110 |
--------------------------------------------------------------------------------
/Register File/RegFile_tb.v:
--------------------------------------------------------------------------------
1 | module RegFile_tb ();
2 |
3 | /*******************************************************************/
4 | ///////////////////// TB Signals Declaration ////////////////////////
5 | /*******************************************************************/
6 | parameter BUS_WIDTH = 16 , DEPTH = 8, ADDR_WIDTH = ($clog2(DEPTH)+1);
7 | parameter CLK_PERIOD = 10 , HALF_PERIOD = (CLK_PERIOD/2);
8 | parameter HIGH = 1 , LOW = 0;
9 |
10 | defparam DUT.BUS_WIDTH = BUS_WIDTH;
11 | defparam DUT.ADDR_WIDTH = ADDR_WIDTH;
12 | defparam DUT.DEPTH = DEPTH;
13 |
14 | // interface ports
15 | reg CLK ; // Clock Signal
16 | reg RST ; // Active Low Reset
17 | reg WrEn ; // Write Enable
18 | reg RdEn ; // Read Enable
19 | reg [ADDR_WIDTH-1:0] Address ; // Address bus
20 | reg [BUS_WIDTH-1 :0] WrData ; // Write Data Bus
21 | wire [BUS_WIDTH-1 :0] REG0 ; // Register at Address 0x0
22 | wire [BUS_WIDTH-1 :0] REG1 ; // Register at Address 0x1
23 | wire [BUS_WIDTH-1 :0] REG2 ; // Register at Address 0x2
24 | wire [BUS_WIDTH-1 :0] REG3 ; // Register at Address 0x3
25 | wire [BUS_WIDTH-1 :0] RdData ; // Read Data Bus
26 | wire RdData_Valid ; // Read Data Valid
27 |
28 | // test memory declaration
29 | reg [BUS_WIDTH-1:0] TEST_MEM [DEPTH-1:0];
30 |
31 | /*******************************************************************/
32 | ////////////////////////// Initial Block ////////////////////////////
33 | /*******************************************************************/
34 | initial
35 | begin
36 | $dumpfile("RegFile.vcd");
37 | $dumpvars;
38 | initialize();
39 | init_mem();
40 | reset();
41 |
42 | $display("/******************** Writing Testcases **************************/");
43 | write_data();
44 |
45 | $display("/******************** Reading Testcases **************************/");
46 | read_data();
47 |
48 | $display("/******************** Enables Testcases **************************/");
49 | no_write_no_read();
50 | #(3*CLK_PERIOD) $stop;
51 | end
52 |
53 | /*******************************************************************/
54 | ////////////////////////////// TASKS ////////////////////////////////
55 | /*******************************************************************/
56 | task reset;
57 | begin
58 | RST = LOW;
59 | #HALF_PERIOD
60 | RST = HIGH;
61 | #HALF_PERIOD;
62 | end
63 | endtask
64 | /********************************/
65 | task initialize;
66 | begin
67 | CLK = LOW;
68 | RST = LOW;
69 | WrEn = LOW;
70 | RdEn = LOW;
71 | Address = LOW;
72 | WrData = LOW;
73 | end
74 | endtask
75 | /********************************/
76 | task init_mem;
77 | integer i;
78 | begin
79 | for(i = 0; i < DEPTH; i = i + 1)
80 | begin
81 | TEST_MEM[i] = ($random %(2**BUS_WIDTH-1));
82 | end
83 | end
84 | endtask
85 | /********************************/
86 | task write_data;
87 | integer i;
88 | begin
89 | @(negedge CLK)
90 | WrEn = HIGH;
91 | RdEn = LOW;
92 |
93 | // writing in a memory for loop
94 | for(i = 0; i < DEPTH; i = i + 1)
95 | begin
96 | Address = i;
97 | WrData = TEST_MEM[i];
98 | #CLK_PERIOD;
99 | end
100 |
101 | #CLK_PERIOD
102 |
103 | // checking the memory contents for loop
104 | for(i = 0; i < DEPTH; i = i + 1)
105 | begin
106 | if(DUT.MEM[i] == TEST_MEM[i])
107 | $display("[PASSED]: Write in Address %3b",i);
108 | else
109 | $display("[FAILED]: Write in Address %3b",i);
110 | end
111 |
112 | end
113 | endtask
114 | /********************************/
115 | task read_data;
116 | integer i;
117 | begin
118 | @(negedge CLK)
119 | WrEn = LOW;
120 | RdEn = HIGH;
121 |
122 | // checking the memory contents for loop
123 | for(i = 0; i < DEPTH; i = i + 1)
124 | begin
125 | Address = i;
126 | #CLK_PERIOD
127 | if((RdData == TEST_MEM[i]) && RdData_Valid)
128 | $display("[PASSED]: Read from Address %3b",i);
129 | else
130 | $display("[FAILED]: Read from Address %3b",i);
131 | #CLK_PERIOD;
132 | end
133 | end
134 | endtask
135 | /********************************/
136 | task no_write_no_read;
137 | begin
138 | WrEn = LOW;
139 | RdEn = LOW;
140 | reset();
141 | #(2*CLK_PERIOD)
142 |
143 | WrEn = HIGH;
144 | RdEn = HIGH;
145 | Address = 'h0;
146 | WrData = 'ha1b2;
147 | #CLK_PERIOD
148 | if(DUT.MEM[Address] == 'ha1b2)
149 | $display("[FAILED]: Writing accepted when WrEn = %0b RdEn = %0b",WrEn,RdEn);
150 | else
151 | $display("[PASSED]: Writing rejected when WrEn = %0b RdEn = %0b",WrEn,RdEn);
152 |
153 | #CLK_PERIOD
154 | if(RdData_Valid)
155 | $display("[FAILED]: Reading accepted when WrEn = %0b RdEn = %0b",WrEn,RdEn);
156 | else
157 | $display("[PASSED]: Reading rejected when WrEn = %0b RdEn = %0b",WrEn,RdEn);
158 |
159 | #CLK_PERIOD
160 | WrEn = LOW;
161 | RdEn = LOW;
162 | Address = 'h1;
163 | WrData = 'hb1a2;
164 | #CLK_PERIOD
165 | if(DUT.MEM[Address] == 'hb1a2)
166 | $display("[FAILED]: Writing accepted when WrEn = %0b RdEn = %0b",WrEn,RdEn);
167 | else
168 | $display("[PASSED]: Writing rejected when WrEn = %0b RdEn = %0b",WrEn,RdEn);
169 |
170 | #CLK_PERIOD
171 | if(RdData_Valid)
172 | $display("[FAILED]: Reading accepted when WrEn = %0b RdEn = %0b",WrEn,RdEn);
173 | else
174 | $display("[PASSED]: Reading rejected when WrEn = %0b RdEn = %0b",WrEn,RdEn);
175 |
176 | end
177 | endtask
178 |
179 | /*******************************************************************/
180 | ///////////////////////// Clock Generator ///////////////////////////
181 | /*******************************************************************/
182 | always #HALF_PERIOD CLK = ~CLK;
183 |
184 | /*******************************************************************/
185 | //////////////////////// DUT Instantiation //////////////////////////
186 | /*******************************************************************/
187 | RegFile DUT (
188 | .CLK (CLK) ,
189 | .RST (RST) ,
190 | .WrEn (WrEn) ,
191 | .RdEn (RdEn) ,
192 | .Address (Address) ,
193 | .WrData (WrData) ,
194 | .REG0 (REG0) ,
195 | .REG1 (REG1) ,
196 | .REG2 (REG2) ,
197 | .REG3 (REG3) ,
198 | .RdData (RdData) ,
199 | .RdData_Valid (RdData_Valid) );
200 |
201 | endmodule
--------------------------------------------------------------------------------
/BACKEND/DFT/area.rpt:
--------------------------------------------------------------------------------
1 |
2 | ****************************************
3 | Report : area
4 | Design : SYS_TOP
5 | Version: K-2015.06
6 | Date : Mon Sep 25 23:00:26 2023
7 | ****************************************
8 |
9 | Library(s) Used:
10 |
11 | scmetro_tsmc_cl013g_rvt_ss_1p08v_125c (File: /home/IC/tsmc_fb_cl013g_sc/aci/sc-m/synopsys/scmetro_tsmc_cl013g_rvt_ss_1p08v_125c.db)
12 |
13 | Number of ports: 894
14 | Number of nets: 2652
15 | Number of cells: 1705
16 | Number of combinational cells: 1351
17 | Number of sequential cells: 304
18 | Number of macros/black boxes: 0
19 | Number of buf/inv: 275
20 | Number of references: 27
21 |
22 | Combinational area: 12354.173486
23 | Buf/Inv area: 1119.041721
24 | Noncombinational area: 9419.483751
25 | Macro/Black Box area: 0.000000
26 | Net Interconnect area: undefined (No wire load specified)
27 |
28 | Total cell area: 21773.657238
29 | Total area: undefined
30 |
31 | Hierarchical area distribution
32 | ------------------------------
33 |
34 | Global cell area Local cell area
35 | ------------------- -----------------------------
36 | Hierarchical cell Absolute Percent Combi- Noncombi- Black-
37 | Total Total national national boxes Design
38 | -------------------------------- ---------- ------- ---------- --------- ------ -------------------------------------------------------------------------------------
39 | SYS_TOP 21773.6572 100.0 131.7904 0.0000 0.0000 SYS_TOP
40 | U0_ALU 5832.9020 26.8 1177.8767 560.1092 0.0000 ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_test_1
41 | U0_ALU/add_21 235.3400 1.1 235.3400 0.0000 0.0000 ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW01_add_0
42 | U0_ALU/div_24 1434.3973 6.6 1434.3973 0.0000 0.0000 ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW_div_uns_0
43 | U0_ALU/mult_23 2159.2445 9.9 1918.0210 0.0000 0.0000 ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW02_mult_0
44 | U0_ALU/mult_23/FS_1 241.2235 1.1 241.2235 0.0000 0.0000 ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW01_add_1
45 | U0_ALU/sub_22 265.9342 1.2 265.9342 0.0000 0.0000 ALU_OPRND_WIDTH8_OUT_WIDTH16_CTRL_WIDTH4_DW01_sub_0
46 | U0_ASYNC_FIFO 4544.4156 20.9 27.0641 0.0000 0.0000 ASYNC_FIFO_DATA_WIDTH8_MEM_DEPTH8_PTR_WIDTH4_test_1
47 | U0_ASYNC_FIFO/U0_DF_SYNC 263.5808 1.2 0.0000 263.5808 0.0000 DF_SYNC_BUS_WIDTH4_test_0
48 | U0_ASYNC_FIFO/U0_FIFO_MEM_CNTRL 3313.5873 15.2 1204.9408 2108.6465 0.0000 FIFO_MEM_CNTRL_DATA_WIDTH8_MEM_DEPTH8_PTR_WIDTH4_test_1
49 | U0_ASYNC_FIFO/U0_FIFO_RD 301.2352 1.4 137.6739 163.5613 0.0000 FIFO_RD_PTR_WIDTH4_test_1
50 | U0_ASYNC_FIFO/U0_FIFO_WR 295.3517 1.4 130.6137 164.7380 0.0000 FIFO_WR_PTR_WIDTH4_test_1
51 | U0_ASYNC_FIFO/U0_GRAY_CONV 40.0078 0.2 40.0078 0.0000 0.0000 GRAY_CONV_PTR_WIDTH4_0
52 | U0_ASYNC_FIFO/U1_DF_SYNC 263.5808 1.2 0.0000 263.5808 0.0000 DF_SYNC_BUS_WIDTH4_test_1
53 | U0_ASYNC_FIFO/U1_GRAY_CONV 40.0078 0.2 40.0078 0.0000 0.0000 GRAY_CONV_PTR_WIDTH4_1
54 | U0_ClkDiv 803.6861 3.7 540.1053 263.5808 0.0000 ClkDiv_RATIO_WIDTH6_test_1
55 | U0_ClkGate 24.7107 0.1 0.0000 24.7107 0.0000 ClkGate
56 | U0_DATA_SYNC 480.0936 2.2 0.0000 0.0000 0.0000 DATA_SYNC_BUS_WIDTH8_test_1
57 | U0_DATA_SYNC/U0_DS_pulse 71.7787 0.3 0.0000 32.9476 0.0000 DS_pulse_test_1
58 | U0_DATA_SYNC/U0_DS_pulse/inst_PULSE_GEN
59 | 38.8311 0.2 5.8835 32.9476 0.0000 PULSE_GEN_test_0
60 | U0_DATA_SYNC/U0_multi_ff 65.8952 0.3 0.0000 65.8952 0.0000 multi_ff_test_1
61 | U0_DATA_SYNC/U0_sync_bus 342.4197 1.6 78.8389 263.5808 0.0000 sync_bus_test_1
62 | U0_PULSE_GEN 38.8311 0.2 5.8835 32.9476 0.0000 PULSE_GEN_test_1
63 | U0_RST_SYNC 65.8952 0.3 0.0000 65.8952 0.0000 RST_SYNC_test_0
64 | U0_RegFile 3757.2032 17.3 1352.0283 2405.1749 0.0000 RegFile_BUS_WIDTH8_DEPTH8_ADDR_WIDTH4_PAR_EN1_PAR_TYPE0_PRESCALE32_DIV_RATIO32_test_1
65 | U0_SYS_CTRL 1159.0495 5.3 760.1482 398.9013 0.0000 SYS_CTRL_ALU_WIDTH16_ADDR_WIDTH4_DATA_BUS_WIDTH8_ALUFN_WIDTH4_test_1
66 | U0_UART_RX 2386.3476 11.0 0.0000 0.0000 0.0000 UART_RX_WIDTH8_test_1
67 | U0_UART_RX/U0_FSM 345.9498 1.6 209.4526 136.4972 0.0000 UART_RX_FSM_test_1
68 | U0_UART_RX/U0_data_sampling 529.5150 2.4 427.1421 102.3729 0.0000 data_sampling_test_1
69 | U0_UART_RX/U0_deserializer 714.2569 3.3 135.3205 578.9364 0.0000 deserializer_test_1
70 | U0_UART_RX/U0_edge_bit_counter 661.3054 3.0 354.1867 307.1187 0.0000 edge_bit_counter_test_1
71 | U0_UART_RX/U0_parity_check 114.1399 0.5 114.1399 0.0000 0.0000 parity_check
72 | U0_UART_RX/U0_start_check 5.8835 0.0 5.8835 0.0000 0.0000 start_check
73 | U0_UART_RX/U0_stop_check 15.2971 0.1 15.2971 0.0000 0.0000 stop_check
74 | U0_UART_TX 1330.8477 6.1 3.5301 0.0000 0.0000 UART_TX_test_1
75 | U0_UART_TX/U0_FSM 201.2157 0.9 102.3729 98.8428 0.0000 FSM_test_1
76 | U0_UART_TX/U0_MUX 36.4777 0.2 36.4777 0.0000 0.0000 MUX
77 | U0_UART_TX/U0_parity_calc 450.6761 2.1 187.0953 263.5808 0.0000 parity_calc_test_1
78 | U0_UART_TX/U0_serializer 638.9481 2.9 212.9827 425.9654 0.0000 serializer_test_1
79 | U0_mux2X1 12.9437 0.1 12.9437 0.0000 0.0000 mux2X1_1
80 | U1_ClkDiv 1041.3795 4.8 494.2140 329.4760 0.0000 ClkDiv_test_1
81 | U1_ClkDiv/add_50 107.0797 0.5 107.0797 0.0000 0.0000 ClkDiv_DW01_inc_0
82 | U1_ClkDiv/add_74 110.6098 0.5 110.6098 0.0000 0.0000 ClkDiv_DW01_inc_1
83 | U1_RST_SYNC 65.8952 0.3 0.0000 65.8952 0.0000 RST_SYNC_test_1
84 | U1_mux2X1 11.7670 0.1 11.7670 0.0000 0.0000 mux2X1_6
85 | U2_mux2X1 11.7670 0.1 11.7670 0.0000 0.0000 mux2X1_5
86 | U3_mux2X1 11.7670 0.1 11.7670 0.0000 0.0000 mux2X1_4
87 | U4_mux2X1 11.7670 0.1 11.7670 0.0000 0.0000 mux2X1_3
88 | U5_mux2X1 11.7670 0.1 11.7670 0.0000 0.0000 mux2X1_2
89 | U6_mux2X1 16.4738 0.1 16.4738 0.0000 0.0000 mux2X1_0
90 | U7_mux2X1 22.3573 0.1 22.3573 0.0000 0.0000 mux2X1_7
91 | -------------------------------- ---------- ------- ---------- --------- ------ -------------------------------------------------------------------------------------
92 | Total 12354.1735 9419.4838 0.0000
93 |
94 | 1
95 |
--------------------------------------------------------------------------------
/Asynchronous FIFO/README.md:
--------------------------------------------------------------------------------
1 | # Asynchronous FIFO Block
2 |
3 | ## Overview
4 | The Asynchronous FIFO (First-In, First-Out) block is a crucial component in our system, designed to efficiently manage data storage and retrieval between two asynchronous clock domains. It serves as a 2-port memory with a specified depth, allowing for asynchronous write and read operations.
5 |
6 | ## Block Description
7 | The Asynchronous FIFO block is characterized by the following key features:
8 |
9 | - **Dual Clocks:** It operates with two clocks:
10 | - `W_CLK` (Write Clock): Used for write operations.
11 | - `R_CLK` (Read Clock): Used for read operations.
12 |
13 | - **Dual Addresses:** The FIFO has two address ports:
14 | - Write Address: Determines the location for write operations.
15 | - Read Address: Determines the location for read operations.
16 |
17 | - **Write Operation:** Data is written into the FIFO at the location specified by the write address (`W_INC` and `WR_DATA` inputs).
18 |
19 | - **Read Operation:** Data is read from the FIFO at the location specified by the read address (`R_INC` output and `RD_DATA` output).
20 |
21 | ## Block Interface
22 | The Asynchronous FIFO block has the following interface:
23 |
24 |
25 |
26 |
27 |
28 | - **Inputs:**
29 | - `W_CLK`: Write clock signal.
30 | - `W_RST`: Asynchronous active-low write reset signal.
31 | - `W_INC`: Write address increment signal.
32 | - `R_CLK`: Read clock signal.
33 | - `R_RST`: Asynchronous active-low read reset signal.
34 | - `R_INC`: Read address increment signal.
35 | - `WR_DATA`: Data input for write operations.
36 |
37 | - **Outputs:**
38 | - `FULL`: Signal indicating that the FIFO is full.
39 | - `RD_DATA`: Data output for read operations.
40 | - `EMPTY`: Signal indicating that the FIFO is empty.
41 |
42 | ## Specifications
43 | The Asynchronous FIFO block operates according to the following specifications:
44 |
45 | - Data can be written into the FIFO using the `W_CLK`, `W_RST`, `W_INC`, and `WR_DATA` inputs.
46 |
47 | - Data can be read from the FIFO using the `R_CLK`, `R_RST`, `R_INC`, and `RD_DATA` outputs.
48 |
49 | - The `FULL` signal indicates that the FIFO is full and cannot accept further write operations.
50 |
51 | - The `EMPTY` signal indicates that the FIFO is empty, and no data can be read from it.
52 |
53 | - Asynchronous reset signals `W_RST` and `R_RST` are used to clear the FIFO's state.
54 |
55 | ## Additional Information
56 | The design of this Asynchronous FIFO block is based on the principles outlined in Clifford E. Cummings' paper: "Simulation and Synthesis Techniques for Asynchronous FIFO Design."[^1]
57 |
58 | ## The Block Diagram for FIFO
59 |
60 | 
61 |
62 | To facilitate static timing analysis of the style #1 FIFO design, the design has been partitioned into the following six
63 | Verilog modules with the following functionality and clock domains:
64 |
65 | ### 1. Wrapper Module ([ASYNC_FIFO.v](./ASYNC_FIFO.v))
66 | - This top-level wrapper module includes all clock domains and serves as a wrapper to instantiate other FIFO modules.
67 | - In a larger ASIC or FPGA design, this top-level wrapper may be discarded to group FIFO modules into their respective clock domains for improved synthesis and static timing analysis.
68 |
69 | 
70 |
71 | ### 2. FIFO Memory Buffer ([FIFO_MEM_CNTRL.v](./FIFO_MEM_CNTRL.v))
72 | - The FIFO memory buffer is accessed by both the write and read clock domains.
73 | - Typically, this buffer is implemented as a synchronous dual-port RAM, although other memory styles can be adapted for use as the FIFO buffer.
74 |
75 |
76 |
77 |
78 |
79 | ### 3. Read-to-Write Synchronizer ([DF_SYNC.v](./DF_SYNC.v))
80 | - This module synchronizes the read pointer into the write-clock domain.
81 | - The synchronized read pointer is used by the `FIFO_WR` module to generate the FIFO full condition.
82 | - This module contains flip-flops synchronized to the write clock, without additional logic.
83 |
84 |
85 |
86 |
87 |
88 | ### 4. Write-to-Read Synchronizer ([DF_SYNC.v](./DF_SYNC.v))
89 | - This module synchronizes the write pointer into the read-clock domain.
90 | - The synchronized write pointer is used by the `FIFO_RD` module to generate the FIFO empty condition.
91 | - Similar to `sync_r2w.v`, this module contains flip-flops synchronized to the read clock, without additional logic.
92 |
93 |
94 |
95 |
96 |
97 | ### 5. Read Pointer and Empty-Flag Logic ([FIFO_RD.v](./FIFO_RD.v))
98 | - This module operates entirely within the read-clock domain.
99 | - It contains the FIFO read pointer and logic for generating the empty condition.
100 |
101 |
102 |
103 |
104 |
105 | ### 6. Write Pointer and Full-Flag Logic ([FIFO_WR.v](./FIFO_WR.v))
106 | - This module operates entirely within the write-clock domain.
107 | - It contains the FIFO write pointer and logic for generating the full condition.
108 |
109 |
110 |
111 |
112 |
113 | ### 7. Gray Code Converter ([GRAY_CONV.v](./GRAY_CONV.v))
114 | - The `GRAY_CONV.v` module is responsible for converting binary pointers into Gray encoded pointers.
115 | - Gray encoding is used to decrease synchronization errors when passing pointers between clock domains, ensuring reliable calculation of empty and full flags.
116 |
117 |
118 |
119 |
120 |
121 | ## [Testbench](./ASYNC_FIFO_tb.v)
122 |
123 | 
124 |
125 | ```
126 | MEMORY[ 0]: CAPTURE PASSED
127 | MEMORY[ 1]: CAPTURE PASSED
128 | MEMORY[ 2]: CAPTURE PASSED
129 | MEMORY[ 3]: CAPTURE PASSED
130 | MEMORY[ 4]: CAPTURE PASSED
131 | MEMORY[ 5]: CAPTURE PASSED
132 | MEMORY[ 6]: CAPTURE PASSED
133 | MEMORY[ 7]: CAPTURE PASSED
134 | MEMORY[ 8]: CAPTURE PASSED
135 | MEMORY[ 9]: CAPTURE PASSED
136 | MEMORY[10]: CAPTURE PASSED
137 | MEMORY[11]: CAPTURE PASSED
138 | MEMORY[12]: CAPTURE PASSED
139 | MEMORY[13]: CAPTURE PASSED
140 | MEMORY[14]: CAPTURE PASSED
141 | MEMORY[15]: CAPTURE PASSED
142 | ```
143 |
144 | [^1]: https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwjcscnm_MKBAxWpV6QEHcLyDzQQFnoECBoQAQ&url=http%3A%2F%2Fwww.sunburst-design.com%2Fpapers%2FCummingsSNUG2002SJ_FIFO1.pdf&usg=AOvVaw3-qzaucL9OsvhhA5RKZqaM&opi=89978449
145 |
--------------------------------------------------------------------------------
/BACKEND/README.md:
--------------------------------------------------------------------------------
1 | # ASIC Flow Overview
2 | This document provides an overview of the Application-Specific Integrated Circuit (ASIC) design flow, outlining the key phases from RTL design to DFT insertion. Each phase contributes to the successful creation of a custom digital integrated circuit.
3 |
4 | ## RTL Design
5 | The RTL (Register-Transfer Level) design phase is the starting point for ASIC development. During this phase, the system's functionality is described using hardware description languages (HDLs) like Verilog or VHDL. Designers create high-level representations of digital logic, specifying the interconnections and operations of various components within the ASIC.
6 |
7 | ### [SYS_TOP](https://github.com/AhmedAmrAbdellatif1/Multi-Clock-Domain-System/blob/e372c26c84a87c1082fa384b7910256214bcdd2b/SYS_TOP.v) Simulation Result
8 | 
9 | 
10 |
11 | ```
12 | # Write Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=0 PRESCALE=32
13 | # Read Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=0 PRESCALE=32
14 | # ALU Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=0 PRESCALE=32
15 | # ALU Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=0 PRESCALE=32
16 | # Write Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=1 PRESCALE=32
17 | # Read Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=1 PRESCALE=32
18 | # ALU Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=1 PRESCALE=32
19 | # ALU Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=1 PRESCALE=32
20 | # Write Operation is succeeded with configurations PARITY_ENABLE=0 PARITY_TYPE=0 PRESCALE=32
21 | # Read Operation is succeeded with configurations PARITY_ENABLE=0 PARITY_TYPE=0 PRESCALE=32
22 | # ALU Operation is succeeded with configurations PARITY_ENABLE=0 PARITY_TYPE=0 PRESCALE=32
23 | # ALU Operation is succeeded with configurations PARITY_ENABLE=0 PARITY_TYPE=0 PRESCALE=32
24 | # Write Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=0 PRESCALE=16
25 | # Read Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=0 PRESCALE=16
26 | # ALU Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=0 PRESCALE=16
27 | # ALU Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=0 PRESCALE=16
28 | # Write Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=1 PRESCALE=16
29 | # Read Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=1 PRESCALE=16
30 | # ALU Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=1 PRESCALE=16
31 | # ALU Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=1 PRESCALE=16
32 | # Write Operation is succeeded with configurations PARITY_ENABLE=0 PARITY_TYPE=0 PRESCALE=16
33 | # Read Operation is succeeded with configurations PARITY_ENABLE=0 PARITY_TYPE=0 PRESCALE=16
34 | # ALU Operation is succeeded with configurations PARITY_ENABLE=0 PARITY_TYPE=0 PRESCALE=16
35 | # ALU Operation is succeeded with configurations PARITY_ENABLE=0 PARITY_TYPE=0 PRESCALE=16
36 | # Write Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=0 PRESCALE= 8
37 | # Read Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=0 PRESCALE= 8
38 | # ALU Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=0 PRESCALE= 8
39 | # ALU Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=0 PRESCALE= 8
40 | # Write Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=1 PRESCALE= 8
41 | # Read Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=1 PRESCALE= 8
42 | # ALU Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=1 PRESCALE= 8
43 | # ALU Operation is succeeded with configurations PARITY_ENABLE=1 PARITY_TYPE=1 PRESCALE= 8
44 | # Write Operation is succeeded with configurations PARITY_ENABLE=0 PARITY_TYPE=0 PRESCALE= 8
45 | # Read Operation is succeeded with configurations PARITY_ENABLE=0 PARITY_TYPE=0 PRESCALE= 8
46 | # ALU Operation is succeeded with configurations PARITY_ENABLE=0 PARITY_TYPE=0 PRESCALE= 8
47 | # ALU Operation is succeeded with configurations PARITY_ENABLE=0 PARITY_TYPE=0 PRESCALE= 8
48 | ```
49 |
50 | ## [Synthesis](https://github.com/AhmedAmrAbdellatif1/Multi-Clock-Domain-System/tree/523d0aed7bb8a34674a57778fa5e1acd2a9f78f2/System%20Top/Synthesis)
51 | Once the RTL design is complete, synthesis is the next crucial step. In this phase, the RTL code is transformed into a gate-level netlist. The synthesis tool maps the RTL description onto specific target libraries, optimizing for factors like area, power, and speed. The result is a gate-level representation of the design, which can be further optimized.
52 |
53 | 
54 |
55 | ## Post-Synthesis Formal Verification
56 | After synthesis, formal verification techniques are employed to ensure that the gate-level netlist accurately reflects the original RTL design. Formal methods, such as model checking and equivalence checking, are used to mathematically verify that the design behaves as intended. This phase helps identify and rectify any discrepancies introduced during synthesis.
57 |
58 |
59 |
60 |
61 |
62 | ## [DFT Insertion](https://github.com/AhmedAmrAbdellatif1/Multi-Clock-Domain-System/tree/bbccaeeca005c569c398ab85718bef4f8792171a/System%20Top/DFT)
63 |
64 | Design for Testability (DFT) is a critical phase in ASIC development, aimed at ensuring efficient testing of the final chip. During DFT insertion, various test structures, such as scan chains and boundary scan cells, are added to the design. These structures enable comprehensive testing of the ASIC's functionality and help diagnose and debug any faults.
65 |
66 | 
67 |
68 | ## [Post-DFT Formal Verification](https://github.com/AhmedAmrAbdellatif1/Multi-Clock-Domain-System/tree/bbccaeeca005c569c398ab85718bef4f8792171a/System%20Top/Formal%20Verification%20(POST-DFT))
69 |
70 | Following DFT insertion, formal verification is once again applied to the modified design. This phase ensures that the test structures and DFT logic are correctly integrated into the ASIC and that they do not introduce any unintended behavior. Formal methods play a crucial role in confirming that the DFT enhancements do not compromise the design's integrity.
71 |
72 |
73 |
74 |
75 |
76 | ## Physical Design and Place-and-Route (PnR)
77 | In the Physical Design phase, the logical design is translated into a physical layout. This involves defining the exact locations and sizes of transistors, interconnections, and metal layers on the silicon wafer. The Place-and-Route (PnR) tool plays a crucial role in determining the optimal placement of components and routing of connections to meet performance, power, and area constraints.
78 |
79 | 
80 |
81 | 
82 |
83 |
84 |
--------------------------------------------------------------------------------
/UART/UART RX/README.md:
--------------------------------------------------------------------------------
1 | # UART RX (Receiver) Block
2 |
3 | ## Overview
4 | The UART RX (Receiver) block is a pivotal component in our multi-clock domain system, responsible for receiving UART frames and ensuring data integrity. It plays a crucial role in receiving and processing data from a master device through the UART interface.
5 |
6 | ## Block Description
7 | The UART RX block serves several essential functions:
8 |
9 | - **Receiving UART Frames:** It receives UART frames on the `RX_IN` input and processes them for data extraction.
10 |
11 | - **Oversampling Support:** UART RX supports oversampling by 8, 16, or 32, ensuring accurate data reception even at different clock speeds.
12 |
13 | - **Data Validation:** The block checks the received frame for correctness and integrity. If the frame is corrupted, it raises error flags (`PAR_ERR` for parity error and `STP_ERR` for stop bit error).
14 |
15 | - **Data Extraction:** Once the received frame is verified as correct and not corrupted, data is extracted and sent through the `P_DATA` bus, accompanied by the `DATA_VLD` signal.
16 |
17 | - **Consecutive Frame Acceptance:** UART_RX can accept consecutive frames without any gap, ensuring smooth data reception.
18 |
19 | ## Block Interface
20 | The UART RX block has the following interface:
21 |
22 | 
23 |
24 | - **Inputs:**
25 | - `i_clk`: Clock signal for sequential elements.
26 | - `i_rst_n`: Active-low asynchronous reset signal to clear registers.
27 | - `i_prescale`: Configuration signal for oversampling (8, 16, or 32 times).
28 | - `i_serial_data`: Input for the UART frame data.
29 | - `i_parity_enable`: Configuration signal to enable/disable the frame parity bit (0 for disable, 1 for enable).
30 | - `i_parity_type`: Configuration signal for parity type (0 for even, 1 for odd).
31 |
32 | - **Outputs:**
33 | - `o_data_valid`: Signal indicating the validity of the received data.
34 | - `o_parity_error`: Signal indicating a parity error in the received frame.
35 | - `o_stop_error`: Signal indicating a stop bit error in the received frame.
36 | - `o_parallel_data`: Output bus for the extracted data from the received frame.
37 |
38 | > For a better understanding of how the UART RX block is implemented in RTL (Register-Transfer Level) code, please refer to the [`UART_RX.v`](./UART_RX.v) file in this repository.
39 |
40 | ## Specifications
41 | To effectively use the UART RX block, consider the following specifications:
42 |
43 | - UART RX receives UART frames on the `RX_IN` input.
44 |
45 | - It supports oversampling by 8, 16, or 32 times, ensuring accurate data reception at different clock speeds.
46 |
47 | - The `RX_IN` input is high in the IDLE case (No transmission).
48 |
49 | - The `PAR_ERR` signal is high when the calculated parity bit does not match the received frame's parity bit, indicating a corrupted frame.
50 |
51 | - The `STP_ERR` signal is high when the received stop bit is not equal to 1, indicating a corrupted frame.
52 |
53 | - Data is extracted from the received frame and sent through the `P_DATA` bus, accompanied by the `DATA_VLD` signal, only after verifying that the frame is received correctly and not corrupted (`PAR_ERR = 0` and `STP_ERR = 0`).
54 |
55 | - UART_RX can accept consecutive frames without any gap, ensuring smooth data reception.
56 |
57 | - The block is cleared using the asynchronous active low reset signal `i_rst_n`.
58 |
59 | - Configuration:
60 | - `i_parity_enable` (Parity Configuration):
61 | - 0: Disables the frame parity bit.
62 | - 1: Enables the frame parity bit.
63 | - `i_parity_type` (Parity Type Configuration):
64 | - 0: Specifies even parity.
65 | - 1: Specifies odd parity.
66 |
67 | - The prescale value determines the clock speed of UART_RX to the speed of UART_TX.
68 |
69 | ## Elaborated Design
70 | The UART RX block is composed of several essential components, each serving a unique function:
71 |
72 | 
73 |
74 | ### 1. Deserializer ([deserializer.v](./deserializer.v))
75 | The Deserializer converts the incoming serial data into parallel data, making it accessible for further processing within the block.
76 |
77 | 
78 |
79 | ### 2. Edge Bit Counter ([edge_bit_counter.v](./edge_bit_counter.v))
80 | The Edge Bit Counter is used to determine the sampling time at the mid-time of each bit, ensuring accurate data sampling.
81 |
82 | 
83 |
84 | ### 3. Data Sampling ([data_sampling.v](./data_sampling.v))
85 | Data Sampling is responsible for the actual sampling of the received data, ensuring that the data is captured accurately.
86 |
87 | 
88 |
89 | ### 4. Parity Check ([parity_check.v](./parity_check.v))
90 | The Parity Check component verifies the parity bit in the received frame, ensuring data integrity. If the parity bit does not match, a `PAR_ERR` signal is raised.
91 |
92 | 
93 |
94 | ### 5. Start Bit Check ([start_check.v](./start_check.v))
95 | Start Bit Check verifies the start bit of the received frame to ensure that data reception begins correctly.
96 |
97 |
98 |
99 |
100 |
101 | ### 6. Stop Bit Check ([stop_check.v](./stop_check.v))
102 | Stop Bit Check ensures that the stop bit of the received frame is set to 1, indicating the end of data transmission. If the stop bit is incorrect, an `STP_ERR` signal is raised.
103 |
104 |
105 |
106 |
107 |
108 | ### 7. Finite State Machine (FSM) ([FSM.v](./FSM.v))
109 | The Finite State Machine (FSM) governs the overall flow of the UART RX block, orchestrating the transitions between different states based on received data and control signals.
110 |
111 | 
112 |
113 | ## [Testbench](./UART_RX_tb.v)
114 |
115 | 
116 |
117 | ```
118 | # /*********************** Prescale Testcases *************************/
119 | # Prescale = 8: RX Period = 5ns & TX Period = 40ns [PASSED]
120 | # Prescale = 16: RX Period = 5ns & TX Period = 80ns [PASSED]
121 | # Prescale = 32: RX Period = 5ns & TX Period = 160ns [PASSED]
122 | # /*********************** Even Parity Testcases **********************/
123 | # MISMATCH: 00000000 -> EVEN PARITY TESTCASE [PASSED]
124 | # MISMATCH: 00000000 -> EVEN PARITY TESTCASE [PASSED]
125 | # MISMATCH: 00000000 -> EVEN PARITY TESTCASE [PASSED]
126 | # /************************ Odd Parity Testcases **********************/
127 | # MISMATCH: 00000000 -> ODD PARITY TESTCASE [PASSED]
128 | # MISMATCH: 00000000 -> ODD PARITY TESTCASE [PASSED]
129 | # MISMATCH: 00000000 -> ODD PARITY TESTCASE [PASSED]
130 | # /*********************** NO Parity Testcases ************************/
131 | # MISMATCH: 00000000 -> NO PARITY TESTCASE [PASSED]
132 | # MISMATCH: 00000000 -> NO PARITY TESTCASE [PASSED]
133 | # MISMATCH: 00000000 -> NO PARITY TESTCASE [PASSED]
134 | # /******************** Gliches & Errors Testcases ********************/
135 | # MISMATCH: 00000000 -> START GLITCH TESTCASE [PASSED]
136 | # MISMATCH: 00000000 -> INCORRECT STOP TESTCASE [PASSED]
137 | # MISMATCH: 00000000 -> INCORRECT PARITY TESTCASE [PASSED]
138 | # /*********************** Two Successive Bytes ***********************/
139 | # MISMATCH: 0000000000000000 -> TWO SUCCESSIVE BYTES TESTCASE [PASSED]
140 | # /********************* Multiple Successive Bytes *********************/
141 | ```
142 |
--------------------------------------------------------------------------------
/UART/UART RX/FSM.v:
--------------------------------------------------------------------------------
1 | module UART_RX_FSM #(
2 | parameter NO_STATES = 5 ,
3 | HIGH = 1 ,
4 | LOW = 0 ,
5 | PAR_MAX = 11 ,
6 | STAT_WIDTH = ($clog2(NO_STATES)) ,
7 | FRAME_WIDTH = ($clog2(PAR_MAX) + 1) )
8 | (
9 | input wire clk ,
10 | input wire rst ,
11 | input wire RX_IN ,
12 | input wire par_en ,
13 | input wire par_err ,
14 | input wire start_glitch ,
15 | input wire stop_err ,
16 | input wire [FRAME_WIDTH-2:0] bit_cnt ,
17 | input wire done_sampling ,
18 | output reg par_check_en ,
19 | output reg start_check_en ,
20 | output reg stop_check_en ,
21 | output reg samp_cnt_en ,
22 | output reg deser_en ,
23 | output reg data_valid );
24 |
25 |
26 | // states register declaration
27 | reg [STAT_WIDTH-1:0] current_state, next_state;
28 |
29 | // registering check_error
30 | reg check_error;
31 |
32 | // states encoding using HOT STATE
33 | localparam IDLE = 'b000;
34 | localparam start_bit = 'b001;
35 | localparam serial_data = 'b011;
36 | localparam parity_bit = 'b010;
37 | localparam stop_bit = 'b110;
38 |
39 | // current state sequential logic
40 | always @(posedge clk, negedge rst)
41 | begin
42 | if(!rst)
43 | current_state <= IDLE;
44 | else
45 | current_state <= next_state;
46 | end
47 |
48 | // next state combinational logic
49 | always @(*)
50 | begin
51 | case(current_state)
52 | IDLE: begin
53 | if(!RX_IN)
54 | next_state = start_bit;
55 | else
56 | next_state = IDLE;
57 | end
58 |
59 | start_bit: begin
60 | if((bit_cnt == 'b1) && !check_error)
61 | next_state = serial_data;
62 | else if((bit_cnt == 'b1) && check_error)
63 | next_state = IDLE;
64 | else
65 | next_state = start_bit;
66 | end
67 |
68 | serial_data: begin
69 | if((bit_cnt == 'b1001) && par_en)
70 | next_state = parity_bit;
71 | else if((bit_cnt == 'b1001) && !par_en)
72 | next_state = stop_bit;
73 | else
74 | next_state = serial_data;
75 | end
76 |
77 | parity_bit: begin
78 | if(bit_cnt == 'b1010)
79 | next_state = stop_bit;
80 | else
81 | next_state = parity_bit;
82 | end
83 |
84 | stop_bit: begin
85 | if( ((bit_cnt == 'b0) && RX_IN) || done_sampling && check_error)
86 | next_state = IDLE;
87 | else if((bit_cnt == 'b0) && !RX_IN)
88 | next_state = start_bit;
89 | else
90 | next_state = stop_bit;
91 | end
92 |
93 | default: begin
94 | next_state = IDLE;
95 | end
96 | endcase
97 | end
98 |
99 | // output combinational logic
100 | always @(*)
101 | begin
102 | case(current_state)
103 | IDLE: begin
104 | if(!RX_IN)
105 | begin
106 | samp_cnt_en = HIGH;
107 | start_check_en = LOW;
108 | deser_en = LOW;
109 | par_check_en = LOW;
110 | stop_check_en = LOW;
111 | data_valid = LOW;
112 | end
113 | else
114 | begin
115 | samp_cnt_en = LOW;
116 | start_check_en = LOW;
117 | deser_en = LOW;
118 | par_check_en = LOW;
119 | stop_check_en = LOW;
120 | data_valid = LOW;
121 | end
122 | end
123 |
124 | start_bit: begin
125 | if((bit_cnt == 'b1) && start_glitch)
126 | begin
127 | samp_cnt_en = LOW;
128 | start_check_en = LOW;
129 | deser_en = LOW;
130 | par_check_en = LOW;
131 | stop_check_en = LOW;
132 | data_valid = LOW;
133 | end
134 | else if((bit_cnt == 'b1) && !start_glitch)
135 | begin
136 | samp_cnt_en = HIGH;
137 | start_check_en = LOW;
138 | deser_en = LOW;
139 | par_check_en = LOW;
140 | stop_check_en = LOW;
141 | data_valid = LOW;
142 | end
143 | else
144 | begin
145 | samp_cnt_en = HIGH;
146 | start_check_en = (done_sampling)? HIGH:LOW;
147 | deser_en = LOW;
148 | par_check_en = LOW;
149 | stop_check_en = LOW;
150 | data_valid = LOW;
151 | end
152 | end
153 |
154 | serial_data: begin
155 | if((bit_cnt == 'b1001) && par_en)
156 | begin
157 | samp_cnt_en = HIGH;
158 | start_check_en = LOW;
159 | deser_en = LOW;
160 | par_check_en = LOW;
161 | stop_check_en = LOW;
162 | data_valid = LOW;
163 | end
164 | else if((bit_cnt == 'b1001) && !par_en)
165 | begin
166 | samp_cnt_en = HIGH;
167 | start_check_en = LOW;
168 | deser_en = LOW;
169 | par_check_en = LOW;
170 | stop_check_en = LOW;
171 | data_valid = LOW;
172 | end
173 | else
174 | begin
175 | samp_cnt_en = HIGH;
176 | start_check_en = LOW;
177 | if(done_sampling)
178 | deser_en = HIGH;
179 | else
180 | deser_en = LOW;
181 | par_check_en = LOW;
182 | stop_check_en = LOW;
183 | data_valid = LOW;
184 | end
185 | end
186 |
187 | parity_bit: begin
188 | if(bit_cnt == 'b1010)
189 | begin
190 | samp_cnt_en = HIGH;
191 | start_check_en = LOW;
192 | deser_en = LOW;
193 | par_check_en = LOW;
194 | stop_check_en = LOW;
195 | data_valid = LOW;
196 | end
197 | else
198 | begin
199 | samp_cnt_en = HIGH;
200 | start_check_en = LOW;
201 | deser_en = LOW;
202 | par_check_en = (done_sampling)? HIGH:LOW;
203 | stop_check_en = LOW;
204 | data_valid = LOW;
205 | end
206 | end
207 |
208 | stop_bit: begin
209 | if((bit_cnt == 'b0) && RX_IN)
210 | begin
211 | samp_cnt_en = LOW;
212 | start_check_en = LOW;
213 | deser_en = LOW;
214 | par_check_en = LOW;
215 | stop_check_en = LOW;
216 | data_valid = LOW;
217 | end
218 | else
219 | begin
220 | samp_cnt_en = HIGH;
221 | start_check_en = LOW;
222 | deser_en = LOW;
223 | par_check_en = LOW;
224 | stop_check_en = (done_sampling)? HIGH:LOW;
225 | data_valid = (done_sampling)? ~(check_error):LOW;
226 | end
227 | end
228 | default: begin
229 | samp_cnt_en = LOW;
230 | start_check_en = LOW;
231 | deser_en = LOW;
232 | par_check_en = LOW;
233 | stop_check_en = LOW;
234 | data_valid = LOW;
235 | end
236 | endcase
237 | end
238 |
239 | always @(posedge clk, negedge rst)
240 | begin
241 | if(!rst)
242 | check_error <= 1'b0;
243 | else if(stop_err | par_err | start_glitch)
244 | check_error <= 1'b1;
245 | else if(next_state == IDLE)
246 | check_error <= 1'b0;
247 | end
248 | endmodule
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RTL to GDS Implementation of Low Power Configurable Multi Clock Digital System
2 |
3 | It is responsible of receiving commands through UART receiver to do different system functions as register file reading/writing or doing some processing using ALU block and send result using up to 4 bytes frame through UART transmitter communication protocol
4 |
5 | ## Introduction
6 |
7 | The Low Power Configurable Multi-Clock Digital System is a sophisticated digital design realized in Verilog HDL. It serves as a versatile platform, receiving commands through a UART (Universal Asynchronous Receiver-Transmitter) receiver. It executes a wide range of system functions, including register file operations and complex computations via the ALU (Arithmetic Logic Unit) block. Subsequently, the system transmits results using a 4-byte frame through UART communication.
8 |
9 | ## Overview
10 | ### The system receives a UART Frame from the UART RX block, the first frame determines the needed command, the system offers 4 different operations:
11 | 1. Register File Write command
12 | 2. Register File Read command
13 | 3. ALU Operation command with operand
14 | 4. ALU Operation command with No operand
15 |
16 | **The UART RX parallel data undergoes synchronization before being sent to the System Controller due to the discrepancy in clock domains.**
17 | **The System Controller operates on a 50 MHz REF CLK, while the UART RX functions on a 3.6864 MHz clock.**
18 | **Synchronizing the data is crucial in ensuring its integrity during transfer.**
19 |
20 | After synchronization, the data enters the System Controller, which determines the required operation and configures the necessary control signals. Here's how the System Controller manages different tasks:
21 |
22 | 1. Register File Write Operation (0xAA):
23 |
24 | -It enables the `WrEn` signal of the Register File, indicating a write operation.
25 |
26 | -The desired `Address` for writing is specified.
27 |
28 | 2. Register File Read Operation (0xBB):
29 |
30 | -It enables the `RdEn` signal of the Register File, indicating a read operation.
31 |
32 | -The desired `Address` for reading is specified.
33 |
34 | -The data is retrieved from the Register File and sent to the UART TX.
35 |
36 | > **However, the UART TX operates on a different clock frequency, specifically 115.2 KHz. To prevent data loss due to clock domain crossing (CDC), a `FIFO` (First-In-First-Out) buffer is strategically placed just before the UART TX. This buffer ensures the orderly transmission of data without loss or corruption.**
37 |
38 | 3. ALU (Arithmetic Logic Unit) Operation (0xCC):
39 |
40 | -It activates the `ALU_EN` signal of the ALU, signaling the start of an ALU operation.
41 |
42 | -The `CLK GATE` is enabled to activate the `ALU CLK`, synchronizing it with the ALU operation.
43 |
44 | -The operands required for the operation are obtained from the Register File at the predefined addresses.
45 |
46 | -The desired function for the ALU operation is conveyed using the `ALU_FUN` signal.
47 |
48 | -The result of the ALU operation (`ALU_OUT`) is passed to the System Controller.
49 |
50 | -From there, it is sent to the FIFO for subsequent transmission to the UART TX and, ultimately, to the master.
51 |
52 | 4. ALU Operation without Operand Change (0xDD):
53 |
54 | -This configuration allows the ALU to perform an operation without altering the operands previously defined in the Register File.
55 |
56 | *These well-defined steps ensure efficient data management and processing within the Low Power Configurable Multi-Clock Digital System, even when dealing with disparate clock frequencies and multiple operations.*
57 |
58 | ### To address the presence of multiple clock domains within the system, we have implemented synchronizers.
59 | As mentioned earlier, a [Data Synchronizer](https://github.com/AhmedAmrAbdellatif1/Multi-Clock-Domain-System/tree/405196392bf892d5c6059fc183e1ec9a1a9db0ec/Data%20Synchronizer) is introduced after the UART RX stage. This addition is essential to prevent the occurrence of metastability in the output byte from the UART RX when it interfaces with the SYS CTRL block.
60 |
61 | Furthermore, to mitigate metastability issues during the de-assertion of the reset signal, we have incorporated two [Reset Synchronizers](https://github.com/AhmedAmrAbdellatif1/Multi-Clock-Domain-System/tree/24d94171fbf92b36649f055d8c104d8afbe419e2/Reset%20Synchronizer). Each of these synchronizers is integrated into its respective clock domain group, ensuring that reset signals are effectively synchronized across the system.
62 |
63 | To accommodate various configurations for UART sampling, we connect the highest required frequency to the i_uart_clk port. Subsequently, we utilize a [clock divider](https://github.com/AhmedAmrAbdellatif1/Multi-Clock-Domain-System/tree/54e8705dad16caf8acdef827c448cbae46984f52/Clock%20Divider) to generate both the UART RX Clock and the UART TX Clock
64 |
65 | ## System Architecture
66 |
67 | This system consists of ten distinct blocks, each contributing to its overall functionality. Let's delve into these blocks:
68 |
69 | 
70 |
71 | ### Clock Domain 1 (REF_CLK)
72 |
73 | #### 1. RegFile (Register File)
74 |
75 | The RegFile block serves as a data storage unit, facilitating efficient data storage and retrieval operations.
76 |
77 | #### 2. ALU (Arithmetic Logic Unit)
78 |
79 | The ALU is the computational powerhouse of the system, capable of executing a variety of arithmetic and logic operations.
80 |
81 | #### 3. Clock Gating
82 |
83 | The Clock Gating block optimizes power consumption by controlling clock signals during idle periods, reducing dynamic power consumption.
84 |
85 | #### 4. SYS_CTRL (System Controller)
86 |
87 | SYS_CTRL acts as the central hub of the system. It receives external commands, orchestrates operations across different blocks, and communicates results.
88 |
89 | ### Clock Domain 2 (UART_CLK)
90 |
91 | #### 5. UART_TX (UART Transmitter)
92 |
93 | UART_TX is responsible for transmitting data to an external device or master via UART communication.
94 |
95 | #### 6. UART_RX (UART Receiver)
96 |
97 | UART_RX receives incoming data and commands from external sources, facilitating communication with the system.
98 |
99 | #### 7. PULSE_GEN (Pulse Generator)
100 |
101 | PULSE_GEN generates pulse signals as needed within the system, contributing to various internal operations.
102 |
103 | #### 8. Clock Dividers
104 |
105 | Clock Dividers are essential for generating clocks with different frequencies and ratios, enabling precise control over timing.
106 |
107 | ### Data Synchronizers
108 |
109 | #### 9. RST Synchronizer
110 |
111 | The RST Synchronizer ensures synchronous de-assertion of asynchronous reset signals, addressing timing challenges during system operation.
112 |
113 | #### 10. Data Synchronizer
114 |
115 | The Data Synchronizer employs a unique synchronization scheme to address Clock Domain Crossing challenges, ensuring reliable data transfer between different clock domains.
116 |
117 | ## Reserved Registers
118 |
119 | This system includes several reserved registers, each serving specific functions:
120 |
121 | 1. **REG0 (Address: 0x0) - ALU Operand A**
122 | 2. **REG1 (Address: 0x1) - ALU Operand B**
123 | 3. **REG2 (Address: 0x2) - UART Configuration**
124 | - Bit 0: Parity Enable (Default: 1)
125 | - Bit 1: Parity Type (Default: 0)
126 | - Bits 7-2: Prescale (Default: 32)
127 | 4. **REG3 (Address: 0x3) - Divisor Ratio**
128 | - Bits 7-0: Division ratio (Default: 32)
129 |
130 | ## System Operation
131 |
132 | The system's operation is driven by commands received via UART_RX. It supports a wide range of operations, including ALU operations such as addition, subtraction, multiplication, division, logic operations, comparisons, and shifts. Additionally, it handles register file operations, including read and write commands.
133 |
134 | ### Supported Commands
135 |
136 | 1. Register File Write Command (3 frames)
137 | 2. Register File Read Command (2 frames)
138 | 3. ALU Operation Command with Operand (4 frames)
139 | 4. ALU Operation Command with No Operand (2 frames)
140 |
141 | ## System Specifications
142 |
143 | - Reference Clock (REF_CLK): 50 MHz
144 | - UART Clock (UART_CLK): 3.6864 MHz
145 | - Clock Divider: Always enabled (clock divider enable = 1)
146 |
147 | This system represents a remarkable achievement in digital design, combining versatility, efficiency, and precise control over multi-clock domains. Its wide range of supported operations makes it a valuable asset in various applications.
148 |
149 |
--------------------------------------------------------------------------------
/UART/UART TX/UART_TX_tb.v:
--------------------------------------------------------------------------------
1 | `timescale 1ns/100ps
2 |
3 | module UART_TX_tb();
4 |
5 | /*******************************************************************/
6 | ///////////////////// TB Signals Declaration ////////////////////////
7 | /*******************************************************************/
8 | parameter WIDTH = 8; // width of the input data
9 | parameter par_frame = 11; // frame size with a parity bit
10 | parameter nopar_frame = 10; // frame size without a partiy bit
11 | parameter TESTCASES = 9; // no. of parity testcases
12 | parameter CLK_PERIOD = 5; // 200MHz frequency
13 | parameter HALF_PERIOD = 2.5;
14 | parameter EVEN = 0; // Even Parity => PAR_TYP
15 | parameter ODD = 1; // Odd Parity => PAR_TYP
16 | parameter HIGH = 1;
17 | parameter LOW = 0;
18 |
19 |
20 | // interface ports
21 | reg [WIDTH-1:0] P_DATA;
22 | reg DATA_VALID;
23 | reg PAR_EN;
24 | reg PAR_TYP;
25 | reg CLK;
26 | reg RST;
27 | wire TX_OUT;
28 | wire Busy;
29 |
30 | // register to store output serial data for testing
31 | reg [par_frame-1:0] tx_pdata;
32 | reg [nopar_frame-1:0] tx_npdata;
33 |
34 | // testing memories
35 | reg [WIDTH-1:0] input_data[0:TESTCASES-1];
36 | reg [par_frame-1:0] expec_out [0:TESTCASES-1];
37 |
38 | // control loop index
39 | integer i,n;
40 |
41 | /*******************************************************************/
42 | ////////////////////////// Initial Block ////////////////////////////
43 | /*******************************************************************/
44 | initial
45 | begin
46 | $dumpfile("UART_TX.vcd");
47 | $dumpvars;
48 |
49 | // the .txt files has 9 rows, each 3 rows represet different testcase
50 | // first section: even parity
51 | // second section: odd parity
52 | // third section: no parity
53 | $readmemb("input_data.txt",input_data);
54 | $readmemb("expected_output.txt",expec_out);
55 |
56 | initialize();
57 | reset();
58 |
59 | #CLK_PERIOD
60 | n = 0;
61 |
62 | $display("/********** Even Parity Testcases **********/");
63 | repeat(3)
64 | begin
65 | even_parity(input_data[n],expec_out[n]);
66 | n = n + 1;
67 | #CLK_PERIOD;
68 | end
69 |
70 | $display("/********** Odd Parity Testcases **********/");
71 | repeat(3)
72 | begin
73 | odd_parity(input_data[n],expec_out[n]);
74 | n = n + 1;
75 | #CLK_PERIOD;
76 | end
77 |
78 | $display("/********** NO Parity Testcases **********/");
79 | repeat(3)
80 | begin
81 | NO_parity(input_data[n],expec_out[n]);
82 | n = n + 1;
83 | #CLK_PERIOD;
84 | end
85 |
86 | $display("/**** Passing New Data While Transmission ****/");
87 | adding_new_data(input_data[0],expec_out[0]);
88 |
89 | // we disabled this feature in FSM.v line 64, un-comment both to enable it
90 | //$display("/********** Two Successive Bytes **********/");
91 | //two_success_bytes(input_data[0],expec_out[0],input_data[3],expec_out[3]);
92 |
93 | #(5*CLK_PERIOD) $stop;
94 | end
95 |
96 | /*******************************************************************/
97 | ////////////////////////////// TASKS ////////////////////////////////
98 | /*******************************************************************/
99 | task reset;
100 | begin
101 | RST = HIGH;
102 | #HALF_PERIOD;
103 | RST = LOW;
104 | #HALF_PERIOD
105 | RST = HIGH;
106 | tx_pdata = 'bx; // evacute the register for another test
107 | tx_npdata = 'bx;
108 | end
109 | endtask
110 | /********************************/
111 | task initialize;
112 | begin
113 | RST = HIGH;
114 | CLK = LOW;
115 | P_DATA = 'b0;
116 | PAR_EN = LOW;
117 | PAR_TYP = LOW;
118 | DATA_VALID = LOW;
119 | end
120 | endtask
121 | /********************************/
122 | task valid;
123 | begin
124 | DATA_VALID = HIGH;
125 | #CLK_PERIOD
126 | DATA_VALID = LOW;
127 | end
128 | endtask
129 | /********************************/
130 | task even_parity;
131 | input [WIDTH-1:0] data; // input parallel data
132 | input [par_frame-1:0] check_data; // expected output data
133 | reg [par_frame-1:0] mismatch; // mismatch bits
134 | integer cycle; // control loop index
135 |
136 | begin
137 | reset();
138 | P_DATA = data;
139 | PAR_EN = HIGH;
140 | PAR_TYP = EVEN;
141 |
142 | valid();
143 |
144 | cycle = par_frame - 1;
145 |
146 | repeat(par_frame) // preserve the output serial data in a register
147 | begin
148 | @(negedge CLK)
149 | tx_pdata[cycle] = TX_OUT;
150 | cycle = cycle - 1;
151 | end
152 |
153 | #CLK_PERIOD
154 | mismatch = tx_pdata - check_data;
155 | if(tx_pdata == check_data)
156 | $display("MISMATCH: %11b -> EVEN PARITY TESTCASE [PASSED]",mismatch);
157 | else
158 | $display("MISMATCH: %11b -> EVEN PARITY TESTCASE [FAILED]",mismatch);
159 |
160 | #CLK_PERIOD;
161 | end
162 | endtask
163 | /********************************/
164 | task odd_parity;
165 | input [WIDTH-1:0] data;
166 | input [par_frame-1:0] check_data;
167 |
168 | reg [par_frame-1:0] mismatch;
169 | integer cycle;
170 | begin
171 | reset();
172 | P_DATA = data;
173 | PAR_EN = HIGH;
174 | PAR_TYP = ODD;
175 |
176 | valid();
177 |
178 | cycle = par_frame - 1;
179 | repeat(par_frame)
180 | begin
181 | @(negedge CLK)
182 | tx_pdata[cycle] = TX_OUT;
183 | cycle = cycle - 1;
184 | end
185 | #CLK_PERIOD
186 | mismatch = tx_pdata - check_data;
187 | if(tx_pdata == check_data)
188 | $display("MISMATCH: %11b -> ODD PARITY TESTCASE [PASSED]",mismatch);
189 | else
190 | $display("MISMATCH: %11b -> ODD PARITY TESTCASE [FAILED]",mismatch);
191 |
192 | #CLK_PERIOD;
193 | end
194 | endtask
195 | /********************************/
196 | task NO_parity;
197 | input [WIDTH-1:0] data;
198 | input [nopar_frame-1:0] check_data;
199 |
200 | reg [nopar_frame-1:0] mismatch;
201 | integer cycle;
202 | begin
203 | reset();
204 | P_DATA = data;
205 | PAR_EN = LOW;
206 |
207 | valid();
208 |
209 | cycle = nopar_frame - 1;
210 | repeat(nopar_frame)
211 | begin
212 | @(negedge CLK)
213 | tx_npdata[cycle] = TX_OUT;
214 | cycle = cycle - 1;
215 | end
216 | #CLK_PERIOD
217 | mismatch = tx_npdata - check_data;
218 | if(tx_npdata == check_data)
219 | $display("MISMATCH: %11b -> NO PARITY TESTCASE [PASSED]",mismatch);
220 | else
221 | $display("MISMATCH: %11b -> NO PARITY TESTCASE [FAILED]",mismatch);
222 |
223 | #CLK_PERIOD;
224 | end
225 | endtask
226 | /********************************/
227 | task two_success_bytes;
228 | input [WIDTH-1:0] data_1;
229 | input [par_frame-1:0] check_data_1;
230 | input [WIDTH-1:0] data_2;
231 | input [par_frame-1:0] check_data_2;
232 |
233 | reg [2*(par_frame)-1:0] tx_o_data;
234 | reg [2*(par_frame)-1:0] mismatch;
235 | integer cycle;
236 | begin
237 | reset();
238 | P_DATA = data_1;
239 |
240 | PAR_EN = HIGH;
241 | PAR_TYP = EVEN;
242 |
243 | valid();
244 |
245 | cycle = 2*(par_frame)-1;
246 | repeat(par_frame)
247 | begin
248 | @(negedge CLK)
249 | tx_o_data[cycle] = TX_OUT;
250 | cycle = cycle - 1;
251 | end
252 |
253 | begin
254 | DATA_VALID = HIGH;
255 | P_DATA = data_2;
256 | PAR_EN = HIGH;
257 | PAR_TYP = ODD;
258 | end
259 |
260 | #CLK_PERIOD;
261 | DATA_VALID = LOW;
262 | repeat(par_frame)
263 | begin
264 | @(negedge CLK)
265 | tx_o_data[cycle] = TX_OUT;
266 | cycle = cycle - 1;
267 | end
268 |
269 | #CLK_PERIOD
270 | mismatch = tx_o_data - {check_data_1,check_data_2};
271 | if(!mismatch)
272 | $display("MISMATCH: %22b -> TWO SUCCESSIVE BYTES TESTCASE [PASSED]",mismatch);
273 | else
274 | $display("MISMATCH: %22b -> TWO SUCCESSIVE BYTES [FAILED]",mismatch);
275 |
276 | #CLK_PERIOD;
277 | end
278 | endtask
279 | /********************************/
280 | task adding_new_data;
281 | input [WIDTH-1:0] data; // input parallel data
282 | input [par_frame-1:0] check_data; // expected output data
283 | reg [par_frame-1:0] mismatch; // mismatch bits
284 |
285 | integer RANDOM;
286 | integer cycle; // control loop index
287 |
288 | begin
289 | reset();
290 | P_DATA = data;
291 | PAR_EN = HIGH;
292 | PAR_TYP = EVEN;
293 | valid();
294 |
295 | cycle = par_frame - 1;
296 |
297 | repeat(par_frame) // preserve the output serial data in a register
298 | begin
299 | @(negedge CLK)
300 | RANDOM = $urandom %127; // random 7-bit generator
301 | tx_pdata[cycle] = TX_OUT;
302 | cycle = cycle - 1;
303 | P_DATA = {RANDOM,~^(RANDOM)}; // random 8-bit odd parity generator
304 | end
305 |
306 | #CLK_PERIOD
307 | mismatch = tx_pdata - check_data;
308 | if(tx_pdata == check_data)
309 | $display("MISMATCH: %11b -> IGNORING INPUT TESTCASE [PASSED]",mismatch);
310 | else
311 | $display("MISMATCH: %11b -> IGNORING INPUT TESTCASE [FAILED]",mismatch);
312 |
313 | #CLK_PERIOD;
314 | end
315 | endtask
316 | /********************************/
317 |
318 | /*******************************************************************/
319 | ///////////////////////// Clock Generator ///////////////////////////
320 | /*******************************************************************/
321 | always #HALF_PERIOD CLK = ~CLK;
322 |
323 | /*******************************************************************/
324 | //////////////////////// DUT Instantiation //////////////////////////
325 | /*******************************************************************/
326 | UART_TX DUT ( .P_DATA(P_DATA),
327 | .DATA_VALID(DATA_VALID),
328 | .PAR_EN(PAR_EN),
329 | .PAR_TYP(PAR_TYP),
330 | .CLK(CLK),
331 | .RST(RST),
332 | .TX_OUT(TX_OUT),
333 | .Busy(Busy) );
334 | endmodule
335 |
--------------------------------------------------------------------------------
/SYS_TOP.v:
--------------------------------------------------------------------------------
1 | //***************************************************************************************************************//
2 | // Module: SYS_TOP.Valid
3 | // Project: Multi Clock Domain System
4 | // Description:
5 | //***************************************************************************************************************//
6 |
7 | module SYS_TOP #( parameter MEM_DEPTH = 8 , // RegFile and FIFO depth
8 | parameter BUS_WIDTH = 8 , // data bus width
9 | parameter ALU_WIDTH = 16 , // ALU output max width
10 | parameter ADDR_WIDTH = 4 , // address width
11 | parameter ALUFN_WIDTH = 4 , // ALU func width
12 | parameter PAR_EN = 1 , // parity enable
13 | parameter PAR_TYPE = 0 , // parity type
14 | parameter PRESCALE = 32 , // prescale value
15 | parameter DIV_RATIO = 32 , // clock div ratio
16 | parameter PTR_WIDTH = ($clog2(MEM_DEPTH)+1) ) // pointer width
17 |
18 | ( input wire i_ref_clk , // reference clock signal
19 | input wire i_uart_clk , // UART clock signal
20 | input wire i_rst_n , // Asynchronous active-low reset signal
21 | input wire i_rx_in , // input serial data
22 | output wire o_parity_err , // parity bit error
23 | output wire o_stop_err , // stop bit error
24 | output wire o_tx_out ); // output serial data
25 |
26 | /******************************************* Internal Signal Declaration *******************************************/
27 | /********* UART RX OUTPUT SIGNALS *********/
28 | wire x_URX_VLD ; // Out Data Valid : connected to DATA_SYNC
29 | wire [BUS_WIDTH-1:0] x_URX_OUT ; // Parallel Out Data Bus : connected to DATA_SYNC
30 |
31 | /******** DATA _SYNC OUTPUT SIGNALS *******/
32 | wire [BUS_WIDTH-1:0] x_DS_OUT ; // Synchronized Data Bus : connected to SYS_CTRL
33 | wire x_DS_pulse ; // Enable Pulse Signal : connected to SYS_CTRL
34 |
35 | /******** Sys Ctrl OUTPUT SIGNALS *********/
36 | wire [ALUFN_WIDTH-1:0] x_ALU_fun ; // ALU Function Signal : connected to ALU
37 | wire x_ALU_en ; // ALU Enable Signal : connected to ALU
38 | wire x_CG_en ; // Clock Gate Enable Signal : connected to CLK_GATE
39 | wire [ADDR_WIDTH-1:0] x_Reg_addr ; // Address Bus : connected to RegFile
40 | wire x_Reg_WrEn ; // Write Enable Signal : connected to RegFile
41 | wire x_Reg_RdEn ; // Read Enable Signal : connected to RegFile
42 | wire [BUS_WIDTH-1:0] x_Reg_WrData ; // Write Data Bus : connected to RegFile
43 | wire [BUS_WIDTH-1:0] x_UTX_data ; // Parallel Data Bus : connected to UART_TX
44 | wire x_UTX_VLD ; // Parallel Data Valid : connected to UART_TX
45 | wire x_CD_en ; // Clock Divider Enable : connected to ClkDiv
46 | wire [BUS_WIDTH-3:0] x_CD_RX ; // Clock Divider RX ratio : connected to ClkDiv
47 |
48 | /*********** ALU OUTPUT SIGNALS ***********/
49 | wire [ALU_WIDTH-1:0] x_ALU_out ; // ALU Result : connected to SYS_CTRL
50 | wire x_ALU_vld ; // Result Valid : connected to SYS_CTRL
51 |
52 | /********* RegFile OUTPUT SIGNALS *********/
53 | wire [BUS_WIDTH-1:0] x_Reg_RdData ; // Read Data Bus : connected to SYS_CTRL
54 | wire [BUS_WIDTH-1:0] x_Reg_REG0 ; // Register at Address 0x0 : connected to ALU
55 | wire [BUS_WIDTH-1:0] x_Reg_REG1 ; // Register at Address 0x1 : connected to ALU
56 | wire [BUS_WIDTH-1:0] x_Reg_REG2 ; // Register at Address 0x2 : connected to UART
57 | wire [BUS_WIDTH-1:0] x_Reg_REG3 ; // Register at Address 0x3 : connected to ClkDiv
58 | wire x_Reg_RdVld ; // Read Data Valid : connected to SYS_CTRL
59 |
60 | /******** ASYNC_FIFO OUTPUT SIGNALS *******/
61 | wire [BUS_WIDTH-1:0] x_FIFO_RData ; // Read Data Bus : connected to UART_TX
62 | wire x_FIFO_EMPTY ; // FIFO Buffer empty flag : connected to UART_TX
63 | wire x_FIFO_FULL ; // FIFO Buffer full flag : connected to SYS_CTRL
64 |
65 | /********** UART TX OUTPUT SIGNALS ********/
66 | wire x_UTX_busy ; // UART TX Status Signal : connected to PULSE_GEN
67 |
68 | /********* Pulse Gen OUTPUT SIGNALS *******/
69 | wire x_PG_pulse ; // Pulse signal : connected to ASYNC_FIFO
70 |
71 | /********* Clk Gate OUTPUT SIGNALS ********/
72 | wire x_CG_ALUclk ; // Gated Clock signal : connected to ALU
73 |
74 | /********* Clk Div OUTPUT SIGNALS *********/
75 | wire x_UTX_CLK ; // Divided Clock Signal : connected to UART_TX
76 | wire x_URX_CLK ; // Divided Clock Signal : connected to UART_RX
77 |
78 | /******** RST_SYNC OUTPUT SIGNALS *********/
79 | wire x_RST_SYNC1 ; // Active Low synchronized Reset : connected to ASYNC_FIFO
80 | wire x_RST_SYNC2 ; // Active Low synchronized Reset : connected to UART
81 |
82 |
83 |
84 | /********************************************* IP Blocks Instantiation *********************************************/
85 | /********* UART RX instantiation **********/
86 | UART_RX #(
87 | .WIDTH ( BUS_WIDTH )
88 |
89 | ) U0_UART_RX (
90 | .i_clk ( x_URX_CLK ) ,
91 | .i_rst_n ( x_RST_SYNC2 ) ,
92 | .i_prescale ( x_Reg_REG2[7:2] ) ,
93 | .i_serial_data ( i_rx_in ) ,
94 | .i_parity_enable ( x_Reg_REG2[0] ) ,
95 | .i_parity_type ( x_Reg_REG2[1] ) ,
96 | .o_parity_error ( o_parity_err ) ,
97 | .o_stop_error ( o_stop_err ) ,
98 | .o_data_valid ( x_URX_VLD ) ,
99 | .o_parallel_data ( x_URX_OUT ) );
100 |
101 | /**** Data Synchronizer instantiation *****/
102 | DATA_SYNC #(
103 | .BUS_WIDTH ( BUS_WIDTH )
104 |
105 | ) U0_DATA_SYNC (
106 | .dest_clk ( i_ref_clk ) ,
107 | .dest_rst ( x_RST_SYNC1 ) ,
108 | .bus_enable ( x_URX_VLD ) ,
109 | .unsync_bus ( x_URX_OUT ) ,
110 | .sync_bus ( x_DS_OUT ) ,
111 | .enable_pulse ( x_DS_pulse ) );
112 |
113 | /********* Sys Ctrl instantiation *********/
114 | SYS_CTRL #(
115 | .ALU_WIDTH ( ALU_WIDTH ),
116 | .ADDR_WIDTH ( ADDR_WIDTH ),
117 | .ALUFN_WIDTH ( ALUFN_WIDTH ),
118 | .DATA_BUS_WIDTH ( BUS_WIDTH )
119 |
120 | ) U0_SYS_CTRL (
121 | .CLK ( i_ref_clk ) ,
122 | .RST ( x_RST_SYNC1 ) ,
123 | .ALU_OUT ( x_ALU_out ) ,
124 | .OUT_Valid ( x_ALU_vld ) ,
125 | .RX_P_Data ( x_DS_OUT ) ,
126 | .RX_D_VLD ( x_DS_pulse ) ,
127 | .RdData ( x_Reg_RdData ) ,
128 | .RdData_Valid ( x_Reg_RdVld ) ,
129 | .Prescale_RX ( x_Reg_REG2[7:2]) ,
130 | .ClkDiv_RX ( x_CD_RX ) ,
131 | .FIFO_FULL ( x_FIFO_FULL ) ,
132 | .ALU_EN ( x_ALU_en ) ,
133 | .ALU_FUN ( x_ALU_fun ) ,
134 | .CLK_EN ( x_CG_en ) ,
135 | .Address ( x_Reg_addr ) ,
136 | .WrEn ( x_Reg_WrEn ) ,
137 | .RdEn ( x_Reg_RdEn ) ,
138 | .WrData ( x_Reg_WrData ) ,
139 | .TX_P_Data ( x_UTX_data ) ,
140 | .TX_D_VLD ( x_UTX_VLD ) ,
141 | .clk_div_en ( x_CD_en ) );
142 |
143 | /*********** ALU instantiation ************/
144 | ALU #(
145 | .OUT_WIDTH( ALU_WIDTH ),
146 | .OPRND_WIDTH( BUS_WIDTH ),
147 | .CTRL_WIDTH( ALUFN_WIDTH )
148 |
149 | ) U0_ALU (
150 | .CLK ( x_CG_ALUclk ) ,
151 | .RST ( x_RST_SYNC1 ) ,
152 | .Enable ( x_ALU_en ) ,
153 | .A ( x_Reg_REG0 ) ,
154 | .B ( x_Reg_REG1 ) ,
155 | .ALU_FUN ( x_ALU_fun ) ,
156 | .ALU_OUT ( x_ALU_out ) ,
157 | .OUT_VALID ( x_ALU_vld ) );
158 |
159 | /********** RegFile instantiation **********/
160 | RegFile #(
161 | .DEPTH ( MEM_DEPTH ),
162 | .PAR_EN ( PAR_EN ),
163 | .PAR_TYPE ( PAR_TYPE ),
164 | .PRESCALE ( PRESCALE ),
165 | .DIV_RATIO ( DIV_RATIO),
166 | .BUS_WIDTH ( BUS_WIDTH ),
167 | .ADDR_WIDTH ( ADDR_WIDTH )
168 |
169 | ) U0_RegFile (
170 | .CLK ( i_ref_clk ) ,
171 | .RST ( x_RST_SYNC1 ) ,
172 | .WrEn ( x_Reg_WrEn ) ,
173 | .RdEn ( x_Reg_RdEn ) ,
174 | .Address ( x_Reg_addr ) ,
175 | .WrData ( x_Reg_WrData ) ,
176 | .REG0 ( x_Reg_REG0 ) ,
177 | .REG1 ( x_Reg_REG1 ) ,
178 | .REG2 ( x_Reg_REG2 ) ,
179 | .REG3 ( x_Reg_REG3 ) ,
180 | .RdData ( x_Reg_RdData ) ,
181 | .RdData_Valid ( x_Reg_RdVld ) );
182 |
183 | /********* ASYNC FIFO instantiation ********/
184 | ASYNC_FIFO #(
185 | .DATA_WIDTH ( BUS_WIDTH ),
186 | .MEM_DEPTH ( MEM_DEPTH ),
187 | .PTR_WIDTH ( PTR_WIDTH )
188 |
189 | ) U0_ASYNC_FIFO (
190 | .i_Wclk ( i_ref_clk ) ,
191 | .i_Wrst_n ( x_RST_SYNC1 ) ,
192 | .i_Winc ( x_UTX_VLD ) ,
193 | .i_Rclk ( x_UTX_CLK ) ,
194 | .i_Rrst_n ( x_RST_SYNC2 ) ,
195 | .i_Rinc ( x_PG_pulse ) ,
196 | .i_Wdata ( x_UTX_data ) ,
197 | .o_full ( x_FIFO_FULL ) ,
198 | .o_Rdata ( x_FIFO_RData ) ,
199 | .o_empty ( x_FIFO_EMPTY ) );
200 |
201 | /********* RST SYNC instantiation **********/
202 | RST_SYNC U0_RST_SYNC (
203 | .CLK ( i_ref_clk ) ,
204 | .RST ( i_rst_n ) ,
205 | .SYNC_RST ( x_RST_SYNC1 ) );
206 |
207 | RST_SYNC U1_RST_SYNC (
208 | .CLK ( i_uart_clk ) ,
209 | .RST ( i_rst_n ) ,
210 | .SYNC_RST ( x_RST_SYNC2 ) );
211 |
212 | /********** CLK DIV instantiation **********/
213 | ClkDiv #(.RATIO_WIDTH ( BUS_WIDTH-2 )) U0_ClkDiv (
214 | .i_ref_clk ( i_uart_clk ) ,
215 | .i_rst_n ( x_RST_SYNC2 ) ,
216 | .i_clk_en ( x_CD_en ) ,
217 | .i_div_ratio ( x_CD_RX ) ,
218 | .o_div_clk ( x_URX_CLK ) );
219 |
220 | ClkDiv U1_ClkDiv (
221 | .i_ref_clk ( i_uart_clk ) ,
222 | .i_rst_n ( x_RST_SYNC2 ) ,
223 | .i_clk_en ( x_CD_en ) ,
224 | .i_div_ratio ( x_Reg_REG3 ) ,
225 | .o_div_clk ( x_UTX_CLK ) );
226 |
227 | /********* Pulse Gen instantiation *********/
228 | PULSE_GEN U0_PULSE_GEN (
229 | .CLK ( x_UTX_CLK ) ,
230 | .RST ( x_RST_SYNC2 ) ,
231 | .LVL_SIG ( x_UTX_busy ) ,
232 | .PULSE_SIG ( x_PG_pulse ) ;
233 |
234 | /********* UART TX instantiation *********/
235 | UART_TX U0_UART_TX (
236 | .CLK ( x_UTX_CLK ) ,
237 | .RST ( x_RST_SYNC2 ) ,
238 | .P_DATA ( x_FIFO_RData ) ,
239 | .DATA_VALID ( !x_FIFO_EMPTY ) ,
240 | .PAR_EN ( x_Reg_REG2[0] ) ,
241 | .PAR_TYP ( x_Reg_REG2[1] ) ,
242 | .TX_OUT ( o_tx_out ) ,
243 | .Busy ( x_UTX_busy ) );
244 |
245 | /********* Clk Gate instantiation ********/
246 | ClkGate U0_ClkGate (
247 | .CLK ( i_ref_clk ) ,
248 | .CLK_EN ( x_CG_en ) ,
249 | .GATED_CLK ( x_CG_ALUclk ) );
250 |
251 | endmodule
252 |
253 |
--------------------------------------------------------------------------------
/System Controller/SYS_CTRL.v:
--------------------------------------------------------------------------------
1 | module SYS_CTRL #( parameter ALU_WIDTH = 16, ADDR_WIDTH = 4, DATA_BUS_WIDTH = 8, ALUFN_WIDTH = 4, NO_STATES = 12, STATE_WIDTH = $clog2(NO_STATES))
2 |
3 | ( input wire CLK , // Clock Signal
4 | input wire RST , // Active Low Reset
5 | input wire [ALU_WIDTH-1:0] ALU_OUT , // ALU Result
6 | input wire OUT_Valid , // ALU Result Valid
7 | input wire [DATA_BUS_WIDTH-1:0] RX_P_Data , // UART_RX Data
8 | input wire RX_D_VLD , // RX Data Valid
9 | input wire [DATA_BUS_WIDTH-1:0] RdData , // Read Data Bus
10 | input wire RdData_Valid , // Read Data Valid
11 | input wire [DATA_BUS_WIDTH-3:0] Prescale_RX , // config prescale values
12 | input wire FIFO_FULL , // FIFO full flag
13 | output reg [DATA_BUS_WIDTH-3:0] ClkDiv_RX , // Clock Divider Ratio for RX
14 | output reg ALU_EN , // ALU Enable signal
15 | output reg [ALUFN_WIDTH-1:0] ALU_FUN , // ALU Function signal
16 | output reg CLK_EN , // Clock gate enable
17 | output reg [ADDR_WIDTH-1:0] Address , // Address bus
18 | output reg WrEn , // Write Enable
19 | output reg RdEn , // Read Enable
20 | output reg [DATA_BUS_WIDTH-1:0] WrData , // Write Data Bus
21 | output reg [DATA_BUS_WIDTH-1:0] TX_P_Data , // UART _TX Data
22 | output reg TX_D_VLD , // TX Data Valid
23 | output wire clk_div_en ); // Clock divider enable
24 |
25 | // states register declaration
26 | reg [STATE_WIDTH-1:0] current_state, next_state;
27 |
28 | // state encoding
29 | localparam S_IDLE = 'b0000; // Idle state
30 | localparam S_REG_WRT_ADRS = 'b0001; // Register File Write command: Frame 1 [Address]
31 | localparam S_REG_WRT_DATA = 'b0011; // Register File Write command: Frame 2 [Data]
32 | localparam S_REG_RD_ADRS = 'b0010; // Register File Read command: [Address]
33 | localparam S_REG_RD_OUT = 'b0110; // Register File Passing Data to output
34 | localparam S_ALU_IN_A = 'b0111; // ALU Operation with OPERAND command: Frame 1 [Operand A]
35 | localparam S_ALU_IN_B = 'b0101; // ALU Operation with OPERAND command: Frame 2 [Operand B]
36 | localparam S_ALU_FUN = 'b0100; // ALU Operation with OPERAND command: Frame 3 [ALU Func]
37 | localparam S_ALU_OUT_LSB = 'b1100; // ALU Operation with OPERAND command: Pass the output outside LSB
38 | localparam S_ALU_OUT_MSB = 'b1101; // ALU Operation with OPERAND command: Pass the output outside MSB
39 |
40 | // commands encoding
41 | localparam REG_WR_CMD = 'hAA;
42 | localparam REG_RD_CMD = 'hBB;
43 | localparam ALU_OP_CMD = 'hCC;
44 | localparam ALU_NOP_CMD = 'hDD;
45 |
46 | // registers
47 | reg [ADDR_WIDTH-1:0] addr_reg;
48 | reg [ALUFN_WIDTH-1:0] ALUFN_reg;
49 |
50 | // conditions
51 | wire CHANGE_ADDR,CHANGE_FUNC;
52 |
53 |
54 | /****************************************** *******************************************/
55 | // current state sequential always
56 | always @(posedge CLK or negedge RST)
57 | begin
58 | if(!RST)
59 | current_state <= S_IDLE;
60 | else
61 | current_state <= next_state;
62 | end
63 |
64 | // next state & output logic
65 | always @(*)
66 | begin
67 | case(current_state)
68 | // idle state
69 | S_IDLE: begin
70 | ALU_EN = 1'b0;
71 | ALU_FUN = 'b1000;
72 | CLK_EN = 1'b0;
73 | Address = addr_reg;
74 | WrEn = 1'b0;
75 | RdEn = 1'b0;
76 | WrData = 'b0;
77 | TX_P_Data = 'hFF;
78 | TX_D_VLD = 1'b0;
79 |
80 | if(RX_D_VLD)
81 | case(RX_P_Data)
82 | REG_WR_CMD: begin
83 | ALU_EN = 1'b0;
84 | CLK_EN = 1'b0;
85 | next_state = S_REG_WRT_ADRS;
86 | end
87 |
88 | REG_RD_CMD: begin
89 | ALU_EN = 1'b0;
90 | CLK_EN = 1'b0;
91 | next_state = S_REG_RD_ADRS;
92 | end
93 | ALU_OP_CMD: begin
94 | ALU_EN = 1'b1;
95 | CLK_EN = 1'b1;
96 | next_state = S_ALU_IN_A;
97 | end
98 | ALU_NOP_CMD: begin
99 | ALU_EN = 1'b1;
100 | CLK_EN = 1'b1;
101 | next_state = S_ALU_FUN;
102 | end
103 | default: next_state = S_IDLE;
104 | endcase
105 | else
106 | next_state = S_IDLE;
107 | end
108 |
109 |
110 | // Reg Write frame 1: Address Frame
111 | S_REG_WRT_ADRS: begin
112 | ALU_EN = 1'b0;
113 | ALU_FUN = 'b1000;
114 | CLK_EN = 1'b0;
115 | WrEn = 1'b0;
116 | RdEn = 1'b0;
117 | WrData = 'b0;
118 | TX_P_Data = 'b0;
119 | TX_D_VLD = 1'b0;
120 | if(RX_D_VLD)
121 | begin
122 | Address = addr_reg;
123 | next_state = S_REG_WRT_DATA;
124 | end
125 | else
126 | begin
127 | Address = addr_reg;
128 | next_state = S_REG_WRT_ADRS;
129 | end
130 | end
131 |
132 | // Reg Write frame 2: Data Frame
133 | S_REG_WRT_DATA: begin
134 | ALU_EN = 1'b0;
135 | ALU_FUN = 'b1000;
136 | CLK_EN = 1'b0;
137 | Address = addr_reg;
138 | WrData = 'b0;
139 | TX_P_Data = 'b0;
140 | TX_D_VLD = 1'b0;
141 |
142 | if(RX_D_VLD)
143 | begin
144 | WrEn = 1'b1;
145 | RdEn = 1'b0;
146 | WrData = RX_P_Data;
147 | next_state = S_IDLE;
148 | end
149 | else
150 | begin
151 | WrEn = 1'b0;
152 | RdEn = 1'b0;
153 | WrData = 'b0;
154 | next_state = S_REG_WRT_DATA;
155 | end
156 | end
157 |
158 | // Reg Read address
159 | S_REG_RD_ADRS: begin
160 | ALU_EN = 1'b0;
161 | ALU_FUN = 'b1000;
162 | CLK_EN = 1'b0;
163 | WrEn = 1'b0;
164 | RdEn = 1'b0;
165 | WrData = 'b0;
166 | TX_P_Data = 'b0;
167 | TX_D_VLD = 1'b0;
168 |
169 | if(RX_D_VLD)
170 | begin
171 | Address = addr_reg;
172 | next_state = S_REG_RD_OUT;
173 | end
174 | else
175 | begin
176 | Address = addr_reg;
177 | next_state = S_REG_RD_ADRS;
178 | end
179 | end
180 |
181 | // Passing read data
182 | S_REG_RD_OUT: begin
183 | ALU_EN = 1'b0;
184 | ALU_FUN = 'b1000;
185 | CLK_EN = 1'b0;
186 | Address = addr_reg;
187 | WrData = 'b0;
188 | WrEn = 1'b0;
189 | RdEn = 1'b1;
190 |
191 | if(RdData_Valid && !FIFO_FULL)
192 | begin
193 | TX_P_Data = RdData;
194 | TX_D_VLD = 1'b1;
195 | next_state = S_IDLE;
196 | end
197 | else
198 | begin
199 | TX_P_Data = 'b0;
200 | TX_D_VLD = 1'b0;
201 | next_state = S_REG_RD_OUT;
202 | end
203 | end
204 |
205 | // ALU Operantion with Operand command: Operand A
206 | S_ALU_IN_A: begin
207 | Address = 'h0;
208 | ALU_EN = 1'b0;
209 | ALU_FUN = 'b1000;
210 | CLK_EN = 1'b0;
211 | TX_P_Data = 'b0;
212 | TX_D_VLD = 1'b0;
213 |
214 | if(RX_D_VLD)
215 | begin
216 | WrEn = 1'b1;
217 | RdEn = 1'b0;
218 | WrData = RX_P_Data;
219 | next_state = S_ALU_IN_B;
220 | end
221 | else
222 | begin
223 | WrEn = 1'b0;
224 | RdEn = 1'b0;
225 | WrData = 'b0;
226 | next_state = S_ALU_IN_A;
227 | end
228 | end
229 |
230 | // ALU Operantion with Operand command: Operand B
231 | S_ALU_IN_B: begin
232 | Address = 'h1;
233 | ALU_EN = 1'b0;
234 | ALU_FUN = 'b1000;
235 | CLK_EN = 1'b0;
236 | TX_P_Data = 'b0;
237 | TX_D_VLD = 1'b0;
238 |
239 | if(RX_D_VLD)
240 | begin
241 | WrEn = 1'b1;
242 | RdEn = 1'b0;
243 | WrData = RX_P_Data;
244 | next_state = S_ALU_FUN;
245 | end
246 | else
247 | begin
248 | WrEn = 1'b0;
249 | RdEn = 1'b0;
250 | WrData = 'b0;
251 | next_state = S_ALU_IN_B;
252 | end
253 | end
254 |
255 | // ALU Operantion with Operand command: ALU FUNC
256 | S_ALU_FUN: begin
257 | ALU_EN = 1'b1;
258 | CLK_EN = 1'b1;
259 | Address = addr_reg;
260 | WrEn = 1'b0;
261 | RdEn = 1'b0;
262 | WrData = 'b0;
263 | TX_P_Data = 'b0;
264 | TX_D_VLD = 1'b0;
265 | WrEn = 1'b0;
266 | RdEn = 1'b0;
267 |
268 | if(RX_D_VLD)
269 | begin
270 | ALU_FUN = RX_P_Data;
271 | next_state = S_ALU_OUT_LSB;
272 | end
273 | else
274 | begin
275 | ALU_FUN = 'b1000;
276 | next_state = S_ALU_FUN;
277 | end
278 | end
279 |
280 | // Passing the ALU result
281 | S_ALU_OUT_LSB: begin
282 | ALU_EN = 1'b1;
283 | CLK_EN = 1'b1;
284 | ALU_FUN = ALUFN_reg;
285 | Address = addr_reg;
286 | WrEn = 1'b0;
287 | RdEn = 1'b0;
288 | WrData = 'b0;
289 | WrEn = 1'b0;
290 | RdEn = 1'b0;
291 |
292 | if(OUT_Valid && !FIFO_FULL)
293 | begin
294 |
295 | TX_P_Data = ALU_OUT[DATA_BUS_WIDTH-1:0];
296 | TX_D_VLD = 1'b1;
297 | next_state = S_ALU_OUT_MSB;
298 | end
299 | else
300 | begin
301 | TX_P_Data = 'b0;
302 | TX_D_VLD = 1'b0;
303 | next_state = S_ALU_OUT_LSB;
304 | end
305 | end
306 |
307 | // Passing the ALU result
308 | S_ALU_OUT_MSB: begin
309 | ALU_EN = 1'b1;
310 | CLK_EN = 1'b1;
311 | Address = addr_reg;
312 | WrEn = 1'b0;
313 | RdEn = 1'b0;
314 | WrData = 'b0;
315 | WrEn = 1'b0;
316 | RdEn = 1'b0;
317 |
318 | if(OUT_Valid && !FIFO_FULL)
319 | begin
320 | TX_P_Data = ALU_OUT[2*DATA_BUS_WIDTH-1:DATA_BUS_WIDTH];
321 | TX_D_VLD = 1'b1;
322 | ALU_FUN = 'b1000;
323 | next_state = S_IDLE;
324 | end
325 | else
326 | begin
327 | TX_P_Data = 'b0;
328 | TX_D_VLD = 1'b0;
329 | ALU_FUN = ALUFN_reg;
330 | next_state = S_ALU_OUT_MSB;
331 | end
332 | end
333 |
334 | default: begin
335 | ALU_EN = 1'b0;
336 | ALU_FUN = 'b1000;
337 | CLK_EN = 1'b0;
338 | Address = addr_reg;
339 | WrEn = 1'b0;
340 | RdEn = 1'b0;
341 | WrData = 'b0;
342 | TX_P_Data = 'b0;
343 | TX_D_VLD = 1'b0;
344 | next_state = S_IDLE;
345 | end
346 | endcase
347 | end
348 |
349 |
350 |
351 | // registering the addr_reg
352 | always @(posedge CLK or negedge RST)
353 | begin
354 | if(!RST)
355 | addr_reg <= 'b0;
356 | else if(CHANGE_ADDR)
357 | addr_reg <= RX_P_Data;
358 | end
359 |
360 | // registering the ALU func
361 | always @(posedge CLK or negedge RST)
362 | begin
363 | if(!RST)
364 | ALUFN_reg <= 'b1000;
365 | else if(CHANGE_FUNC)
366 | ALUFN_reg <= RX_P_Data;
367 | end
368 |
369 | // Configuring ClkDiv RX Ratio
370 | always @(*)
371 | begin
372 | case(Prescale_RX)
373 | 'd8: ClkDiv_RX = 'd4;
374 | 'd16: ClkDiv_RX = 'd2;
375 | 'd32: ClkDiv_RX = 'd1;
376 | default: ClkDiv_RX = 'd1;
377 | endcase
378 | end
379 |
380 | // change address conditions
381 | assign CHANGE_ADDR = ( (current_state == S_REG_WRT_ADRS) ||
382 | (current_state == S_REG_RD_ADRS) );
383 |
384 | // change address conditions
385 | assign CHANGE_FUNC = ( (current_state == S_ALU_FUN) );
386 |
387 | // clock divider is always active
388 | assign clk_div_en = 1'b1;
389 | endmodule
--------------------------------------------------------------------------------