Cactus Posted August 4, 2018 Report Share Posted August 4, 2018 I'd like to use CLaSH (http://www.clash-lang.org/) with a Papilio Pro. By and large, it works; however, CLaSH requires an asynchronous, active-high reset spike to initialize registers. This is because CLaSH generates assignments on RESET only, instead of initializers; here's an example VHDL generated from CLaSH: -- Automatically generated VHDL-93 library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; use IEEE.MATH_REAL.ALL; use std.textio.all; use work.all; use work.blinkertop_types.all; entity blinkerTop is port(-- clock CLK_32MHZ : in std_logic; -- asynchronous reset: active high RESET : in std_logic; LED : out std_logic); end; architecture structural of blinkerTop is signal \#tup_app_arg\ : unsigned(31 downto 0); signal \s'\ : boolean; signal \#s'_case_alt\ : boolean; signal s : boolean; signal \#finished_case_alt\ : boolean; signal \#k'_case_alt\ : unsigned(31 downto 0); signal ds : blinkertop_types.tup2; signal \#finished_app_arg\ : signed(63 downto 0); signal x : unsigned(63 downto 0); signal x_0 : blinkertop_types.tup2; signal \x#\ : unsigned(63 downto 0); signal k : unsigned(31 downto 0); signal \#w\ : unsigned(63 downto 0); begin LED <= '1' when \s'\ else '0'; \#tup_app_arg\ <= resize(to_unsigned(0,64),32) when \#finished_case_alt\ else \#k'_case_alt\; \s'\ <= \#s'_case_alt\ when \#finished_case_alt\ else s; \#s'_case_alt\ <= false when s else true; s <= ds.tup2_sel0; \#finished_case_alt\ <= tagToEnum(\#finished_app_arg\); \#w\ <= (\x#\ + to_unsigned(1,64)); \#k'_case_alt\ <= resize((resize(\#w\(31 downto 0),64)),32); -- register begin blinkertop_register : process(CLK_32MHZ,RESET) begin if RESET = '1' then ds <= ( tup2_sel0 => false, tup2_sel1 => resize(to_unsigned(0,64),32) ) -- pragma translate_off after 1 ps -- pragma translate_on ; elsif rising_edge(CLK_32MHZ) then ds <= x_0 -- pragma translate_off after 1 ps -- pragma translate_on ; end if; end process; -- register end \#finished_app_arg\ <= to_signed(1,64) when x = to_unsigned(32000000,64) else to_signed(0,64); x <= resize(\#k'_case_alt\,64); x_0 <= ( tup2_sel0 => \s'\ , tup2_sel1 => \#tup_app_arg\ ); \x#\ <= resize(k,64); k <= ds.tup2_sel1; end; (Note how `ds` is not initialized but set in the `blinkertop_register` process when RESET is high) Of course, for a simple circuilt like above, where the initialization is for 0 anyway, just setting RESET to always low works; however, any slightly more complicated circuit will need register initialization to non-0 values as well. In these cases, I really need the spike. Is there a pin on the Papilio Pro that I could use in my UCF file to get this reset spike? I was able to get it working, in more complicated circuits requiring non-0 initialization, by using a (negated) LogicStart joystick direction, but this approach has two problems: I am getting a warning from the Xilinx tools that the joystick input shouldn't be used for reset or anything clock-like: WARNING:Place:1109 - 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 <RESET> is placed at site <P57>. The corresponding BUFG component <RESET_IBUF_BUFG> is placed at site <BUFGMUX_X3Y13>. 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. This is normally an ERROR but the CLOCK_DEDICATED_ROUTE constraint was applied on COMP.PIN <RESET.PAD> allowing your design to continue. This constraint disables all clock placer rules related to the specified COMP.PIN. 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. I would like my circuit to start in an initialized state instead of requiring me to press a button Quote Link to comment Share on other sites More sharing options...
Jaxartes Posted August 5, 2018 Report Share Posted August 5, 2018 Can you insert a small amount of VHDL (or Verilog) code into your Clash design, and use its output as a RESET, instead of taking RESET from an external pin? Using initializers it'd fairly easy to generate a 1 for a few clock cycles after the FPGA is initialized, and 0 afterwards. It can also be combined with a button so you'd have both ways of causing a reset. It seems like something that would have already been done, and made available as a Clash primitive, by somebody. As I think about it, you might be able to do it just in Clash, with two resets: the "outer reset" is either always 0, or is driven by a button, and is only used by the reset logic the "reset logic" has a few bits of state that's initially zero, and filled in with ones the "inner reset" is driven by the reset logic, and is the NAND of the reset logic's state Not sure of all the details, as I've never used Clash. Quote Link to comment Share on other sites More sharing options...
Jaxartes Posted August 5, 2018 Report Share Posted August 5, 2018 Additional tip: The output of the reset logic should be synchronized by a register. That's to avoid glitches which might be troublesome with an async reset. Quote Link to comment Share on other sites More sharing options...
Cactus Posted August 20, 2018 Author Report Share Posted August 20, 2018 On 8/6/2018 at 3:41 AM, Jaxartes said: Can you insert a small amount of VHDL (or Verilog) code into your Clash design, and use its output as a RESET, instead of taking RESET from an external pin? Using initializers it'd fairly easy to generate a 1 for a few clock cycles after the FPGA is initialized, and 0 afterwards. Thank you! I have now done just that, and it works. Wrapping the whole design into a toplevel VHDL module is a bit of a bummer (since I now have to manually "forward" all real IO from the real Clash code to the IO of this wrapper), but I think there should be a way around that by somehow getting Clash to automagically instantiate a VHDL part and thereby avoid this inversion of structure. Quote It can also be combined with a button so you'd have both ways of causing a reset. Wouldn't that still have that problem of too much fanout, like in the original Xilinx warning? Quote Link to comment Share on other sites More sharing options...
Jaxartes Posted August 21, 2018 Report Share Posted August 21, 2018 18 hours ago, Cactus said: Wouldn't that still have that problem of too much fanout, like in the original Xilinx warning? Not if you pass the result of all your reset logic through a register before using it as a reset -- which I recommended above (in my 2nd post) for other reasons. Then it shouldn't make any difference, to that warning, what is controlling the register. I think the cause of the warning is not with using the pin for something related to reset, but only with directly driving reset from it. The Xilinx tools will try to figure out how long signals take to propagate from where they originate to wherever they are needed. There can be a problem if they take too long, or if the time is too hard to predict. The register improves both. I don't see anything in the warning about fanout, either. I've read about reset fanout being a problem, but haven't encountered it. But then, my designs have been fairly small, have not demanded the utmost of performance, and have used synchronous rather than asynchronous reset. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.