Monday, August 2, 2021

AMBA Bus Architecture & Protocol Understanding - Part#3



There are 2 basic reasons why AXI may be faster:

1) Simplex Vs Duplex Transfers
AXI has completely independent channels for read/write, which enables full duplex mode of data transportation. That is to say read and writes can take place simultaneously, giving 2x boost over AHB in any circumstances. However, this will ONLY be possible when the slave is able to process 1 read and 1 write operation simultaneously in 1 clock cycle. Which in many cases will be possible, e.g. if the slave is a dual port SRAM which can process 1 read and 1 write transaction simultaneously. Also in this example, we are considering 1 Master and 1 Slave. But in case of multiple slaves, the master can send read transaction to 1 slave and write to other slave, even if the slave(s) cannot handle more than 1 transactions in single clock cycle.

To make more clarity, in a system where there is only 1 master and only 1 slave, the slave is unable to process read and write in 1 single clock cycle simultaneously and both master and slave are in single synchronous clock domain with no clock delay between the master and the slave there won’t be any difference in performance between AXI and AHB. The AXI will only consume more power and area.

2) When there are clock cycle delays between a Master and a responding slave.
This is usually when the Master clock and slave clock is Async, and a there is a clock domain crossing bridge.
It can be observed in the diagram shown below, that that as the number of OTs (outstanding transaction) increase in AXI, the efficiency increases. It can also be observed that with 1 OT, again, the performance will be comparable, if we are doing only reads or only writes.
In AXI case, since the system is able to issue outstanding transactions (OT), i.e. able to issue addresses without waiting for data to return, there is only a initial delay, and then the continuous flow of data follows.
In AHB this is not possible. The AHB cannot issue another transaction, without first receiving the response to its only transaction, which it can issue at a time.

It is to be noted again, that if there are no clock delays between a master and a slave, and if we assume only 1 master and 1 slave in the system, then again the AXI performance will be equal to AHB performance, if we are doing only reads or only writes.









AHB Lite Vs AHB:
AHB Lite is a reduced version of AHB protocol. AHB Lite essentially means that there is only 1 master.
This in turn means
1. No Arbitration

2. No HBUSREQ signal, no HGRANT signal

3. No HSEL Signal

4. No Split or Retry response type -> HRESP can only be 1 bit

5. No Early Bus Termination.

How to connect a full AHB Master to AHB Lite Slave
1. Leave the HBUSREQ open

2. Tie the HGRANT to '1'

How to connect a AHBLite Master to full AHB Slave
1. Feedback the HREADY_out from the Slave back into the HREADY_In at slave (A slave will have hready as input and as output) but also connect the HREADY_out from Slave to the Master.

2. Tie the HSEL '1' at the Slave.

AHB Split Transfer-

In a AHB based Interconnect system, where the interconnect is essentially an AHB Bus, the bus is ownedby 1 master at a time, and it is held by the master at least till it completes the ongoing transfer. Now what if a slave is presented by a read command, and the slave is incredibly slow. Say it takesmultiple clock cycles to produce the data it is requested to provide. Now starting from the point of time read transaction is presented to slave, till it ready to produce response, the slave will pull hready low, and will keep the bus engaged. Now the whole system is stalled, and no other master is able to do any operation.

The SPLIT response now comes into picture, and is able to change this scenario.
The AHB protocol allows the slave to issue a SPLIT response to a transaction, thereby relinquishing the bus for the other masters in the system to be able to use the bus. As the slave issues a SPLIT response, it records the master ID (HMASTER) of the transaction and memorizes it.
When this slave is ready to respond to the SPLITted transaction, it informs the arbiter using HSPLIT signal.
HSPLIT has 1 bit for every master, and a '1' in a bit specifies which master this Slave is talking about.
The arbiter would then grant the bus to the SPLITted master on the earliest opportunity, and let it complete the transaction. This improves the overall system performance.







  - Improved bus utilization

  - May cause deadlocks if not carefully implemented

------------------------------------Happy Learning--------------------------------------

AMBA Bus Architecture & Protocol Understanding - Part#1



Following diagram illustrates AMBA evolution of protocols along with the SOC design trends in industry.





AMBA 1 specification (First version) defines two buses/interfaces-

1) Advanced System Bus (ASB)

2) Advanced Peripheral Bus (APB)



AMBA 2 specification defines three buses/interfaces:

1) Advanced High-performance Bus (AHB) - widely used on ARM7, ARM9 and ARM Cortex-M based designs

2) Advanced System Bus (ASB)

3) Advanced Peripheral Bus (APB2 or APB)




AMBA 3 specification defines four buses/interfaces:

1) Advanced eXtensible Interface (AXI3 or AXI v1.0) - widely used on ARM Cortex-A processors including Cortex-A9

2) AHB-Lite v1.0

3) APB3 v1.0

4) Advanced Trace Bus (ATB v1.0)

AMBA 4 specification defines following buses/interfaces:

1) AXI Coherency Extensions (ACE) - widely used on the latest ARM Cortex-A processors including Cortex-A7 and Cortex-A15

2) ACE-Lite

3) AXI4

4) AXI4-Lite

5) AXI4-Stream v1.0

6) ATB v1.1

7) APB4 v2.0

AMBA 5 specification defines the following buses/interfaces:

1) AXI5, AXI5-Lite and ACE5

2) AHB5, AHB-Lite

3) CHI Coherent Hub Interface (CHI)

4) Distributed Translation Interface (DTI)

5) Generic Flash Bus (GFB)

APB: Used for connecting low bandwidth peripherals, Non-pipelined, No burst data transfer

AHB: Used for connecting higher bandwidth peripherals, Burst data transfer

