Closed paddytheplaster closed 3 years ago
Did you include resetsynchronizer.vhdl
?
Hi Martijn,
No. I wasn't suspecting that. I started with 'Blinker.hs', and then ran 'clash --vhdl Blinker.hs'.
Should I have added the function? If yes, where do i find it, please? The latter may seem a silly question cause I can use find
. However I don't want to have to run find
every time I pull clash
(and there's a chance the function has changed).
TIA
Paddy
Hi again.
I notice there is a file 'resetsynchronizer.vhdl' which is generated by clash. If I tell my quartus IDE it should consider it part of the project I get a different error. I may get back about that as it looks it's an error in the generated VHDL.
Regards,
Paddy
Did you include
resetsynchronizer.vhdl
?
Hi again,
First of all, IMO Clash should not cache by default as this is dangerous behaviour and may result in errors, which are difficult to find. I just happended to notice that Clash output Using cached result. When I run with -fclash-no-cache
Clash generates some additional files which are needed to compile propoerly.
[nix-shell:~/Altera/Blinker-Clash-1.2.4]$ clash --vhdl Blinker.hs GHC: Parsing and optimising modules took: 2.798s GHC: Loading external modules from interface files took: 0.000s GHC: Parsing annotations took: 0.001s Clash: Parsing and compiling primitives took 0.088s GHC+Clash: Loading modules cumulatively took 3.275s Clash: Compiling Blinker.topEntity Clash: Using cached result for: Blinker.topEntity Clash: Total compilation took 3.285s
[nix-shell:~/Altera/Blinker-Clash-1.2.4]$ clash --vhdl Blinker.hs -fclash-no-cache GHC: Parsing and optimising modules took: 2.584s GHC: Loading external modules from interface files took: 0.000s GHC: Parsing annotations took: 0.001s Clash: Parsing and compiling primitives took 0.086s GHC+Clash: Loading modules cumulatively took 3.043s Clash: Compiling Blinker.topEntity Clash: Ignoring .manifest files Clash: Normalisation took 0.022s Clash: Netlist generation took 0.002s Clash: Total compilation took 3.186s
This now also generates a file altpllE588ED61A4853C9C.qsys. When I include it in my quartus project, my IDE want me to launch an IP upgrade tool. If I run the tool and automatically upgrade, everything compiles fine. When I execute the netlist it also works.
For me this workflow is extremely unsatisfactory as I compile the VHDL from the command line and it's not clear whether I should upgrade IP automatically. All I get is a "it no longer works" error and I have to get back to the Blinker example to check the workflow. Is there a way around this, please?
I now get a warning:
Critical Warning (332168): The following clock transfers have no clock uncertainty assignment. For more accurate results, apply clock uncertainty assignments or use the derive_clock_uncertainty command.
Critical Warning (332169): From CLOCK_50 (Rise) to CLOCK_50 (Rise) (setup and hold)
I already mentioned Clash overwrites my .sdc file, which had a 'derive_clock_uncertainty' in it. Do I need to worry about this?
Regards,
Paddy
With regards to the "IP upgrade": I've been able to compile projects without doing the IP upgrade. Quartus only complains about it because we don't include the Quartus version string in the .qsys
file; and I feel adding a flag to Clash to specify the Quartus version we're generating HDL for is taking it a bit far....
With regards to the .sdc
file being overwritten, it's somewhat annoying to try to distinguish between the .sdc
file clash previously generated from a user-provided .sdc
file put in the same spot. It's probably best not to put any of your own files in the directories where Clash puts generated files.
@paddytheplaster, the SDC files generated by clash are always named <component>.sdc
for any components that have them generated. If you name yours something else hopefully that should be fine as a workaround.
As for the issue with -fclash-cache
, I think that should only be a problem when a blackbox is used which renders additional files (like the .qsys
files for Altera/Intel clock gen). I think at the very least clash should print a warning if a cached result would render an additional file like that. It may also be reasonable to change -fclash-cache
from a boolean flag to something more like -fclash-cache=Always|Auto|Never
, where Auto
never caches a component that uses a blackbox that renders other files for safety. Always
and Never
would preserve the current behaviour.
@paddytheplaster, I've been unable to reproduce the issue locally. From a clean environment when I run
cabal run -- clash --vhdl examples/Blinker.hs
I get the expected output, including the .qsys
file for the altpll
. I can also build with -fclash-edalize
and then use edalize to build Blinker using quartus... Can you give any more info that might help me see if there's anything we can do: clash version, quartus version and commands etc.?
@paddytheplaster, I've been unable to reproduce the issue locally. From a clean environment when I run
cabal run -- clash --vhdl examples/Blinker.hs
I get the expected output, including the
.qsys
file for thealtpll
. I can also build with-fclash-edalize
and then use edalize to build Blinker using quartus... Can you give any more info that might help me see if there's anything we can do: clash version, quartus version and commands etc.?
Hi Alex,
Maybe this is related to me using a "stale" project environment.
I pulled Clash from github yesterday and rebuilt. Quartus: 20.1.0 Build 711 06/05/2020 SJ Standard Edition.
Before I start, please let me know what you mean by clean: which quartus files should I include and which not. At the moment I'm providing: altpll50.* clash-generated files, blinker.qpf, blinker.qsf, blinker.sdc. If you could attach your environment for the Blinker project then that may also be useful.
I've never used edalize.
Regards,
Paddy
With regards to the "IP upgrade": I've been able to compile projects without doing the IP upgrade. Quartus only complains about it because we don't include the Quartus version string in the
.qsys
file; and I feel adding a flag to Clash to specify the Quartus version we're generating HDL for is taking it a bit far....With regards to the
.sdc
file being overwritten, it's somewhat annoying to try to distinguish between the.sdc
file clash previously generated from a user-provided.sdc
file put in the same spot. It's probably best not to put any of your own files in the directories where Clash puts generated files.
Thanks.
Since I started working with the Blinker project again (since yesterday), I've had to upgrade a few times. I suspect this is related to the generated altpll files. Another problem is that it's not clear which Clash-generated files I should add to my quartus project. E.g. these files may change from Clash version to Clash version. It would help if a list of these files could be output (using some Clash flag e.g.).
I don't agree about the .sdc file. If a user already has a file, you can't just silently overwrite the user's file. If Clash insists on using a file with the same name as that of an existing file, the least thing Clash should do is bail out and request the user rename their file. BTW: I still don't know whether I can trust the newly generated .sdc file. Please see my previous post.
Using a different directory for user-defined/user-owned files is a reasonable solution.
Regards,
Paddy
@paddytheplaster, I've been unable to reproduce the issue locally. From a clean environment when I run
cabal run -- clash --vhdl examples/Blinker.hs
I get the expected output, including the
.qsys
file for thealtpll
. I can also build with-fclash-edalize
and then use edalize to build Blinker using quartus... Can you give any more info that might help me see if there's anything we can do: clash version, quartus version and commands etc.?Hi Alex,
Maybe this is related to me using a "stale" project environment.
I pulled Clash from github yesterday and rebuilt. Quartus: 20.1.0 Build 711 06/05/2020 SJ Standard Edition.
Before I start, please let me know what you mean by clean: which quartus files should I include and which not. At the moment I'm providing: altpll50.* clash-generated files, blinker.qpf, blinker.qsf, blinker.sdc. If you could attach your environment for the Blinker project then that may also be useful.
I've never used edalize.
Regards,
Paddy
I just noticed your post does provide enough context to define a clean project. I'll have a look (but this may take a while).
Hi Paddy,
Just to be completely precise because I wasn't before. My clean environment is just clash built from master, and no vhdl
directory with previous compiler runs in. Hope that helps
Hi Paddy,
Just to be completely precise because I wasn't before. My clean environment is just clash built from master, and no
vhdl
directory with previous compiler runs in. Hope that helps
Hi Alex,
I managed to run 'clash --vhdl' on the Blinker.hs in the examples directory and that worked. (Running 'cabal' doesn't work for me.) I then started my quartus IDE, created a new project, added the generated files to it, and the first thing I needed to do was upgrade IP for the generated altplllXYZ file. After this I could compile the project without errors.
This leaves me with more questions. I'd be much obliged if you could answer:
* Previous tutorials required-user supplied altpll files. Are these no longer needed? If not, that looks great but it may be useful to explain this in some tutorial.
* I notice the input and output ports of the topEntity are annotated with pin names. This suggests you don't have to do this in your .qsf file. Is this correct? If yes, that'd be wonderful. Is this described somewhere?
Regards,
Paddy
Hi Paddy,
Clash generates the qsys file for at least the altpll black box now (it is possible to generate additional files in a black box, this should probably be added to the tutorial / docs). So no need to supply your own for blinker, but you may need to for any other IP you have.
As for setting pin names I believe you can do it with port annotations (I hope so, that's the name that sprung to mind.) Hopefully someone else knows where to find information about that
- I notice the input and output ports of the topEntity are annotated with pin names. This suggests you don't have to do this in your .qsf file. Is this correct? If yes, that'd be wonderful. Is this described somewhere?
I believe that's correct. It goes by different names for different HDLs, but for VHDL this would be the chip_pin synthesis attributes. You can set attributes using Clash.Annotations.SynthesisAttributes
. As you've noticed, Blinker.hs
is an example of a design using it.
Hi Paddy,
Just to be completely precise because I wasn't before. My clean environment is just clash built from master, and no
vhdl
directory with previous compiler runs in. Hope that helpsHi again,
If I use the Blinker.hs from the examples directory, I am pretty sure there are two separate problems, one of which is new. (When I wrote that I had tried examples/Blinker.hs earlier, I had just copied an pasted the code of the topEntity.)
The first problem is related to the pin name annotations. Clash generates names like 'Pin_A15', which aren't accepted. If I remove the annotations from Blinker.hs and hard code pin assignments like 'PIN_A15' in my .qsf file, the problem with the pin names disappears.
The second problem is related to the altpll-realted code. Quartus doesn't like it and insists I run the IP upgrade tool. Once that's done, Quartus inserts a line along the following in the .qsf file and all is hunky-dory. You can convince Quartus it should use the generated black box code for the altpll by adding a "QSYS_FILE" entry in the .qsf file. (See below.)
set_global_assignment -name QSYS_FILE altpllE588ED61A4853C9C.qsys
I solved the second problem by using the following script, which assumes there are no pin annotations in 'Blinker.hs'. The script assumes the .qsf file has proper pin assignment lines.
# ----------------------------%<---------------------------------
#!/bin/bash
set -x
set -e
function report( ) {
echo "${1}" 1>&2
}
function abandon( ) {
report "${1}"
exit 1
}
EXT=hs
TOP=Blinker
SRC=./examples
SOURCE=${SRC}/${TOP}.${EXT}
[ -f ${SOURCE} ] \
|| abandon "${SOURCE} not found"
PROJECT=$( sed -n -e 's/^.*t_name *= *"\(.*\)" *$/\1/p' ${SOURCE} )
[ -n "${PROJECT}" ] \
|| abandon "Can't find 't_name=\"project name\"' on single line in ${SOURCE}"
QUARTUS_DIR=./vhdl/${TOP}/${PROJECT}
[ -d ${QUARTUS_DIR} ] \
|| abandon "Error: ${QUARTUS_DIR} does not exist !"
rm -rf ${QUARTUS_DIR}/*.qsys
clash --vhdl ${SOURCE} -fclash-no-cache
cd ${QUARTUS_DIR}
# =======================================================================
# Test if the project files needed exists
# =======================================================================
# .qsf
for EXT in qsf qpf sdc; do
[ -e ${PROJECT}.${EXT} ] \
|| abandon "Error: ${PROJECT}.${EXT} not found"
done
# =======================================================================
# Sanitise .qsf file
# =======================================================================
echo >> ${PROJECT}.qsf
sed -i '$d' ${PROJECT}.qsf
# =======================================================================
# Adjust .qsys entry in project file
# =======================================================================
QSYS=$( ls *.qsys )
sed -i '/ QSYS_FILE /d' ${PROJECT}.qsf
echo "set_global_assignment -name QSYS_FILE ${QSYS}" >> ${PROJECT}.qsf
# =======================================================================
# Add VHDL files
# =======================================================================
# remove existing files from project file
SGA_SPELL="set_global_assignment -name VHDL_FILE "
sed -i '/\<[_A-Za-z][_A-Za-z]*.vhdl/d' ${PROJECT}.qsf
for FILE in *.vhdl; do
echo "${SGA_SPELL} ${FILE}" >> ${PROJECT}.qsf
done
# =======================================================================
# Synthesis
# =======================================================================
report "> Beginning synthesis ..."
nice -n 19 \
quartus_map --read_settings_files=on --write_settings_files=off \
${PROJECT} -c ${PROJECT}
report " > Synthesis done"
# =======================================================================
# Filter (Place and route)
# =======================================================================
report "> Filter (Place and route) ..."
nice -n 19 \
quartus_fit --read_settings_files=off --write_settings_files=off \
${PROJECT} -c ${PROJECT}
report " > Filter done"
# =======================================================================
# Assembler (Generating programming files)
# =======================================================================
report "> Assembler (Generating programming files) ..."
quartus_asm --read_settings_files=off --write_settings_files=off \
${PROJECT} -c ${PROJECT}
report " > Assembler done"
# =======================================================================
# TimeQuest Timing Analysis
# =======================================================================
report "> TimeQuest Timing Analysis ..."
nice -n 19 \
quartus_sta ${PROJECT} -c ${PROJECT}
report " > TimeQuest Timing Analysis done"
# =======================================================================
# Program FPGA
# =======================================================================
SOF=${PROJECT}.sof
if [ ! -e ${SOF} ]; then
SOF=output_files/${SOF}
[ -e ${SOF} ] \
|| abandon "Can't find .sof file"
fi
nice -n 19 \
quartus_pgm -c USB-Blaster -m JTAG -o "p;${SOF}"
# ----------------------------%<---------------------------------
The following are the contents of blinker.qsf, which should be in '${QUARTUS_DIR}'.
# ----------------------------%<---------------------------------
#============================================================
# Build by Terasic System Builder
#============================================================
set_global_assignment -name FAMILY "Cyclone IV E"
set_global_assignment -name DEVICE EP4CE22F17C6
set_global_assignment -name TOP_LEVEL_ENTITY "blinker"
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 12.0
set_global_assignment -name LAST_QUARTUS_VERSION "20.1.0 Standard Edition"
set_global_assignment -name PROJECT_CREATION_TIME_DATE "9:50:00 MAY 01,2020"
set_global_assignment -name DEVICE_FILTER_PACKAGE FBGA
set_global_assignment -name DEVICE_FILTER_PIN_COUNT 256
set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 6
#============================================================
# CLOCK
#============================================================
set_location_assignment PIN_R8 -to CLOCK_50
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to CLOCK_50
#============================================================
# LED
#============================================================
set_location_assignment PIN_A15 -to LED[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[0]
set_location_assignment PIN_A13 -to LED[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[1]
set_location_assignment PIN_B13 -to LED[2]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[2]
set_location_assignment PIN_A11 -to LED[3]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[3]
set_location_assignment PIN_D1 -to LED[4]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[4]
set_location_assignment PIN_F3 -to LED[5]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[5]
set_location_assignment PIN_B1 -to LED[6]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[6]
set_location_assignment PIN_L3 -to LED[7]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to LED[7]
#============================================================
# KEY
#============================================================
set_location_assignment PIN_J15 -to KEY[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to KEY[0]
set_location_assignment PIN_E1 -to KEY[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to KEY[1]
#============================================================
# End of pin assignments by Terasic System Builder
#============================================================
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW"
set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
set_global_assignment -name SDC_FILE blinker.sdc
set_global_assignment -name QSYS_FILE altpllE588ED61A4853C9C.qsys
set_global_assignment -name VHDL_FILE blinker.vhdl
set_global_assignment -name VHDL_FILE blinker_types.vhdl
set_global_assignment -name VHDL_FILE resetsynchronizer.vhdl
# ----------------------------%<---------------------------------
Finally, I know it would have been better if I had attached the source code. However, for some reason my browser wouldn't let me select them because it didn't like their file extensions.
Regards,
Paddy
Using:
master
of the Clash compilerI cannot replicate your issues:
Pin_A15
Processing -> Start Compilation (Ctrl+L)
in the menu.And as we can see from Pin Planner
, the ports are assigned to the correct pins:
This is the generated blinker.vhdl
file that I get:
-- 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.blinker_types.all;
entity blinker is
port(-- clock
CLOCK_50 : in blinker_types.clk_input;
KEY0 : in boolean;
KEY1 : in std_logic;
LED : out std_logic_vector(7 downto 0));
attribute altera_attribute : string;
attribute altera_attribute of LED : signal is "-name IO_STANDARD ""3.3-V LVTTL""";
attribute altera_attribute of KEY1 : signal is "-name IO_STANDARD ""3.3-V LVTTL""";
attribute altera_attribute of KEY0 : signal is "-name IO_STANDARD ""3.3-V LVTTL""";
attribute altera_attribute of CLOCK_50 : signal is "-name IO_STANDARD ""3.3-V LVTTL""";
attribute chip_pin : string;
attribute chip_pin of LED : signal is "L3, B1, F3, D1, A11, B13, A13, A15";
attribute chip_pin of KEY1 : signal is "E1";
attribute chip_pin of KEY0 : signal is "J15";
attribute chip_pin of CLOCK_50 : signal is "R8";
end;
architecture structural of blinker is
-- examples/Blinker.hs:52:1-9
signal \c$ds1_app_arg\ : blinker_types.rst_input;
-- examples/Blinker.hs:52:1-9
signal \c$$d(%,,%)_app_arg\ : blinker_types.rst_dom50;
-- examples/Blinker.hs:52:1-9
signal \c$ds_app_arg\ : blinker_types.tup3 := ( tup3_sel0_std_logic_vector => std_logic_vector'(x"01"), tup3_sel1_ledmode => "0", tup3_sel2_index_16650001 => to_unsigned(0,24) );
signal result : boolean;
-- examples/Blinker.hs:98:1-8
signal leds : std_logic_vector(7 downto 0);
-- examples/Blinker.hs:98:1-8
signal mode : blinker_types.ledmode;
-- examples/Blinker.hs:98:1-8
signal cntr : blinker_types.index_16650001;
signal \c$case_alt\ : blinker_types.tup2;
signal \c$app_arg\ : blinker_types.index_16650001;
signal \c$app_arg_0\ : blinker_types.ledmode;
signal \c$case_alt_0\ : blinker_types.ledmode;
signal \c$app_arg_1\ : std_logic_vector(7 downto 0);
signal \c$case_alt_1\ : std_logic_vector(7 downto 0);
-- examples/Blinker.hs:52:1-9
signal old : std_logic := '1';
-- examples/Blinker.hs:52:1-9
signal \$d(%,,%)\ : blinker_types.rst_dom50;
-- examples/Blinker.hs:52:1-9
signal clk50 : blinker_types.clk_dom50;
-- examples/Blinker.hs:52:1-9
signal ds1 : blinker_types.tup2_0;
signal result_selection_res : boolean;
begin
\c$ds1_app_arg\ <= '1' when (not KEY0) = true else '0';
\c$$d(%,,%)_app_arg\ <= '1' when (not ds1.tup2_0_sel1_boolean) = true else '0';
-- register begin
cds_app_arg_register : process(clk50,\$d(%,,%)\)
begin
if \$d(%,,%)\ = '1' then
\c$ds_app_arg\ <= ( tup3_sel0_std_logic_vector => std_logic_vector'(x"01"), tup3_sel1_ledmode => "0", tup3_sel2_index_16650001 => to_unsigned(0,24) );
elsif rising_edge(clk50) then
\c$ds_app_arg\ <= \c$case_alt\.tup2_sel0_tup3;
end if;
end process;
-- register end
result_selection_res <= old = ('0');
result <= KEY1 = ('1') when result_selection_res else
false;
leds <= \c$ds_app_arg\.tup3_sel0_std_logic_vector;
mode <= \c$ds_app_arg\.tup3_sel1_ledmode;
cntr <= \c$ds_app_arg\.tup3_sel2_index_16650001;
\c$case_alt\ <= ( tup2_sel0_tup3 => ( tup3_sel0_std_logic_vector => \c$app_arg_1\
, tup3_sel1_ledmode => \c$app_arg_0\
, tup3_sel2_index_16650001 => \c$app_arg\ )
, tup2_sel1_std_logic_vector => leds );
with (cntr) select
\c$app_arg\ <= to_unsigned(0,24) when x"FE0F10",
cntr + to_unsigned(1,24) when others;
\c$app_arg_0\ <= \c$case_alt_0\ when result else
mode;
with (mode) select
\c$case_alt_0\ <= "1" when "0",
"0" when others;
with (cntr) select
\c$app_arg_1\ <= \c$case_alt_1\ when x"000000",
leds when others;
with (mode) select
\c$case_alt_1\ <= std_logic_vector(rotate_left(unsigned(leds),to_integer(to_signed(1,64)))) when "0",
not leds when others;
LED <= \c$case_alt\.tup2_sel1_std_logic_vector;
-- register begin
old_register : process(clk50,\$d(%,,%)\)
begin
if \$d(%,,%)\ = '1' then
old <= '1';
elsif rising_edge(clk50) then
old <= KEY1;
end if;
end process;
-- register end
resetsynchronizer_d : entity resetsynchronizer
port map
( result => \$d(%,,%)\
, eta => clk50
, eta1 => \c$$d(%,,%)_app_arg\ );
clk50 <= ds1.tup2_0_sel0_clk_dom50;
altpll_block : block
signal locked : std_logic;
signal plllock : boolean;
signal pllout : blinker_types.clk_dom50;
component altpllE588ED61A4853C9C
port ( clk : in blinker_types.clk_input
; areset : in blinker_types.rst_input
; c0 : out blinker_types.clk_dom50
; locked : out std_logic );
end component;
begin
altpll50 : component altpllE588ED61A4853C9C
port map
( clk => CLOCK_50
, areset => \c$ds1_app_arg\
, c0 => pllout
, locked => locked );
with (locked) select
plllock <= true when '1',
false when others;
ds1 <= ( tup2_0_sel0_clk_dom50 => pllout
, tup2_0_sel1_boolean => plllock );
end block;
end;
Using:
- The latest HEAD of
master
of the Clash compiler- The latest https://github.com/clash-lang/clash-compiler/blob/03890037acbf399fc78f4c7c35e11e188a84c7ee/examples/Blinker.hs
- Quartus Prime 19.1 Lite edition
I cannot replicate your issues:
- Clash doesn't generate any signals named
Pin_A15
- Although Quartus shows a big red "IP upgrade required": This warning can be safely ignored, and Quartus builds the bitstream when I click
Processing -> Start Compilation (Ctrl+L)
in the menu.And as we can see from
Pin Planner
, the ports are assigned to the correct pins:This is the generated
blinker.vhdl
file that I get:-- 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.blinker_types.all; entity blinker is port(-- clock CLOCK_50 : in blinker_types.clk_input; KEY0 : in boolean; KEY1 : in std_logic; LED : out std_logic_vector(7 downto 0)); attribute altera_attribute : string; attribute altera_attribute of LED : signal is "-name IO_STANDARD ""3.3-V LVTTL"""; attribute altera_attribute of KEY1 : signal is "-name IO_STANDARD ""3.3-V LVTTL"""; attribute altera_attribute of KEY0 : signal is "-name IO_STANDARD ""3.3-V LVTTL"""; attribute altera_attribute of CLOCK_50 : signal is "-name IO_STANDARD ""3.3-V LVTTL"""; attribute chip_pin : string; attribute chip_pin of LED : signal is "L3, B1, F3, D1, A11, B13, A13, A15"; attribute chip_pin of KEY1 : signal is "E1"; attribute chip_pin of KEY0 : signal is "J15"; attribute chip_pin of CLOCK_50 : signal is "R8"; end; architecture structural of blinker is -- examples/Blinker.hs:52:1-9 signal \c$ds1_app_arg\ : blinker_types.rst_input; -- examples/Blinker.hs:52:1-9 signal \c$$d(%,,%)_app_arg\ : blinker_types.rst_dom50; -- examples/Blinker.hs:52:1-9 signal \c$ds_app_arg\ : blinker_types.tup3 := ( tup3_sel0_std_logic_vector => std_logic_vector'(x"01"), tup3_sel1_ledmode => "0", tup3_sel2_index_16650001 => to_unsigned(0,24) ); signal result : boolean; -- examples/Blinker.hs:98:1-8 signal leds : std_logic_vector(7 downto 0); -- examples/Blinker.hs:98:1-8 signal mode : blinker_types.ledmode; -- examples/Blinker.hs:98:1-8 signal cntr : blinker_types.index_16650001; signal \c$case_alt\ : blinker_types.tup2; signal \c$app_arg\ : blinker_types.index_16650001; signal \c$app_arg_0\ : blinker_types.ledmode; signal \c$case_alt_0\ : blinker_types.ledmode; signal \c$app_arg_1\ : std_logic_vector(7 downto 0); signal \c$case_alt_1\ : std_logic_vector(7 downto 0); -- examples/Blinker.hs:52:1-9 signal old : std_logic := '1'; -- examples/Blinker.hs:52:1-9 signal \$d(%,,%)\ : blinker_types.rst_dom50; -- examples/Blinker.hs:52:1-9 signal clk50 : blinker_types.clk_dom50; -- examples/Blinker.hs:52:1-9 signal ds1 : blinker_types.tup2_0; signal result_selection_res : boolean; begin \c$ds1_app_arg\ <= '1' when (not KEY0) = true else '0'; \c$$d(%,,%)_app_arg\ <= '1' when (not ds1.tup2_0_sel1_boolean) = true else '0'; -- register begin cds_app_arg_register : process(clk50,\$d(%,,%)\) begin if \$d(%,,%)\ = '1' then \c$ds_app_arg\ <= ( tup3_sel0_std_logic_vector => std_logic_vector'(x"01"), tup3_sel1_ledmode => "0", tup3_sel2_index_16650001 => to_unsigned(0,24) ); elsif rising_edge(clk50) then \c$ds_app_arg\ <= \c$case_alt\.tup2_sel0_tup3; end if; end process; -- register end result_selection_res <= old = ('0'); result <= KEY1 = ('1') when result_selection_res else false; leds <= \c$ds_app_arg\.tup3_sel0_std_logic_vector; mode <= \c$ds_app_arg\.tup3_sel1_ledmode; cntr <= \c$ds_app_arg\.tup3_sel2_index_16650001; \c$case_alt\ <= ( tup2_sel0_tup3 => ( tup3_sel0_std_logic_vector => \c$app_arg_1\ , tup3_sel1_ledmode => \c$app_arg_0\ , tup3_sel2_index_16650001 => \c$app_arg\ ) , tup2_sel1_std_logic_vector => leds ); with (cntr) select \c$app_arg\ <= to_unsigned(0,24) when x"FE0F10", cntr + to_unsigned(1,24) when others; \c$app_arg_0\ <= \c$case_alt_0\ when result else mode; with (mode) select \c$case_alt_0\ <= "1" when "0", "0" when others; with (cntr) select \c$app_arg_1\ <= \c$case_alt_1\ when x"000000", leds when others; with (mode) select \c$case_alt_1\ <= std_logic_vector(rotate_left(unsigned(leds),to_integer(to_signed(1,64)))) when "0", not leds when others; LED <= \c$case_alt\.tup2_sel1_std_logic_vector; -- register begin old_register : process(clk50,\$d(%,,%)\) begin if \$d(%,,%)\ = '1' then old <= '1'; elsif rising_edge(clk50) then old <= KEY1; end if; end process; -- register end resetsynchronizer_d : entity resetsynchronizer port map ( result => \$d(%,,%)\ , eta => clk50 , eta1 => \c$$d(%,,%)_app_arg\ ); clk50 <= ds1.tup2_0_sel0_clk_dom50; altpll_block : block signal locked : std_logic; signal plllock : boolean; signal pllout : blinker_types.clk_dom50; component altpllE588ED61A4853C9C port ( clk : in blinker_types.clk_input ; areset : in blinker_types.rst_input ; c0 : out blinker_types.clk_dom50 ; locked : out std_logic ); end component; begin altpll50 : component altpllE588ED61A4853C9C port map ( clk => CLOCK_50 , areset => \c$ds1_app_arg\ , c0 => pllout , locked => locked ); with (locked) select plllock <= true when '1', false when others; ds1 <= ( tup2_0_sel0_clk_dom50 => pllout , tup2_0_sel1_boolean => plllock ); end block; end;
Hi Chrisatiaan,
I just removed the pin assignments from the .qsf file and went through the workflow with the pin annotations enabled in 'Blinker.hs'. To my surprise it worked.
This is curious because I spent several hours figuring out what is going on. At some stage I definitely got the error with the pin names and at that stage I thought it was caused by the pin annotation because when I commented them out, the error disappeared.
I'll see if I can reproduce. I'm not making it up.
Regards,
Paddy
Hi again,
I tried a few things but I can't reproduce the error about pin names starting with 'Pin_'.
All I can say is that quartus does appear to use pin names of the form 'Pin*' in some of its text-based output (the error I got was through the command line interface). E.g. when I open 'blinker.map.rpt', I get the following information about the pin assignments. In the GUI the pin names are displayed as 'PIN*' etc.
+---------------------------------------------------+
; Source assignments for Top-level Entity: |blinker ;
+-------------+-------------+------+----------------+
; Assignment ; Value ; From ; To ;
+-------------+-------------+------+----------------+
; LOCATION ; Pin_L3 ; - ; LED[7] ;
; LOCATION ; Pin_B1 ; - ; LED[6] ;
<MORE LINES OMITTED>
Regards,
Paddy
- I notice the input and output ports of the topEntity are annotated with pin names. This suggests you don't have to do this in your .qsf file. Is this correct? If yes, that'd be wonderful. Is this described somewhere?
I believe that's correct. It goes by different names for different HDLs, but for VHDL this would be the chip_pin synthesis attributes. You can set attributes using
Clash.Annotations.SynthesisAttributes
. As you've noticed,Blinker.hs
is an example of a design using it.
Thanks again Martijn,
I'm now trying the in-Haskell pin annotations but I get a problem when I use a port product for the output.
, t_output = PortProduct "" [ PortName "TX"
, PortName "LED"
]
-- output of top entity
-> Signal ClockDomain (Bit,BitVector 8)
`Annotate` 'StringAttr "chip_pin" "D3, L3, B1, F3, D1, A11, B13, A13, A15"
`Annotate` 'StringAttr "altera_attribute" "-name IO_STANDARD \"3.3-V LVTTL
When I compile this I get the following.
/home/paddy/Altera/Clash/tops/TopEntity.lhs:70:3: error:
Clash.Netlist.Util(1427): Attempted to split Product into a number of HDL ports. This is not allowed in combination with attribute annotations. You can annotate Product's components by splitting it up manually.
The source location of the error is not exact, only indicative, as it is acquired
after optimizations. The actual location of the error can be in a function that is
inlined. To prevent inlining of those functions, annotate them with a NOINLINE pragma.
When I turn the '(Bit,BitVector 8)' into a 'BitVector 9' (and concatenate the 'Bit' and 'BitVector 8' signals) I get the following:
Clash.Netlist.Util(743): Ports were annotated as product, but type wasn't one:
Filtered was: FilteredHWType (Annotated [StringAttr' "altera_attribute" "-name IO_STANDARD \"3.3-V LVTTL\"",StringAttr' "chip_pin" "D3, L3, B1, F3, D1, A11, B13, A13, A15"] (Annotated [StringAttr' "chip_pin" "D3, L3, B1, F3, D1, A11, B13, A13, A15"] (BitVector 9))) []
Ports was: PortProduct "" [PortName "TX",PortName "LED"]
CallStack (from HasCallStack):
error, called at src/Clash/Netlist/Util.hs:743:3 in clash-lib-1.3.0-LvWndWMDBc6AzweKogm6Ks:Clash.Netlist.Util
I checked the documentation on 'http://hackage.haskell.org/package/clash-prelude-1.2.4/docs/Clash-Annotations-SynthesisAttributes.html' but it doesn't refer to signals of product types. Is there a way around this, please?
Regards,
Paddy
This is my first brush with these annotations, but this works:
, t_output = PortProduct "" [ PortName "TX"
, PortName "LED"
]
[...]
-> Signal System
( Bit `Annotate`
[ 'StringAttr "chip_pin" "D3"
, 'StringAttr "altera_attribute" "-name IO_STANDARD \"3.3-V LVTTL\""
]
, BitVector 8 `Annotate`
[ 'StringAttr "chip_pin" "L3, B1, F3, D1, A11, B13, A13, A15"
, 'StringAttr "altera_attribute" "-name IO_STANDARD \"3.3-V LVTTL\""
]
)
We should add such an example to the documentation.
This is my first brush with these annotations, but this works:
, t_output = PortProduct "" [ PortName "TX" , PortName "LED" ] [...] -> Signal System ( Bit `Annotate` [ 'StringAttr "chip_pin" "D3" , 'StringAttr "altera_attribute" "-name IO_STANDARD \"3.3-V LVTTL\"" ] , BitVector 8 `Annotate` [ 'StringAttr "chip_pin" "L3, B1, F3, D1, A11, B13, A13, A15" , 'StringAttr "altera_attribute" "-name IO_STANDARD \"3.3-V LVTTL\"" ] )
We should add such an example to the documentation.
This is my first brush with these annotations, but this works:
, t_output = PortProduct "" [ PortName "TX" , PortName "LED" ] [...] -> Signal System ( Bit `Annotate` [ 'StringAttr "chip_pin" "D3" , 'StringAttr "altera_attribute" "-name IO_STANDARD \"3.3-V LVTTL\"" ] , BitVector 8 `Annotate` [ 'StringAttr "chip_pin" "L3, B1, F3, D1, A11, B13, A13, A15" , 'StringAttr "altera_attribute" "-name IO_STANDARD \"3.3-V LVTTL\"" ] )
We should add such an example to the documentation.
Great. Thanks a mille.
Regards,
Paddy
I believe this was mostly an issue with configuring the EDA tooling. I'll therefore be closing this issue. If this is incorrect, please reopen.
Hello again,
I am having some problems with a communication circuit. I suspect this is related to a clock issue. To make sure everything works properly, I just tried to compile the Blinker example and I got an error when I tried to compile the generated VHDL. (I just pulled the most recent development version from github.)
I downloaded the Blinker sources for the highest (1.0) Clash version on the tutorial site. This is how I got to the tutorial site.
https://clash-lang.org/ -> [Click Documentation] -> https://clash-lang.org/documentation/ -> [Click Tutorial] -> http://hackage.haskell.org/package/clash-prelude-1.2.4/docs/Clash-Tutorial.html
My quartus compiler gives:
(The blinker.hs in (git development) clash-compiler/examples/ also throws this error. Aren't the files in that directory unit tested?)
I note that clash still overwrites my .sdc file which has a 'derive_pll_clocks' statement in it.
Any suggestions?
Paddy