Hi all,
I am using 6.3.02i Xilinx editor and Modelsim 5.3 simulator. I am
slightly confused about which type of address decoding logic should be
used when?.
Consider an example where I need to write and read back some 50
registers in FPGA from a host processor.
Consider,
S_Write_Enable <= write_from_cpu or Ce ;
-- /AWE(Write enable) or /CE(chip enable(Active low))
S_Read_Enable <= read_from_cpu or Ce;
-- /ARE(Read enable) or /CE(chip enable(Active low))
I first tried to use the Case logic,as I needed to program 4 channel
parameters, which could be easily written using Case logic.
Process(S_Write_Enable,Reset)
variable Vl_Offset : std_logic_vector(3 downto 0);
variable Vl_ch_num : std_logic_vector(1 downto 0);
begin
if(Reset = '1') then
-- initializatin
elsif(S_Write_Enable'event AND S_Write_Enable = '0') then
Vl_Offset := address_input(3 downto 0);
Vl_ch_num := conv_integer(address_input(5 downto 4));
case Vl_Offset is
when ZERO =>
S_Ch_Control_Reg <= data_bus;
when ONE =>
S_Code_Phase_Inc(Vl_ch_num)(31 downto 16) <= data_bus;
when TWO =>
S_Code_Phase_Inc(Vl_ch_num)(15 downto 0) <= data_bus;
when THREE =>
S_Data_Phase_Inc(Vl_ch_num)(31 downto 16) <= data_bus;
when FOUR =>
S_Data_Phase_Inc(Vl_ch_num)(15 downto 0) <= data_bus;
-
- Other decoding logics-- 15 * 4 registers(4 Channel Parameters)
-
when others => null;
end case;
end if;
end process;
While reading the registers also , I used the same decoding logic to
read back the registers.
I dont know why? i got timing errors i.e when I simulated it using
ModelSim 5.3 ., and programmed setup(/CE low to AWE low) as 30ns ,
strobe time(/AWE low time) as 30 ns and hold time(/AWE high to /CE
high) as 30 ns. The registers were in unknown state.
How does the case logic works? does it do priority encoding or normal
encoding??
I changed my case logic to direct if-else structure which worked fine .
But I still dont understand why the same logic didnot work in Case.
Process(S_Write_Enable,Reset)
variable Vl_Offset := std_logic_vector(3 downto 0);
variable Vl_ch_num := std_logic_vector(1 downto 0);
begin
if(Reset = '1') then
-- initializatin
elsif(S_Write_Enable'event AND S_Write_Enable = '0') then
if(address_input = "0000001000") then
S_Code_Aid1(0) <= data_bus(C_LFSR_LENGTH-1 downto 0);
end if;
if(address_input = "0000001001") then
S_Code_Aid2(0) <= data_bus(C_LFSR_LENGTH-1 downto 0);
end if;
if(address_input = "0000011000") then
S_Code_Aid1(1) <= data_bus(C_LFSR_LENGTH-1 downto 0);
end if;
if(address_input = "0000011001") then
S_Code_Aid2(1) <= data_bus(C_LFSR_LENGTH-1 downto 0);
end if;
if(address_input = X"0028") then
S_Code_Aid1(2) <= data_bus(C_LFSR_LENGTH-1 downto 0);
end if
if(address_input = X"0029") then
S_Code_Aid2(2) <= data_bus(C_LFSR_LENGTH-1 downto 0);
end if;
end if;
Efficient implementation of Address Decoding logic
Started by ●June 6, 2006
Reply by ●June 6, 20062006-06-06
First, your code (both versions) will create latches, not registers. You need a clock edge specification: if rising_edge(clk) then -- decode/assignment statements go here end if; Second, whenever I see a long case or if-then-else tree, I look for ways to use an array, or array of arrays, to do the decoding for me, possibly within a loop. Think about transforming slices of the address into indices for the array, then assign the desired element(s) of the array from the data bus. For documentation, you can assign meaningfully-named constants to the appropriate index values, and use them where you want to individually access the contents by name. Lastly, VHDL case statement targets are required to be mutually exclusive, therefore no priority is assigned. If-then-else statements do imply priority, but if the synthesis tool is smart enough to figure out that the conditions are all mutually exclusive, then it will remove the priority logic anyway. if address = 1 then a <= data; elsif address = 2 then b <= data; elsif address = 3 then c <= data; end if; Address clearly cannot be 1 and 2 and 3 at the same time; the synthesizer should recognize that and remove the priority logic, creating something that looks more like: if address = 1 then a <= data; end if; if address = 2 then b <= data; end if; if address = 3 then c <= data; end if; or: case address is when 1 => a <= data; when 2 => b <= data; when 3 => c <= data; end case; Andy Jones
Reply by ●June 6, 20062006-06-06
Andy wrote:> If-then-else statements > do imply priority,... if (and only if) two or more cases overlap. Otherwise, excellent posting. -- Mike Treseler
Reply by ●June 6, 20062006-06-06
Mike,
You're correct, but the synthesizer must _recognize_ whether two or
more cases overlap (i.e. if they are not mutually exclusive). If it
cannot prove they are ME, then it must include (keep) the priority
logic. In other words, priority is assumed for an if-then-else
statement until proven otherwise.
Another way to imply priority (which the synthesizer can remove if it
recognizes ME conditions) is to use an exit statement inside an if
statement in a loop:
for i in reg'range loop
if addr = i then
reg(i) <= data;
exit; -- should not make any difference, except for sim speed
end if;
end loop;
An example of where this gets messy is if you are pre-decoding the
address a clock cycle early, then using the decoded strobes to enable
reads or writes to a set of registers. You know the decoded strobes
are ME, but does the synthesizer know it? It would be nice if we could
define a standare mutex function inside an assertion statement, and the
synthesis tool could recognize/accept that as proof that the strobes
(or any set of conditions) were ME.
This is also an excellent application of retiming, since you could
simply delay (register) the address a cycle, then decode and enable
read/write in one cycle using the (ME) delayed address. Then let the
synthesis retiming push the pre-decoding back a cycle for you (if
necessary).
Andy
Mike Treseler wrote:
> Andy wrote:
>
> > If-then-else statements
> > do imply priority,
> ... if (and only if) two or more cases overlap.
>
> Otherwise, excellent posting.
>
> -- Mike Treseler
Reply by ●June 6, 20062006-06-06
Andy wrote:> You're correct, but the synthesizer must _recognize_ whether two or > more cases overlap (i.e. if they are not mutually exclusive). If it > cannot prove they are ME, then it must include (keep) the priority > logic. In other words, priority is assumed for an if-then-else > statement until proven otherwise.Yes, of course, but if *I* know that cases A, B cannot overlap, it is up to *me* to exclude special coverage of the (A and B) case in my description, if I want to save the gates. I would say: ___________________ ... if A then do_A_thing; endif; if B then do_B_thing; endif; ... ___________________ I see coding an if-then-else for this example as a logical error on *my* part, even though there is no functional difference. -- Mike Treseler
Reply by ●June 6, 20062006-06-06
Good point, but just for grins, let's turn this around into a read, rather than a write: If a then data <= a_thing; end if; if b then data <= b_thing; end if; There is still an implied priority of B over A which, without explicitly coding an and-or tree, is pretty difficult to code with no priority implied. In other words, the priority is still implied by the order, but in your case it can be resolved without knowledge of the mutual exclusivity of the conditions if the resulting actions are independent (i.e. do_a and do_b can both be done at the same time). Another way I have coded it is like a tri-state bus, then told the synthesis tool to convert tri-states to muxes. It assumes the tri-state enables are mutually exclusive. Andy Mike Treseler wrote:> Andy wrote: > > > You're correct, but the synthesizer must _recognize_ whether two or > > more cases overlap (i.e. if they are not mutually exclusive). If it > > cannot prove they are ME, then it must include (keep) the priority > > logic. In other words, priority is assumed for an if-then-else > > statement until proven otherwise. > > Yes, of course, but if > *I* know that cases A, B cannot overlap, > it is up to *me* to exclude special coverage > of the (A and B) case in my description, > if I want to save the gates. > > I would say: > ___________________ > ... > if A then > do_A_thing; > endif; > > if B then > do_B_thing; > endif; > ... > ___________________ > I see coding an if-then-else for this > example as a logical error on *my* part, > even though there is no functional difference. > > -- Mike Treseler
Reply by ●June 7, 20062006-06-07
Hi Andy,thanks a lot for your response. Andy wrote:> First, your code (both versions) will create latches, not registers. > You need a clock edge specification: > > if rising_edge(clk) then > -- decode/assignment statements go here > end if; >I am using address decoding logic irrespective of the Clock i.e based on that particular address., i am implementing read and write functionalities.If i need a edge, could I use the /ARE low or /AWE low i.e if falling_edge(AWE) -- decoding end if; Please clarify..
Reply by ●June 7, 20062006-06-07
Andy wrote:> Good point, but just for grins, let's turn this around into a read, > rather than a write: > > If a then > data <= a_thing; > end if; > > if b then > data <= b_thing; > end if; > > There is still an implied priority of B over A which, without > explicitly coding an and-or tree, is pretty difficult to code with no > priority implied.Since a and b are exclusive, I might save a gate by doing a single bit selection, if b_thing is ok as default data: if a then data <= a_thing; else data <= b_thing; end if; -- Mike Treseler
Reply by ●June 7, 20062006-06-07
If you use "falling_edge(awe)" then awe will get tied to the clock input on one or more registers that will hold the signal values that you assign within that if-then clause. Storing data on falling edges of strobes will work, but think about what you are going to do with that data in the latches. The timing can be very difficult to manage if you need to use that data elsewhere in a synchronous (clocked) system. Handling asynchronous buses in a synchronous system is beyond the scope of this conversation. Whole chapters/books have been written on it. Generally speaking, you usually end up syncrhonizing the control lines, and using those synchronized versions to control storage into synchronous registers (i.e. they form clock enables on registers that are clocked by your system clock). If your clock is not fast enough to handle the timing of the controls, then you may need to latch the data with the asynchronous strobe, then use a synchronized version of the strobe to enable transfer from the latch into a register on the system clock. Andy Srikanth BJ wrote:> Hi Andy,thanks a lot for your response. > Andy wrote: > > First, your code (both versions) will create latches, not registers. > > You need a clock edge specification: > > > > if rising_edge(clk) then > > -- decode/assignment statements go here > > end if; > > > I am using address decoding logic irrespective of the Clock i.e based > on that particular address., i am implementing read and write > functionalities.If i need a edge, could I use the /ARE low or /AWE low > i.e > if falling_edge(AWE) > -- decoding > end if; > Please clarify..
Reply by ●June 8, 20062006-06-08
Andy wrote:> If you use "falling_edge(awe)" then awe will get tied to the clock > input on one or more registers that will hold the signal values that > you assign within that if-then clause. > > Storing data on falling edges of strobes will work, but think about > what you are going to do with that data in the latches. The timing can > be very difficult to manage if you need to use that data elsewhere in a > synchronous (clocked) system. Handling asynchronous buses in a > synchronous system is beyond the scope of this conversation. Whole > chapters/books have been written on it. Generally speaking, you usually > end up syncrhonizing the control lines, and using those synchronized > versions to control storage into synchronous registers (i.e. they form > clock enables on registers that are clocked by your system clock). If > your clock is not fast enough to handle the timing of the controls, > then you may need to latch the data with the asynchronous strobe, then > use a synchronized version of the strobe to enable transfer from the > latch into a register on the system clock. >Andy., got to know many things from you. I havenot worked too much on handling asynchronous events., i think its probably very challenging and i guess one should be fully equipped with the basics involved. If you could suggest any book/links which might be very helpful to go further in to the above discussed topics, it would be really appreciated. Thanks in advance, Srikanth





