What is the purpose of the code in the "else" line:
if RdEnabB = '1' then
DoutB <= regfile(to_integer(unsigned(RdAddrB)));
else
DoutB <= (others => 'Z');
end if;
in the accepted answer of this post:
https://electronics.stackexchange.com/questions/100620/vhdl-how-to-double-read-a-register-bank/100756#100756
Questions:
1. Why are the DoutX values driven to high-impedance when they are not read?
2. Does this have an effect on synthesis?
3. Is this for simulation purposes only?
We can only guess the reason. Power saving could be one of the possibilities.
Yes. If the technology supports high-impedance, the circuit will be synthesized appropriately.
No. Answer 2 tells why.
Related
I have the Verilog statement below:
module test (A,B, CLK);
input A, CLK;
output B;
always#(posedge CLK)
if(A) B <= 1'b1;
endmodule
I am expecting a register. However, after I synthesis it with Yosys, I got the result as follow:
assign B = 1'b1;
I don't understand why Yosys translate the above Verilog statement to a constant 1.
Please advice, thanks!
Your B has two possible values:
1'b x during initialization (more in IEEE Std 1364 4.2.2 Variable declarations),
1'b 1 when A is equal to 1'b 1.
You really have only one value. Thats mean you can optimize it to hardwired 1'b 1.
This is not a Yosys fault. All (or almost all) synthesis software will behave same way. If you want to let it work (if I guess what you want), you have to allow B to take two different values. You can do it by initial value equal to 1'b 0 or by reset to value 1'b 0.
I suggest to use reset instead of initial value because initial value can be implemented as A connected to register's set pin.
Interesting! I noticed that if you assign an initial value of zero to the register (e.g. output reg B = 1'b0) you do get a flip-flop. (I used read_verilog <your_code.v> ; synth ; show.)
However, an initial value of one still produces the constant output you mention. So perhaps what's happening here (and I'm only speculating) is that when an initial value is not given, yosys is free to pick its own, in which case it picks 1'b1, so that the whole circuit is equivalent to a simple hard-wired constant? Only when the initial value is zero is the flip-flop necessary?
I'm currently studying for an upcoming quiz in my microprocessors class and ran into a question where an XOR instruction was introduced.
I understood why the N flag was set to 1, but i'm at a loss as to why the C flagwas set to 1.
I looked everywhere online as to why or how this might have occurred, but everything related to a C flag only talked about the arithmetic portion as to why a C flag changes.
I'm using a MSP430 if that helps.
Since it is related to a homework/study preparation, I want to give you a hint.
The XOR operation can be used to add two binary numbers ;-)
What I have
I've a signal of std_logic_vector. I need to give it values from a ROM, what I already do.
The problem
At the beginning of the simulation or use, there's an initialization process which makes it to need some time before ROM returns it first value (about 2 clk period).
Until then, ROM output vector is "UUUU" (since it's 4 bits of width). Let's call this signal ROM_coef_inf, so in simulation, this appears with "UUUU" value, so its colour is orange.
I need
I need to know how can I compare this output in order to know if it's an "undefined vector", in order to give another value (i.e. "0000") to my vector until the first ROM value is ready.
There are several possible solutions:
You could initialize all registers between your ROM and your destination (at least in simulation) with a different value to "UUUU".
A standard compare can test for all 9 STD_LOGIC values:
if (mySignal == 'U') then
You can test signals for special values with is_x(...).
Is is defined like this:
FUNCTION Is_X ( s : std_ulogic) RETURN BOOLEAN IS
BEGIN
CASE s IS
WHEN 'U' | 'X' | 'Z' | 'W' | '-' => RETURN TRUE;
WHEN OTHERS => NULL;
END CASE;
RETURN FALSE;
END;
There are overload for vectors, too.
I assume this is for FPGA use, in which case all registers will have a predictable value after programming, which is zeros unless you specify something else. If all you need is for ROM_coef_inf to have zeros instead of U's for the first clock cycles in simulation, you can simply specify an initial value when declaring the signal:
signal ROM_coef_inf : std_logic_vector(3 downto 0) := "0000";
In ASICs registers will have an unknown value after power is applied. In this case you need to use a reset signal to clear all the registers in your design. It is often a good idea to use a reset signal in an FPGA as well, for example to prevent your circuit from doing anything until the clock is stable.
The answer provided by #Paebbels works only in simulation. In the real world the signals tend to be either an 1 or a 0 (or a transition between them, but that is not discussed here). Number 1 will work, but you need to set it to a value that will never occur in your ROM if you want to check for uninitialized. The simpler option is to count clock cycles. The ROM will always behave the same. So if it takes three cycles to get the first data out, it will always take three cycles. So if you count three cycles you are ok.
I'm working with Arduino and am beginning to work with port registers. I love the speed increases and ability to change multiple ports at the same time. However, I don't know how to watch for a single pin changing using the port registers. (I think it can be done with bitmath, but I don't even know how to start with that.)
So when I check my port register I should get something like this:
PINB = B000xxxxx
Where x are my pin values. Any of those pins could have changed. I want to know when just the rightmost (least significant?) bit has changed. How can I use bitmath to check that just the last one has switched from a 0 to a 1?
"Bitmath" is indeed the answer to the problem. In your case: x & 0x01 will "mask" all but the lowest bit. The result can be compared to 0 or 1 at your wish.
Common idioms are:
x & 0x01 // get only the lowest bit
x & ~0x01 // clear only the lowest bit
x & 0xFE // same: clear only the lowest bit
x | 0x01 // set the lowest bit (others keep their state)
To find out if the bit has changed, you need the previous value, which you mask out as the others have said --
int lastValue = PINB & 0x01;
Then in your code you do
int currentValue = PINB & 0x01;
to get the LSB of the current pin value.
To determine if there was a change to the bit you want the "exclusive OR" (^) operator -- it is "true" if and only if the two bits are different.
if (lastValue ^ currentValue) {
// Code to execute goes here
// Now save "last" as "current" so you can detect the next change
lastValue = currentValue;
}
I am trying to change the value of upper bound in For loop ,but the Loop is running till the upper bound which was defined in the starting.
According to logic loop should go infinite, since value of v_num is always one ahead of i,But loop is executing three time.Please explain
This is the code
DECLARE
v_num number:=3;
BEGIN
FOR i IN 1..v_num LOOP
v_num:=v_num+1;
DBMS_OUTPUT.PUT_LINE(i ||' '||v_num);
END LOOP;
END;
Ouput Coming
1 4
2 5
3 6
This behavior is as specified in the documentation:
FOR-LOOP
...
The range is evaluated when the FOR loop is first entered and is never re-evaluated.
(Oracle Documentation)
Generally, FOR loops would be fixed iterations
For indeterminate looping, use WHILE
This isn't Oracle specific, and why there are separate looping constructs.
While it is generally considered a bad idea to change the loop variable's value, sometimes it seems like the only way to go. However, you might find that loops are optimized, and that might be what is happening here.
There's nothing preventing the language designers from saying "The upper bound of the for loop is evaluated only once". This appears to be the rule that plsql is following here.