AHB Lite: Single master support, no arbitration, retry, split transactions etc.

AXI: The Advanced Extensible interface (AXI) is useful for high bandwidth and low latency interconnects. This is a point to point interconnect and overcomes the limitations of a shared bus protocol in terms of number of agents that can be connected. The protocol also was an enhancement from AHB in terms of supporting multiple outstanding data transfers (pipe-lined), burst data transfers, separate read and write paths and supporting different bus widths.

AXI Lite: No burst data transfer

AXI-stream: Only streaming of data from master to slave

ACE — AXI Coherence extension protocol is an extension to AXI 4 protocol and evolved in the era of multiple CPU cores with coherent caches getting integrated on a single chip.

CHI (Coherent Hub Interface) — The ACE protocol was developed as an extension to AXI to support coherent interconnects. The ACE protocol used a signal level communication between master/slave and hence the interconnects needed large number of wires with added channels for snoops and responses. The CHI protocol uses a layered packet based communication protocol with protocol, link layer and physical layer implementation and also supports QoS based flow control and retry mechanisms.

AHB Architecture :



AHB Arbitration:



A single master system only requires the use of a Decoder and Multiplexor. A multi-master system requires the use of an interconnect that provides arbitration and the routing of signals from different masters to the appropriate slaves. This routing is required for address, control, and write data signaling. Different approaches used for multi-master systems, such as single layer or multi-layer interconnects.

The address phase of any transfer occurs during the data phase of the previous transfer. This overlapping of address and data is fundamental to the pipelined nature of the bus and enables high performance operation while still providing adequate time for a slave to provide the response to a transfer.

