Is it neccessary to have "control unit next state register" to be FALLING edge triggered ? - processor

Each module can be consider to have following power:
[1] It can store data.
[2] It can operate on the data.(arithmetic operation)
some property of modules (listing just that, i am concerned with right now.)
[1] all register/memory element in modules are RAISING edge triggered.
Now this architecture can be use to create a model of a computer processor.
Real Deal:
Is it neccessary to have "control unit next state register" to be FALLING egde triggered ?
(below i explain why i think so)
CLOCK:
|------| |------|[1] |------| |------|
_____| |_________| |_________| |_________| |____
|----|
Data should be valid in this region at least.(considering the setup/hold time).
|----------------|[1]
____________| |_________
So the write signal should be up (if control unit want to) in this region.
This control signals are just the conbinational result of input and CURRENT STATE.
SO that means as the current state changes the control signal changes, which implies the state should change at falling edge[1].
So change of state is simply the change in "control unit state register" which is happening at the falling edge of the clock.
Thats why i think "Is it necessary to have "control unit next state register" to be FALLING edge triggered" ....am i thinking/considering things right ?
If yes then the same(falling edge triggered of control unit state register ) should be happening in actual processor as well.
I am learning stuff so please forgive + correct my mistakes

A common way to handle this is to consider the rising edge of the clock to trigger the “fetch” cycle, and the falling edge to trigger the “execute” cycle.
During “fetch” the memory address is incremented and data from memory is alowed to stabilize and propagate to control circuits (such as ALU’s settings , demultiplexers to control things, multiplexers to sample states for conditional tests, set up shift logic, etc).
During “execute” the things being controlled by the control circuit outputs are triggered (i.e. the test state being read by a multiplexer would be tested, and if true a branch might be taken by loading the program counter with the branch address,so that during the next fetch cycle the system would load the next instruction from the branch address instead of simply incrementing to the next address in memory ).
ANSWERED by: a generous man "BL" (name initials)

Related

Why in the Design Timing Summery (synthesis) in Vivado i get WNS = inf?

I want to make sure that my program works with a clock of at least 100ns. I have already set the timing constraint.
WNS=INF typically means ~ you do not have/ did not setup a clock.
Maybe you dont need a clock - is your circuit all combinatorial? If so, need to add registers and clock to get timing report to report a timed path.
If you circuit has FFs, clk and such already - make sure you tell Vivado (or Quartus) that your clock exists and is a specific frequency - some kind of create_clock constraint.

MSI: When shared and invalid states can occur at the same time

