# Is it ok to use both rising and falling egde in this VHDL design?

I'm pretty new to designing hardware with VHDL, and I think I'm making a noob mistake. I'm making a CPU and my registerfile is rising_edge triggered. I had a problem though. I'll try putting some pseudo code to clear it up

on rising_edge {r0in <= 20; }
CLOCK CYCLE
on rising_edge {r1in <= r0out; }
CLOCK CYCLE


My problem is that r1in would be getting the old value of r0 instead of the appropriate 20. I then proceeded to change my code to use falling_edge instead of rising_edge for only the registerfile. A simplified version is below:

process(WriteEnable, DataIn, Clock)
begin
if falling_edge(Clock) then --note the falling_edge instead of rising_edge
if(WriteEnable = '1') then
registers <= DataIn;
end if;
end if;
end process;
DataOut <= registers;


So now my registers are falling_edge triggered instead of rising_edge. All of the test cases I have pass with this configuration and it synthesizes without warnings... but is this correct?

I'm asking this question because I've long been told to only use both edges in a design if you really know what you're doing. I've been programming in VHDL for a few weeks, so I want to make sure that this is an appropriate case to ues both edges

-

Yes, you can, but it's not recommended. You will need to have the hardware synthesize at twice the clock rate now - a 100MHz bus needs to be set up at 200MHz because the data only has half the time to propagate. You have effectively made it DDR.

It seems that you are actually misunderstanding how a process works. All outputs within a process are scheduled to be presented on the output upon the next clock cycle. So everything you code within that process is actually happening in parallel and must stabilize before the next clock comes along, which is when the outputs will be posted.

-
What I don't understand then is how do you make a CPU in which some instructions take only one clock-cycle. This seems impossible without doing this way – Earlz May 18 '12 at 4:48
For instance, how does AVR do it? – Earlz May 18 '12 at 4:49
Ok, this is the answer, I was going about it wrong. My DataOut should've been like this: DataOut <= registers when WriteEnable='0' else DataIn;. This way, written values to registers appear at the next clock edge, instead of the next-next one. I thought about doing this before, but didn't think it'd work right.. All my tests now pass with this (though some of my tests were actually wrong) – Earlz May 18 '12 at 5:11
@Earlz, very incomplete AVR core in Verilog: bitbucket.org/avakar/pv200_avrcore/src/e085fd7d2023/avrcorev/… You need to fetch the instructions one cycle before executing them. That's why rjmp takes two cycles. – avakar May 18 '12 at 6:05
Ding! Looks like you got it. :) – Aaron D. Marasco May 18 '12 at 9:03

The code you wrong will work if the target part has this capability. Since you can invert the clock and use the rising edge, it will. However the timing may not be what you wish.

You don't need WriteEnable, DataIn in the process sensitivity.

-
 You get warnings if you don't include those though in the process sensitivity though(at least from XST... I know their pointless warnings though) – Earlz May 17 '12 at 23:26 @Earlz: I suspect what you saw were warnings for a combinatorial process with an incomplete sensitivity list. – Brian Carlton May 17 '12 at 23:40 Brian Carlton is right, the sensitivity list depends only on the signals that are used in the "first level" of if statements inside a process. In the example posted, the process only "runs" when there's a change in the clock signal, otherwise it's not "running". – ajs410 May 18 '12 at 16:32