Buffer-able, it specifies that the final destination of the current transfer can be delayed (for example if final destination is to some USB or Network from the processor it can be delayed performing appropriate transfers.
Bufferable Transaction can be buffered. For example, if a master issues a write transaction to a Slave via a bus or a fabric, the bus/fabric may buffer the transaction and respond OK immediately. This means that the OK response does not come from the final destination. The bus/fabric will in turn will transfer the write command to the final destination. Bufferable Writes can also be called posted writes. 'Posted' Writes are the ones for which the issuer gets
no response. Though in bufferable writes the Master do get a response, but it’s not from the final destination Posted/non-posted are terms from the PCIe World. A bufferable transaction is indicated by HPROT[2], when it is '1', the transaction is bufferable.

Cacheable, it specifies that the transaction when it has reached to the final destination need not match with the initial transfer started by the Processor/Master. The data can also be mixed with from different transactions to form a packet (this mix may be used to form a packet/frame) accordingly. Not all master (AHB) will support this kind of transfers, here slave can use the transfers accordingly.

AMBA AHB implements the features required for high-performance, high clock frequency systems including:

· Burst transfers.

· Single clock-edge operation.

· Non-tristate implementation.



· Wide data bus configurations, 64, 128, 256, 512, and 1024 bits.



Locked transfers, if the master requires locked accesses then it must also assert the HMASTLOCK signal. This signal indicates to any slave that the current transfer sequence is indivisible and must therefore be processed before any other transfers are processed. Typically, the locked transfer is used to maintain the integrity of a semaphore, by ensuring that the slave does not perform other operations between the read and write phases of a microprocessor SWP instruction.

Note: Many masters are not capable of generating accurate protection information. If a master is not capable of generating accurate protection information, AHB5 specification recommends that:


The master sets HPROT to 0b0011 to correspond to a Non-cacheable, Non-bufferable, privileged, data access.
Slaves do not use HPROT unless absolutely necessary


Secure transfers - AHB5 defines the Secure_Transfers property. This property defines whether an interface supports the concept of Secure and Non-secure transfers. If this property is not defined then the interface does not support Secure transfers. An interface that supports Secure transfers has an additional signal, HNONSEC. This signal is asserted for a Non-secure transfer and deasserted for a Secure transfer. HNONSEC is an address phase signal and has the same validity constraints as HADDR.

Stable_Between_Clock- AHB5 defines the Stable_Between_Clock property. This property is defined to determine if an interface guarantees that signals that are required to be stable remain stable between rising clock edges. If this property is True, it is guaranteed that signals that are required to be stable remain stable and glitch free between rising clock edges.

Exclusive_Transfer_property -AHB5 defines the Exclusive_Transfers property. This property defines whether an interface supports the concept of Exclusive Transfers. If this property is not defined then the interface does not support Exclusive Transfers. Exclusive Transfers provide a mechanism to support semaphore-type operations. An Exclusive access sequence is a sequence of Exclusive Transfers from a single master that operate using the following steps:

1. Perform an Exclusive Read transfer from an address.

2. Calculate a new data value to store to that address that is based on the data value obtained from the Exclusive Read.

3. Between the Exclusive Read and the Exclusive Write there can be other Non-exclusive transfers.

4. Perform an Exclusive Write transfer to the same address, with the new data value:

• If no other master has written to that location since the Exclusive Read transfer, the Exclusive Write transfer is successful and updates memory.

• If another master has written to that location since the Exclusive Read transfer, the Exclusive Write transfer is failed and the memory location is not updated.

5. The response to the Exclusive Write transfer indicates if the transfer was successful or if it failed. This sequence ensures that the memory location is only updated if, at the point of the store to memory, the location still holds the same value that was used to calculate the new value to be written to the location.

If the Exclusive Write transfer fails, it is expected that the master will repeat the entire Exclusive access sequence.

It is IMPLEMENTATION DEFINED whether an update of the same, or overlapping, location by the same master after an Exclusive Read transfer will cause the associated Exclusive Write transfer to succeed or fail.

Note: An Exclusive Access Monitor is required to support an Exclusive access sequence and this monitor must determine if an Exclusive Write transfer succeeds or fails

Atomicity:

Single-copy atomicity size: The single-copy atomicity size defines the number of data bytes that a transfer is guaranteed to update atomically.

Multi-copy atomicity: A system is defined as being multi-copy atomic if:

· Writes to the same location are observed in the same order by all agents.

· A write to a location that is observable by an agent, other than the issuer, is observable by all agents.

Multi-copy atomicity can be ensured by avoiding the use of forwarding buffers, which can make a transfer visible to some agents in a system, but not visible to all.

Note Additional requirements exist to ensure multi-copy atomicity in systems that include some form of hardware cache coherency.



AHB Multi Layered Bus:
A normal AHB bus has a significant disadvantage, that only 1 Master/Slave pair can be active at a given
time. If any master/slave pair is engaged in a transfer, all the other Master/Slaves has no choice but to wait. This situation is addressed by a AHB Multilayered bus, where the arbitration takes place inside the Slave. Now if say Master M1 is interacting with Slave S3, the other master say M2 can interact in parallel with other slave say S5. And in theory, all masters can now can operate in parallel, as long as they are interacting with unique different respective Slaves.

HREADY an o/p from slave-

Ø HREADY is an o/p from slave so that it can extend the data phases if it needs more time.

HREADY is an input to slave-









Ø The Arbiter Grants a Master the bus on the Last clock cycle of the data phase of the previous Master, because the arbiter keeps track of the number of transfers and it knows the burst size and all characteristics.
Say an INCR4 burst is currently ongoing by Master1 to Slave2. The data phase will be 4 clock cycles, if the HREADY from Slave2 is always high.
The Dataphase will however be 5 clock cycles if say for example the Slave2 extends the DP3 into two clock cycles say DP3_0 and DP3_1, HREADY being '0' in DP3_0.
In absence of HREADY being an input to slave, another slave in the system say Slave3, will
see its HSEL go '1' in DP3_0, and it will start responding in DP3_1, which will result in data corruption. But Since HREADY is also availsble to this Slave3, it will come to konw that even when it has its HSEL go to '1'
The recommended default value of HREADY is '1'.

When would a master sample 'hready' -

Ø Since 'hready' is only related to data phase, the Master would sample 'hready' at the N+1th edge, where N is the clock edge, at which it issued the data.
When a master is granted the bus and is performing a fixed length burst it is not necessary to continue to request the bus in order to complete the burst. The arbiter observes the progress of the burst and uses the HBURST[2:0] signals to determine how many transfers are required by the master. For undefined length bursts the master should continue to assert the request until it has started the last transfer. The arbiter cannot predict when to change the arbitration at the end of an undefined length burst.

Ø An AHB Slave should not pull 'HREADY' low, if it has 'HTRANS' = NSEQ, i.e HTRANS = 2. This will be protocol violation. By spec, "The address cannot be extended, therefore all slaves must sample the address during this time" However, an 'Address Phase' could be extended as a side effect, if it coincides with Data Phase of previous transaction. HREADY indicates a transfer complete, it may then follow that a Slave may never pull down its HREADY to low, while its HTRANS is 0. Because this will mean that Slave is trying to extend a NOP?

Ø Though the AHB spec itself puts no restriction on a combinatorial path from issuing Master back to Issuing Master, but it should be avoided.

Ø A Slave should not pull 'hready' low during address phase, if this address phase is not overlapping with any pre-existing data phase. And if there is an overlap, then technically its the data phase which is being extended, with the address phase extended as a 'side effect'. Usually when all masters in a system are IDLE, then any slave if pulls its hready to 'low' then this won’t have any effect on any of the system masters. If the slave does so, it will be ignored. In fact, if this happens, and there is an arbiter between master and slave, then this low hready won’t be passed to any master either.



AHB Multilayer-
Consider an AHB arbiter, which connects M masters and S slaves. This arbiter or AHB Bus arbitrates between M masters and grants the bus to one of them, say Master 2 or M2 Now M2 is interacting with some slave say S3.
While M2 is interacting with S3, all other masters in the system cannot do anything will M2 is busy. Here we lose the opportunity, as while M2 is interacting with S3, there is no reason why say M4 cannot interact with S1 simultaneously. But with a single layered bus, this is not possible. A Multilayered bus or arbiter enables just that,
so that any master can interact with any slave as long as the master/slave pair is unique.
For example while M2 is interacting with S3, M4 can interact with S2, M1 can interact with S1 simultaneously.
How is this possible?
This is possible when the arbitration takes place at the slave port. Each Slave will have say M interfaces, So, that M masters can connect to it. There is now a path to each master in the system to each slave, so that simultaneous accesses can take place if the Master/Salve pair is unique.

This multi-layer system will be essentially AHB-Lite. No Bus Requests, no Bus Grants, as conceptually there are multiple parallel buses, actually there are as many buses in the system
as there are number of slaves.




References : AHB5, AHB-Lite , AXI Specification



----------------------------------------------------Happy Learning--------------------------------------









Power Aware Clock Domain Crossing



Chief Aspects of Power Management :

· Power Shut-off

· Isolation

· Retention

· Corruption

· Multiple Voltages

· Level shifters

Note: Leakage Power Reduction is Key in Low-Power Design

Power Network Instrumentation -

· Presence of power network may impact CDC

· Power domains may be functionally verified with simulation

· Synchronous clocks are affected by DVFS (Dynamic Voltage and Frequency Scaling)

Power Cells may/may not present in RTL (RTL instantiated V/S UPF inserted) -

· Retention Cells

· Isolation Cells

· Level Shifters

Power Aware CDC Analysis-

· Identify Power Aware CDC paths

· Detect Power Aware CDC scenarios

Ø Isolation enable violation

Ø Combinational logic violation

Ø Retention cell save/restore violation

· Detect Voltage Domain Crossing schemes

Ø Identify all VDC paths

Ø Check for VDC synchronizations & violations

Below are the various examples where Power Aware Design can have multiple Clock Domain Crossing issues reported. Lets have a look at some of such cases -

Example (1) - PA affecting CDC correctness (RTL Paths) :




RTL Paths after DFP(Design-for-Power) Insertion-





· Insertion of isolation cell logic may add new CDC paths

· Implement power control logic

Ø UPF specifies power domain crossings and isolation-enable signals

Example (2) - Isolation Enable Missing Synchronizer :





· Blocks B1&B2 are in clock c1

· Iso_en comes from block B3 in clock domain c2

· New violation for the new CDC path B3->B2

Isolation Enable Missing Synchronizer Fix-




· Solution: Synchronize iso_en from domain c2 to domain c1 before use

Example (3) - Isolation Causes Combo-logic Violation :


· Synchronized CDC path B1->B2 (clock c1 to c2)

· Isolation cell adds combinational path before synchronizer

Example (4) - Retention Cell Causes Missing Synchronizer :






· Retention cell adds paths to save and restore pins

· New CDC violation B1=>B2

Dynamic Frequency and Voltage Scaling(DVFS) :

Frequency and Voltage interdependence

· Max operating frequency dependent on voltage

· Reducing frequency allows voltage & power reduction

"Small voltage reductions = large power savings"

· Power consumption proportional to supply voltage (P α V2 *)



Example (5) - Voltage Domain Crossing :

· Voltage domains create asynchronous clock groups

· Identify crossings between synchronous paths on different voltage domains


· Identify CDC paths that start or end on DVFS voltage domains

· New CDC violation B1=>B2


------------------------------------------Happy Learning----------------------------------------

Design a Circuit for Retention SR Flip-Flop/Latch



SR Retention Flip-Flop/Latch :

- Lets have a look at a normal SR Flip Flop and Latch as below -


Figure#1 : SR Flip-Flop




Figure#2 : SR Latch




- If these Flip-Flops/Latches needs to be retained during the power shut-down, these Flip-Flops/Latches circuits needs to be modified such that when the power restores, these Flip-Flops/Latches gets initialized to the previous value ( Value before power shut-down)

- Lets see the modified circuit diagrams of these cells which acts like a retention Flip-Flop/Latch




Figure#3 : Retention Flip-Flop

Figure#4 : Retention Latch





- As shown in figure#3 & #4, when the power is about to shut down , the 'Save' signal is asserted and the Flip-Flop/Latch output gets captured in the D-Latch (Which is powered and has the active power supply)

- Once the power is up, 'Restore' signal is asserted and the Flip-Flop/Latches gets initialized with the stored value in D-Latch




Hope, this article is helpful in understanding the basic concepts of Retention Flip-Flop/Latches and how they behave during power shut-down and power up.




------------------------------------------------------Happy Learning-------------------------------------

Saturday, July 31, 2021

Unified Power Format (UPF) Design - key Points



1) Do we need any isolation strategy between ON - to - OFF (Standby) Block ?