So, as the title says, is it possible that Processor 0 has line A with a Shared (S) state, and Processor 1 has line B with an Invalid (I) state?
Imagine the following situation:
P0: Line A | Modified
P1: Line A | Invalid
P2: Line A | Invalid
If P2 makes a read request for Line A, what is P1 final state? Shared or keeps Invalid?
TL;DR
P1's line A will still be in Invalid state. An Invalid state cannot be changed by other processors' actions.
Both P0 and P2 will have line A in Shared state.
On the Wikipedia's page for the MSI protocol there's the state machine description of the algorithm.
Along with the English description, there are two pictures.
Given a set of processors and their relative cache lines, a processor can either be "active" by making one action among "load/read" and "store/write", or can be "passive" by snooping an event on the bus.
The input to the MSI (and similar) protocol is either an action or a bus event. For simplicity Wikipedia split the state machine in two: one when the input is an action and one when the input is a bus event.
This way you can use one picture to calculate the new states for the lines of the active processor (which is exactly one) and the other picture for the states of the lines of the passive processors.
Let's say processor X is the active one, thus making a load or a store.
The first picture describes how the cache lines state changes for processor X (the active processor):
Each label has the form x/y where x is the input action (either PrRd for a load/read or PrWr for a store/write) and y is the bus event that is emitted ("-" means no event is emitted on the bus).
The second picture is used similarly but for the passive processors (any processor but processor X):
Each label here is again a x/y pair but x is a bus event and y is a bus action.
The bus events are:
BusRd -> Another processor needs to read a line from memory (or upper cache).
BusRdX -> Another processor needs to read a line from memory (or upper cache) but then will immediately modify it (i.e. because it was doing a write).
BugUpgr -> Another processor just wrote to one of its cache line that was only read so far.
Of course, a Flush is the act of writing a line to memory. Wikipedia considers it a bus transaction (I consider it a bus action since it's not used as an input).
We are now ready to answer your question.
P2 is the active processor and needs to read line A, so it performs a PrRd. The first picture tells us that its line A will end up in S state and that a BusRd is issued on the bus (note that this is a mental model, real hardware won't probably send a special transaction, rather it will detect the read itself).
P2: LineA -> Shared
Both P0 and P1 are passive processors and both see the BusRd.
P0 has the line in state Modified, the second picture tells us that it will flush the line (making the last value available to P2) and set line A to state Shared.
P1 has the line in state Invalid, from the second picture we see that there is no way to escape an Invalid state for a passive processor. Specifically, the BusRd input will set the state of line A to Invalid again (it is actually ignored).
So after the read from P2 we have:
P0: LineA -> Shared
P1: LineA -> Invalid
P2: LineA -> Shared

Proper way to change state on a state machine in VHDL

I'm working on a FPGA project where I need to read data from an image sensor. This sensor has different image modes (like test pattern, frame, binning, etc.) and in order to change image mode I need to look for specific signals before writing into the registers.
I have inherited some code that I need to fix since the image sensor sometimes gets stuck when we change image mode.
Concerning the change of image mode, a state machine is used.
The following piece of code shows how the registers for changing mode are currently written.
Essentially, when we want to change mode, we need to wait that the signal MODE_SIG_HIGH becomes high before writing into the registers. Then, when this condition happens, we check what mode we want to set. For example, to set set test pattern, we check if bit S2 is set. Then we performs all the operations to actually change mode (line 10).
01. ...
02. WHEN MODE_SIG_HIGH =>
03. NEXT_ST <= MODE_SIG_HIGH;
04. ...
05. IF S2 = '1' THEN
06. -- configure the sensor to
07. NEXT_ST <= CONFIGURE_TEST_PATTERN;
08. END IF;
09. ...
10. WHEN CONFIGURE_TEST_PATTERN =>
11. ...
I'm having a debate with a friend of mine concerning what is the best way to change state when a new event happens. The above solution doesn't seem right to me.
As far as I understood, when we enter a sate, all the instructions contained in that state are performed in parallel. Therefore, concerning the above piece of code, when we enter the state MODE_SIG_HIGH the instruction at line 03 is executed in parallel to the IF condition. My point is that if the bit S2 is set to 1, the IF condition is true and we end up assigning the value CONFIGURE_TEST_PATTERN to the NEXT_ST. An this ends up in assigning two different values to the same variable (in parallel), in line 03 and in line 07. Am I right or am I missing some basic behavior? The reason for having the instruction at line 3 is because after we enter MODE_SIG_HIGH, it could take some clock cycles before we see on of the mode bits set.
As far as I understood, when we enter a sate, all the instructions
contained in that state are performed in parallel.
Not quite. The only things in VHDL which are concurrent ('performed in parallel') are:
processes
concurrent signal assignments
component instantiations
concurrent procedure calls
concurrent assertions (inc.PSL)
generates
blocks
The code inside a process or subprogram (function/prodedure) executes sequentially. This is where you do your conventional programming, using sequential statements (ie. nothing in the list above). These are your standard control constructs (if, case, loop, etc), sequential signal assignments, and so on. If you carry out signal (or variable) assignments in a sequential region, the last one wins, just like a conventional programming language. There are scheduling rules that make this happen, but you don't need to know about those (yet!)

How does the output register data path work in the 6502?

I am currently developing a subset of the 6502 in LogiSim and at the current stage I am determining which parts to implement and what can be cut out. One of my main resources is Hanson's Block Diagram.
I am currently trying to determine how exactly the output register and its data path works. In this diagram, it looks to me like the data output register goes back onto the bus through the Input Data Latch, but also back into the instruction register.
This confuses me because usually the Address lines to the right of the diagram are sent back into the program memory (not pictured) and not back onto the bus as pictured.
How exactly does this data path work? As a follow up, Is it possible to simplify this area to only take the output and send it to a display instead of back into the processor as pictured?
This confuses me because usually the Address lines to the right of the diagram are sent back into the program memory (not pictured) and not back onto the bus as pictured.
The address bus works differently from the data bus. The address bus is always Output, but the data bus can be Input or Output. We say that the databus is tristate; it either reads, or writes, or does neither. Each pin d0 thru d7 has a simple circuit involving a couple of transistors that controls this. In the case of the 6502, each and every cycle the CPU is either reading something or writing something. In other words, from the 6502's point of view, every cycle is either a read or write cycle.
I am currently trying to determine how exactly the output register and its data path works.
Have a look: the Input Data Latch and Predecode Register are loaded with each φ2. But the Output Data Register is loaded with each φ1. φ1 and φ2 are the two phases of the CPU clock. This arrangement leaves enough time for, say a value to pass from the Input Data Latch, through the ALU, and into the Output Data Register for example.
The Data Output Register's output goes to the Data Bus Tristate Buffers. As you can see, that is controlled by R/W and also by φ2. If it's a read cycle, nothing happens there. So if it's a write cycle, that means the value in the Data Output Register (which was loaded with the previous φ1) is going to be put onto the databus. It also will get loaded into the Predecode Register and into the Input Data Latch.
In this diagram, it looks to me like the data output register goes back onto the bus through the Input Data Latch, but also back into the instruction register.
Absolutely. Anything that the CPU outputs could also get loaded into the Input Data Latch and the Predecode Register. But that doesn't matter, since an instruction will always start with a read cycle, which is the opcode fetch, so the Input Data Latch and the Predecode Register will get overwritten then with the proper value.

XILINX ISE set I/O Marker as Clock

I'm on Xilinx ISE IDE and using the Schematic Editor.
(click for new window)
The constraints file is following:
NET "A" LOC = M18;
NET "F" LOC = P15;
NET "B" LOC = M16;
NET "A" PULLUP;
NET "B" PULLUP;
NET "F" DRIVE = 8;
But when I want to compile my program, there is this error:
ERROR:Place:1108 - A clock IOB / BUFGMUX clock component pair have been found
that are not placed at an optimal clock IOB / BUFGMUX site pair. The clock
IOB component <B> is placed at site <M16>. The corresponding BUFG component
<B_BUFGP/BUFG> is placed at site <BUFGMUX_X2Y3>. There is only a select set
of IOBs that can use the fast path to the Clocker buffer, and they are not
being used. You may want to analyze why this problem exists and correct it.
If this sub optimal condition is acceptable for this design, you may use the
CLOCK_DEDICATED_ROUTE constraint in the .ucf file to demote this message to a
WARNING and allow your design to continue. However, the use of this override
is highly discouraged as it may lead to very poor timing results. It is
recommended that this error condition be corrected in the design. A list of
all the COMP.PINs used in this clock placement rule is listed below. These
examples can be used directly in the .ucf file to override this clock rule.
< NET "B" CLOCK_DEDICATED_ROUTE = FALSE; >
ERROR:Pack:1654 - The timing-driven placement phase encountered an error.
How to fix it?
While any signal can theoretically be used as a clock, it's not true for FPGA; at least not optimally. Clocks need special considerations that translate to restriction on which pin of the FPGA can be routed to the clock network.
I suspect that in your case, you used a push-button to act as a clock signal, which will only work on a very small design (like yours) because of debouncing and the fact that it's not a clock-enabled input port.
You can tell the tool that you want the sub-optimal and potentially erroneous clock path by adding the following constraint to your .ucf:
NET "B" CLOCK_DEDICATED_ROUTE = FALSE;
Keep in mind that you shouldn't do that without being sure that your design is fine with it... I recommend that you do further design with a "real" clock connected to a clock port on your FPGA, every board has one. That constraint will make your design work, but in a larger, faster design is likely to be a source of problems.

Resources