- Generally the isolation is required between OFF - to ON Block but in some cases it is recommended to use isolation between ON - to -OFF domain as well.

- Normally the isolation strategy between OFF - to - ON is called as Parking

- This kind of strategy is required for some special kind of signals which have multiple loads in the OFF (Standby) domain, for example - RESET/CLK

- This is to insure that the RESET/CLK do not toggle when the domain is in OFF state

- This prevents switching of many sequential elements in the OFF domain and hence helps in reducing the power consumption

2) What is the basic Low Power Sequence followed in modern VLSI Design ?

Below is the basic sequence of Low Power Entry/Exit

- Save the retention register outputs

- Assert the isolation control signals ( Enable the isolation)

- Enable Clock Gating

- Apply the Power Gating /Shutdown the Power for Specific Blocks of Interest)

- Wait for the specific time/event (example - interrupt)to exit the Low Power State

- Remove the Power Gating/Switch ON the Power Domain

- Restore the retention register values

- Un-Gate the Clock

- Release isolation signals

3) What are the benefits of having ELS (Enable Level Shifter) Cells , if we have both Isolation and Level Shifter standalone cells ?

- They are combinedly designed in such a way that they consume less area (Area Efficient Design)

Fundamentals of LINT



Lint :

- A Static analysis of code (e.g HDL) based on a series of rules and guidelines that reflect good coding practices, common errors that tend to lead to buggy code or problems

- Lint tools are used to check potential mismatches between simulation and synthesis in VLSI Design

- Lint incorporates syntactical compliance checks against various coding best practice standards such as STARC

- Lint can catch bugs without requiring specific test vectors and hence reduces the number of simulation cycles needed to achieve coverage of a logic block

- Industry standard Famous LINT Tools : Synopsys SpyGlass, LEDA

Typical LINT Targets :

- Unintentional Latches (Latch inference)

- Unused Declarations

- Un-Synthesizable Constructs

- Missing Parameters in Hierarchical Modules

- Race Conditions

- Multiple Driver issue

- Undriven Signals

- Incorrect uses of Blocking and Non-Blocking Assignments

- Formation of Combinational Loops

- Case Statement Style issue

- Set and Reset Conflicts

- Out-of-Bound Indexing






----------------------------------------------Happy Learning--------------------------------------------

Fundamentals of Isolation Cells in Low Power VLSI Design



In Multi Voltage VLSI Design, isolation cells play an important role in the modern VLSI world.


Requirement : Lets have a look at the below diagram -



- Lets assume VDDA voltage domain is always ON and VDDB voltage domain can go ON or OFF based on the certain design requirements ( To minimize the power consumption of the whole design)

- When VDDB domain is OFF , the outputs of all the gates of this domain are at unpredictable state.

- Since , some of the gates of VDDB domain might be driving some logic in VDDA domain (Which is always ON) but since VDDB domain signals are at unknown state (X) and they might corrupt the logic in VDDA domain and eventually the VDDA domain functionality gets corrupted

- To avoid such scenario , we need to isolate the signals going from VDDB(OFF) to VDDA(ON) domain by the use of nothing but called as isolation cells

- By using isolation cells we will clamp the respective logic to a proper value (0 or 1 or Latch )


Isolation cells :

- These are simple logic gates which is used to pull-up (logic '1'), pull-down (logic '0' ) a logic node when the logic node is supposed to get an invalid logic value ( Unknown Voltage)

Clamp to Zero (Pull Down) Isolation Cell :

- AND Gate based Clamp0 Isolation Cell -




Function: X = (A * EN)



- NOR Gate Based Clamp0 Isolation Cell - This type of cells comes with an inverted logic input A. These are useful in the cases where isolation cell is placed in OFF domain itself (VDDB in this case). They do not require and power supply to pull down the node as they are already sitting in OFF domain and power is OFF


Clamp to One (Pull Up) Isolation Cell -

- OR Gate Based Clamp1 Isolation Cell -





Function : X = (A + EN0)


Latch Type Isolation Cell -









Key Points :

- Only single supply is required for NOR type Pull Down isolation cells.

- To hold the value , Latch type isolation cells must required dual supply

- AND Based / OR Based , Pull Down/Pull Up isolation cells can have dual supply. They can be placed in OFF domain with ON supply



----------------------------------------------------Happy Learning--------------------------------------

Thursday, July 29, 2021

Digital Circuit Design - Problem#5



Problem: Design a digital circuit which can generate a pulse which is high for 16 clock cycles and then goes low (Active High Reset Signal)as shown in the below waveform



Solution :



- Lets have a look at previous problem where we discussed on how can we generate an active low reset pulse which is low for 16 clock cycles

- By carefully observing the problem discussed previously and this problem, we can easily identify that the output waveform in both the problems are exactly opposite

- If we can add an NOT gate at the output of the circuit discussed previously, we can get the expected waveform for this problem

- Lets see the circuit design as below









Please like/share and comment if you have any doubts.

-----------------------------------------------Happy Learning----------------------------------------

Digital Circuit Design - Problem#4



Problem : Design a digital logic circuit to generate a reset pulse which is low for 16 clock cycles (Active Low Reset Generation) as shown in below waveform.







Solution :

- Here we need a output signal of the circuit which is low for 16 cycles and then becomes high

- Can 16 flop in a cascade manner do this job ?

- Lets see the below circuit diagram and see if it matches our expectation -







- yes, as you see this circuit can generate a pulse which is low for 16 clock cycles and then goes high as the first flip-flop input is tied to '1'.

- Assumption here is , initially all the flops are in reset state.




----------------------------------------------------Happy Learning--------------------------------------

Digital Circuit Design - Problem#3



Problem : Design a digital logic circuit to generate a stick bit as shown in the below waveform. The circuit takes an input as I/P and runs at a clock speed of CLK



Solution :



- Once the input is high the output should always remain high irrespective of whether the I/P signal is toggling at later point of time or not

- Lets have a look at below circuit diagram and see if it matches our expectation -







- As you see here once the input goes high and it is captured properly by the flop , then by the incorporation of an OR gate the D input of the flop will always remain high , provided that reset of the flop is not asserted


- Lets try to find the another solution just by writing a HDL pseudo code which translates the problem statement -

always@ (psoedge CLK or negedge rstn)

if(!rstn)

o/p <= 0;

else if(i/p)

o/p <= 1;

else

o/p <= o/p;



- Lets see how this HDL code can be realized into a hardware -





Hope, this problem is helpful in understanding digital logic circuit design and can be very helpful during the interviews.


----------------------------------------------------Happy Learning---------------------------------------

Wednesday, July 28, 2021

Digital Circuit Design - Problem#2



Problem : Design a black box circuit shown below whose input clock and output relationship is shown in below waveform.






Solution :
- Lets have a look at below circuit diagram -




- Now lets see how the waveform looks like for this circuit -





Key Points :


- Negative edge triggered flip -flop alters the output by half clock cycle
- Flip-flop can generate an output with the frequency half of its clock frequency




----------------------------------------------------Happy Learning---------------------------------------




Digital Circuit Design - Problem#1



Problem : Design a digital circuit as depicted in below block diagram which takes DIN as an input and runs at a clock speed of CLK and generates an output DATA as shown in the waveform below.








Solution :

- Since the circuit sample the data at both positive and negative edge of the clock, we need both positive edge and negative edge triggered flip-flops

- Lets have a look at below diagram -





- We notice here that by using both positive and negative edge triggered flip-flops, we are able to sample the DIN at both the clock edges but how will we transfer this sampled data to DATA output port ?

- Well, we need to use a 2*1 MUX to select the sampled data from both of the flip-flops but what should be the select signal of this MUX ?

- The select signal should be like the CLK signal

- Lets have a look at below circuit diagram and see if it can produce a select signal which toggles at CLK frequency



- Yes , here the generated SEL signal can be tied to SEL pin of 2*1 MUX and the MUX output should be similar to the waveform mentioned in the problem.



Hope, this problem helps to understand on how you can design a circuit with given specifications.


Please like/share and comment if you have any doubts related to this problem.


---------------------------------------------Happy Learning --------------------------------------------

Tuesday, July 27, 2021

Verilog HDL Examples - Design of an Event Detector (Circuit Design)



Problem : Design a circuit which detects and event (for one clock cycle) whenever there is a change (Either rising edge or falling edge)in the input signal

Solution :

1) The input signal is asynchronous to the Event Detector logic domain -

Note: The data_in must come out of a register from the source domain or the logic for data_in must be generated in such a way that it is spike free otherwise the synchronizer could catch a glitch and can pass it to the detected event_out








2) The input signal is synchronized to the Event Detector logic domain -

Note:

- When data_in is generated from a different clock domain than 'CLK', a synchronizer (e.g standard 2 -DFF ) is used to synchronize the data_in in the 'CLK' clock domain

- The event_out will get delayed by 2 clock cycles in this case









Waveform :







Please feel free to like/share and comment for any doubts/clarifications regarding Event Detector circuit design.



---------------------------------------------------------Happy Learning --------------------------------

Monday, July 26, 2021

Tic-Tac-Toe Game Design Using Python



And here comes some fun in the time when we all are locked inside our homes because of this COVID-19 pandemic ( 05/25/2020) . I am going to guide you on how you can build your own Tic_Tac_Toe Game using Python scripts in just few minutes and can enjoy playing with your loved once.


How to play Tic_Tac_Toe Game , Please watch the video here.


Tic_Tac_Toe Game : - Tic-tac-toe or noughts and crosses, or Xs and Os is a paper and pencil game for two players, X and O, who take turns marking the spaces in a 3×3 grid. The player who succeeds in placing three of their marks in a horizontal, vertical, or diagonal row is the winner. Here , instead of using paper and pencil we will use our computer/laptop to play this game.


The following example game is won by the first player, X:







Lets get started -
Below are the steps to create a Python Script to run Tic_Tac_Toe Game.


Step- 1 - Write a function that can take in the Player names using your keyboard.

def player_name(): Player_1 = input( "Player 1, Please Enter Your Name :").upper() Player_2 = input( "Player 2, Please Enter Your Name :").upper() return (Player_1 , Player_2)


Step- 2 - Write a function that can take in a player input and assign their marker as 'X' or 'O'.

def player_input(Player_1 , Player_2): marker='' while not (marker == 'X' or marker == 'O'): print("" +Player_1+ ": Do you want to be 'X' or 'O' ? ") marker = input().upper() if marker == 'X': return ('X','O') else: return ('O', 'X')




Step - 3- Write a function that can print out a board. Set up your board as a list, where each index 1-9 corresponds with a number on a number pad, so you get a 3 by 3 board representation.

def keypad_display(keypad_values): clear_output() # Remember, this only works in jupyter! print(' | | ') print(' ' + keypad_values[7] + ' | ' + keypad_values[8] + ' | ' + keypad_values[9]) print(' P(7)| P(8)|P(9)') print('------------------') print(' | | ') print(' ' + keypad_values[4] + ' | ' + keypad_values[5] + ' | ' + keypad_values[6]) print(' P(4)| P(5)|P(6)') print('------------------') print(' | | ') print(' ' + keypad_values[1] + ' | ' + keypad_values[2] + ' | ' + keypad_values[3]) print(' P(1)| P(2)|P(3)')


Step -4 - Write a function that uses the random module to randomly decide which player goes first.

def choose_first(): if random.randint(0,1) == 0: return Player_2 else: return Player_1


Step - 5- Write a function that takes in the board list object, a marker ('X' or 'O'), and a desired position (number 1-9) and assigns it to the board.

def place_marker(keypad_values,marker,position): keypad_values[position]=marker




Step -6 - Write a function that takes in a board and checks to see if someone has won.

def win_check(keypad_values,mark): return ((keypad_values[7] == keypad_values[8] == keypad_values[9] == mark) or (keypad_values[4] == keypad_values[5] == keypad_values[6] == mark) or (keypad_values[1] == keypad_values[2] == keypad_values[3] == mark) or (keypad_values[1] == keypad_values[5] == keypad_values[9] == mark) or (keypad_values[3] == keypad_values[5] == keypad_values[7] == mark) or (keypad_values[1] == keypad_values[4] == keypad_values[7] == mark) or (keypad_values[2] == keypad_values[5] == keypad_values[8] == mark) or (keypad_values[3] == keypad_values[6] == keypad_values[9] == mark))




Step -7 - Write a function that returns a boolean indicating whether a space on the board is freely available.

def space_check(keypad_values,position): return keypad_values[position]== ' '


Step -8 - Write a function that checks if the board is full and returns a boolean value.

def full_board_check(keypad_values): for i in range (1,10): if space_check(keypad_values,i): return False return True


Step - 9 - Write a function that asks for a player's next position (as a number 1-9) and then uses the function from step 7 to check if its a free position. If it is, then return the position for later use.

def player_choice(keypad_values, Player_name): position = 0 while position not in [1,2,3,4,5,6,7,8,9] or not space_check(keypad_values,position): print(""+Player_name+ " , Please Choose Your Next Position (1,9) ?") position = int(input()) return position


Step - 10 - Write a function that asks the player if they want to play again and returns a boolean True if they do want to play again.

def replay(): return input('Do you want to play again ? Enter yes or no ').lower().startswith('y')


Step - 11 - Here comes the REAL JOB !!! Make use of all the functions we have created inside a while loop and run the Game.

#Lets Play the Game !!! while True: keypad_values = [' ']*10 Player_1 , Player_2 = player_name() player1_marker,player2_marker = player_input( Player_1, Player_2) turn = choose_first() print(turn + " Will Go First ") play_game = input ( 'Are you ready to play the game ? Enter y or n : ') if play_game.lower()[0] == 'y': game_on = True else: game_on = False while game_on: if turn == Player_1: keypad_display(keypad_values) position = player_choice(keypad_values , Player_1) place_marker(keypad_values, player1_marker,position) if win_check(keypad_values,player1_marker): keypad_display(keypad_values) print(" Congratulations " +Player_1+"!!! You have Won the Game !!") game_on = False elif full_board_check(keypad_values): keypad_display(keypad_values) print('The Game is Draw!!') break else: turn = Player_2 else: keypad_display(keypad_values) position = player_choice(keypad_values, Player_2) place_marker(keypad_values, player2_marker,position) if win_check(keypad_values,player2_marker): keypad_display(keypad_values) print(" Congratulations " +Player_2+"!!! You have Won the Game !!") game_on = False elif full_board_check(keypad_values): keypad_display(keypad_values) print('The Game is Draw!!') break else: turn = Player_1 if not replay(): print(" Thank You for Playing , Hope You Enjoyed !!!") break




How to RUN the Script?


Well, here I am going to guide you how you can setup your environment and run this game.


Step -1 - Install Python in your computer.
Go to Python.org , Navigate to 'downloads' tab and Click on the latest version of Python available.


Step - 2 - Download the Tic_Tac_Toe_Game.zip file ,unzip it and get the Python Script from below.
Tic_Tac_Toe_Game


Step - 3 - Open the Command Prompt in your computer and Run the below command. ( Make sure you are running the script from correct directory)


python Tic_Tac_Toe_Game.py
Step - 4 - Enter your and your partner name , Choose what you want to pick up from either 'x' or 'o' and the game script will randomly choose which player will go first.






Step - 5 - Keep on playing till the game reaches to Winning position or a Draw.






Step - 6 - Enter 'y' or 'n' if you want to play again or not.




------------------------------------------------------Thank You-----------------------------------------------------


If you face any issues while in understanding the script or running it , please put your query in the below comment section.


Happy Learning, Stay Safe !!!

BlackJack Game Design Using Python



CASINO !!! Yes , You imagined Rightly. Let's see how in couple of minutes you can develop your own Black Jack Game using Python Scripting.


Blackjack : Blackjack, formerly also Black Jack and Vingt-Un, is the American member of a global family of banking games known as "Twenty - One", whose relatives include Pontoon and Vingt-et -Un. It is a comparing card game between one or more players and a dealer, where each player in turn competes against the dealer. Players do not compete against each other. It is played with one or more decks of 52 cards, and is the most widely played casino banking game in the world. (Source : Wikipedia)


To know how to play Blackjack , please watch the video here.


Note: In this Project some of the Object Oriented Programming (OOP) concepts of Python along with basic Python Concepts are used. If you are new to Python , Please visit the Documentation page of www.python.org


Let's get started -


Here are the basic steps to play the game -
To play a hand of Blackjack the following steps must be followed-
Create a deck of 52 cards
Shuffle the deck
Ask the Player for their bet
Make sure that the Player's bet does not exceed their available chips
Deal two cards to the Dealer and two cards to the Player
Show only one of the Dealer's cards, the other remains hidden
Show both of the Player's cards
Ask the Player if they wish to Hit, and take another card
If the Player's hand doesn't Bust (go over 21), ask if they'd like to Hit again.
If a Player Stands, play the Dealer's hand. The dealer will always Hit until the Dealer's value meets or exceeds 17
Determine the winner and adjust the Player's chips accordingly
Ask the Player if they'd like to play again


Note: A standard deck of playing cards has four suits (Hearts, Diamonds, Spades and Clubs) and thirteen ranks (2 through 10, then the face cards Jack, Queen, King and Ace) for a total of 52 cards per deck. Jacks, Queens and Kings all have a rank of 10. Aces have a rank of either 11 or 1 as needed to reach 21 without busting.


Steps to Develop the GAME -
Step - 1 - Declare variables to store suits, ranks and values.suits = ('Hearts','Diamonds','Spades','Clubs') ranks = ('Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten','Jack','Queen','King','Ace') values = {'Two':2,'Three':3,'Four':4,'Five':5,'Six':6,'Seven':7,'Eight':8,'Nine':9,'Ten':10,'Jack':10, 'Queen':10,'King':10,'Ace':11}




Step - 2 - Declare a Boolean value to be used to control while loops.playing = True


Step - 3 - Create a 'card' class which hold two attributes suit and rank. Also , In addition to the Card's __init__ method, consider adding a __str__ method ( Special Methods) that, when asked to print a Card, returns a string in the form "Two of Hearts" ( These are special methods for Python class)class Card(): def __init__(self,suit,rank): self.suit = suit self.rank = rank def __str__(self): return self.rank + '_of_' + self.suit


Step -4 - Create a Deck Class, Here we might store 52 card objects in a list that can later be shuffled. First, though, we need to instantiate all 52 unique card objects and add them to our list. So long as the Card class definition appears in our code, we can build Card objects inside our Deck __init__ method. In addition to an __init__ method we'll want to add methods to shuffle our deck, and to deal out cards during game play.

class Deck(): def __init__(self): self.deck = [] for suit in suits: for rank in ranks: self.deck.append(Card(suit,rank)) def __str__(self): deck_comp = '' for card in self.deck: deck_comp +='\n'+card.__str__() return 'The deck has:' + deck_comp def shuffle(self): random.shuffle(self.deck) def deal(self): single_card = self.deck.pop() return single_card


Step - 5 - Create a Hand Class, In addition to holding Card objects dealt from the Deck, the Hand class may be used to calculate the value of those cards using the values dictionary defined above. It may also need to adjust for the value of Aces when appropriate.

class Hand(): def __init__(self): self.cards = [] self.value = 0 self.aces = 0 def add_card(self,card): self.cards.append(card) self.value += values[card.rank] if card.rank == 'Ace': self.aces +=1 def adjust_for_ace(self): if self.value >21 and self.aces: self.value -=10 // Adding one because according to 'Ace' value in dictionary , 11 will be added first. self.aces -=1


Step - 6 - Create a Chips Class, In addition to decks of cards and hands, we need to keep track of a Player's starting chips, bets, and ongoing winnings. This could be done using global variables, but in the spirit of object oriented programming, let's make a Chips class instead!

class Chips(): def __init__(self,total): self.total = total self.bet = 0 def win_bet(self): self.total +=self.bet def lose_bet(self): self.total -= self.bet


Step -7 - Write a function for taking bets , Since we're asking the user for an integer value, this would be a good place to use try/except( Special blocks to handle the Code ). Remember to check that a Player's bet can be covered by their available chips.



def take_bet(chips): while True: try: chips.bet =int(input("How many chips would you like to bet ?")) except valueError: print('Sorry!! A bet must be an integer') else: if chips.bet > chips.total: print("Sorry, Your bet can't exceed", chips.total) else: break


Step - 8 - Write a function for taking hits, Either player can take hits until they bust. This function will be called during game play anytime a Player requests a hit, or a Dealer's hand is less than 17. It should take in Deck and Hand objects as arguments, and deal one card off the deck and add it to the Hand. You may want it to check for aces in the event that a player's hand exceeds 21. def hit(deck,hand): hand.add_card(deck.deal()) hand.adjust_for_ace()


Step - 9 - Write a function prompting the Player to Hit or Stand, This function should accept the deck and the player's hand as arguments, and assign playing as a global variable.
If the Player Hits, employ the hit() function above. If the Player Stands, set the playing variable to False - this will control the behavior of a while loop later on in our code.def hit_or_stand(deck,hand): global playing while True: x = input("Would you like to Hit or Stand? Enter 'H' or 'S' ") if x[0].lower() == 'h': hit(deck,hand) elif x[0].lower() == 's': print('player stands, dealer is playing') playing = False else: print('Sorry, please try again!!') continue break


Step -10 - Write functions to display cards, When the game starts, and after each time Player takes a card, the dealer's first card is hidden and all of Player's cards are visible. At the end of the hand all cards are shown, and you may want to show each hand's total value. Write a function for each of these scenarios.def show_some(player,dealer): print("\n Dealer's hand:") print('<Card Hidden>') print('',dealer.cards[1]) print("\nPlayer's Hand:",*player.cards , sep='\n') def show_all(player,dealer): print("\nDealer's Hnad:",*dealer.cards , sep='\n') print("Dealer's Hand =", dealer.value) print("\nPlayer's Hand:",*player.cards , sep="\n") print("Player's Hand =",player.value)




Step - 11 -Write functions to handle end of game scenarios, Remember to pass player's hand, dealer's hand and chips as needed.

def player_busts(player,dealer,chips): print("Player Busts!!") chips.lose_bet() def player_wins(player,dealer,chips): print("Player Wins!!") chips.win_bet() def dealer_busts(player,dealer,chips): print("Dealer Busts!!") chips.win_bet() def dealer_wins(player,dealer,chips): print("Dealer Wins!!") chips.lose_bet() def push(player,dealer): print("Dealer and Player tie!!It's a PUSH")


Step -12 - Final Game !!while True: print("Welcome to BlackJack!!!") deck = Deck() deck.shuffle() player_hand = Hand() player_hand.add_card(deck.deal()) player_hand.add_card(deck.deal()) dealer_hand = Hand() dealer_hand.add_card(deck.deal()) dealer_hand.add_card(deck.deal()) player_chips = Chips(100) take_bet(player_chips) show_some(player_hand,dealer_hand) while playing: hit_or_stand(deck,player_hand) show_some(player_hand,dealer_hand) if player_hand.value > 21: player_busts(player_hand,dealer_hand,player_chips) break if player_hand.value<= 21: while dealer_hand.value < 17: hit(deck,dealer_hand) show_all(player_hand,dealer_hand) if dealer_hand.value > 21: dealer_busts(player_hand,dealer_hand,player_chips) elif dealer_hand.value > player_hand.value: dealer_wins(player_hand,dealer_hand,player_chips) elif dealer_hand.value < player_hand.value: player_wins(player_hand,dealer_hand,player_chips) else: push(player_hand,dealer_hand) print("Player's Winnings Stands At",player_chips.total) new_game = input("Would you like to play again? Say Yes or No ") if new_game[0].lower() == 'y': playing = True continue else: print("Thanks for Playing!!") break




How to RUN the Script?
Well, here I am going to guide you on how you can setup your environment and run this game in your windows system.

Step -1 - Install Python in your computer.
Go to Python.org , Navigate to 'downloads' tab and Click on the latest version of Python available.

Step - 2 - Download the BlackJack.zip file ,unzip it and get the Python Script ready for the Game from below.

BlackJack


Step - 3 - Open the Command Prompt in your computer and Run the below command. ( Make sure you are running the script from correct directory)

python BlackJack.py






Step - 4 - Enjoy the Game !!!




----------------------------------------------------Thank You--------------------------------------------------------


If you face any issues while in understanding the script or running it , please put your query in the below comment section.

Happy Learning, Stay Safe !!!