{"id":1638,"date":"2022-11-03T10:56:59","date_gmt":"2022-11-03T09:56:59","guid":{"rendered":"http:\/\/www.fabienm.eu\/flf\/?p=1638"},"modified":"2022-11-03T10:58:33","modified_gmt":"2022-11-03T09:58:33","slug":"clash-un-hdl-base-sur-haskell","status":"publish","type":"post","link":"http:\/\/www.fabienm.eu\/flf\/clash-un-hdl-base-sur-haskell\/","title":{"rendered":"ClaSH un HDL bas\u00e9 sur Haskell"},"content":{"rendered":"\n<p>La version 1.0 de C\u03bbaSH est sortie en septembre 2019. Profitons de cette sortie pour pr\u00e9senter ce langage de description mat\u00e9riel bas\u00e9 sur Haskell.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/img.linuxfr.org\/img\/687474703a2f2f636c6173682d6c616e672e6769746875622e696f2f696d672f69636f6e5f6461726b2e737667\/icon_dark.svg\" alt=\"Logo de C\u03bbaSH\" title=\"Source : http:\/\/clash-lang.github.io\/img\/icon_dark.svg\"\/><\/figure>\n\n\n\n<p>Mais qu&rsquo;est-ce que C\u03bbaSH\u00a0? On pourrait commencer par le d\u00e9finir en d\u00e9crivant ce qu&rsquo;il n&rsquo;est pas :<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>C\u03bbaSH (of c\u03bbaN&nbsp;?) n&rsquo;est pas un jeu vid\u00e9o se jouant en caressant un t\u00e9l\u00e9phone.<\/li><li>C\u03bbaSH n&rsquo;est pas un groupe de musique se demandant s&rsquo;<a href=\"https:\/\/www.youtube.com\/watch?v=BN1WwnEDWAM\">il doit rester ou partir<\/a>.<\/li><li>C\u03bbaSH n&rsquo;est pas un HLS (<a href=\"https:\/\/en.wikipedia.org\/wiki\/High-level_synthesis\">High Level Synthesis<\/a>). La fonction d&rsquo;un logiciel HLS consiste \u00e0 convertir un algorithme \u00e9crit dans un langage de programmation classique (tr\u00e8s souvent du C) dans une architecture num\u00e9rique en Verilog\/<a href=\"https:\/\/fr.wikipedia.org\/wiki\/VHDL\">VHDL<\/a>.<\/li><\/ul>\n\n\n\n<p>Non.<\/p>\n\n\n\n<p>C\u03bbaSH est un langage de description mat\u00e9riel bas\u00e9 sur le langage fonctionnel <a href=\"https:\/\/fr.wikipedia.org\/wiki\/Haskell\">Haskell<\/a>.<\/p>\n\n\n\n<p>Le langage <a href=\"https:\/\/www.haskell.org\/\">Haskell<\/a> est n\u00e9 dans les ann\u00e9es 90, fond\u00e9 par une soci\u00e9t\u00e9 secr\u00e8te de math\u00e9maticiens qui voulait reprendre le contr\u00f4le des ordinateurs. En effet, vex\u00e9s de voir tous ces geeks ma\u00eetriser cette machine mieux qu&rsquo;eux ils d\u00e9cid\u00e8rent de se r\u00e9unir de mani\u00e8re anonyme dans une cave (o\u00f9 il fallait entrer avec un mot de passe \u00e0 base de d\u00e9veloppement limit\u00e9s sur un Alg\u00e8bre commutatif isomorphe) pour fonder un nouveau langage compris par eux seuls. Le Haskell \u00e9tait n\u00e9&nbsp;! Enfin je crois&nbsp;\ud83d\ude09<\/p>\n\n\n\n<p>Haskell est un langage fonctionnel, qui nous impose une autre fa\u00e7ons de penser un programme informatique. Du dire <a href=\"https:\/\/www.youtube.com\/watch?v=4BqG4pH-Ekk\">des auteurs de C\u03bbaSH<\/a>, le paradigme fonctionnel est plus \u00e0 m\u00eame de d\u00e9crire du mat\u00e9riel que le paradigme imp\u00e9ratif.<\/p>\n\n\n\n<p>Un composant d\u00e9crit en C\u03bbaSH est directement convertible en Verilog ou en VHDL (les deux sont g\u00e9r\u00e9s dans la version 1.0). Ce qui fait qu&rsquo;un composant d\u00e9crit en C\u03bbaSH est synth\u00e9tisable avec n&rsquo;importe quel logiciel de <a href=\"https:\/\/en.wikipedia.org\/wiki\/Logic_synthesis\">synth\u00e8se FPGA<\/a>.<\/p>\n\n\n\n<p>Dans le cas de ce type de langage on parle de g\u00e9n\u00e9rateur de code, un peu comme Chisel (bas\u00e9 sur Scala), Migen\/Litex (bas\u00e9 sur Python) ou SpinalHDL (bas\u00e9 \u00e9galement sur Scala). Ces langages sont en fait des librairies ou des modules du langage auquel ils sont accol\u00e9s.<br>Cette modularit\u00e9 permet de profiter d&rsquo;un langage souvent bien \u00e9tabli avec \u00e9norm\u00e9ment de fonctions optimis\u00e9es (Scala, Python, Haskell\u2026).<\/p>\n\n\n\n<p>Le paradigme fonctionnel n&rsquo;est pas du tout quelque chose qui coule de source pour un simple \u00e9lectronicien comme votre serviteur. Cette d\u00e9p\u00eache a donc \u00e9t\u00e9 un peu diff\u00e9r\u00e9e le temps d&rsquo;avaler les <a href=\"http:\/\/www.lyah.haskell.fr\/\">100 premi\u00e8res pages de tutoriel<\/a> permettant de faire un simple \u00ab\u00a0hello world\u00a0\u00bb en Haskell. Puis d&rsquo;avaler le <a href=\"http:\/\/hackage.haskell.org\/package\/clash-prelude-1.0.0\/docs\/Clash-Tutorial.html\">tutoriel C\u03bbaSH<\/a> pour enfin faire clignoter cette fameuse LED sur un kit FPGA low cost de base.<\/p>\n\n\n\n<p>Nous allons donc tenter un petit C\u03bbaSHtest permettant de faire clignoter une led.<\/p>\n\n\n\n<p>Le type de base manipul\u00e9 en C\u03bbaSH est le <a href=\"http:\/\/hackage.haskell.org\/package\/clash-prelude-1.0.0\/docs\/Clash-Explicit-Signal.html#t:Signal\">Signal<\/a>. C\u03bbaSH ne permettant que des descriptions <a href=\"https:\/\/fr.wikipedia.org\/wiki\/Logique_s%C3%A9quentielle\">synchrones<\/a>, un Signal repr\u00e9sente une liste infinie de valeurs synchronis\u00e9e sur une horloge et un reset pour la valeur initiale. L&rsquo;horloge et le reset du signal sont d\u00e9crit par le Domaine <code>dom<\/code> du signal. La forme d&rsquo;un <code>Signal<\/code> est donc la suivante :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code> Signal (dom :: Domain) a\n<\/code><\/pre>\n\n\n\n<p>En logique synchrone, le composant de base est le registre, nomm\u00e9 <code>register<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>register\n     ( HiddenClockResetEnable dom dom\n     , NFDataX a )\n  =&gt; a\n  -&gt; Signal dom a\n  -&gt; Signal dom a\n<\/code><\/pre>\n\n\n\n<p>Son fonctionnement est assez basique : La valeur initiale (de reset) est donn\u00e9e en premier argument, le second argument est le signal d&rsquo;entr\u00e9e qui est recopi\u00e9 sur le signal de sortie (valeur de retour de la fonction). On peut utiliser C\u03bbaSH en ligne de commande avec la commande clash.clashi.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ clash.clashi\nClashi, version 1.0.1 (using clash-lib, version 1.0.1):\nhttp:\/\/www.clash-lang.org\/  :? for help\nClash.Prelude&gt; \n<\/code><\/pre>\n\n\n\n<p>Mais on pr\u00e9f\u00e9rera rapidement enregistrer notre module dans un fichiers source au format *.hs.<\/p>\n\n\n\n<p>Pour faire clignoter une LED dans un FPGA, la premi\u00e8re chose \u00e0 mettre en place est un compteur :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Clash.Prelude&gt; counter = register 0 counter + 1\n<\/code><\/pre>\n\n\n\n<p>Cette fonction counter que nous venons de cr\u00e9er retourne un registre initialis\u00e9 \u00e0 0 et qui ajoute 1&nbsp;\u00e0 sa sortie \u00e0 chaque coup d&rsquo;horloge. La d\u00e9finition est r\u00e9cursive, c&rsquo;est \u00e0 dire qu&rsquo;elle ajoute 1 \u00e0 elle m\u00eame. Et comme on commence \u00e0 0 et qu&rsquo;on ajoute 1, la valeur initiale sera 1.<br>Cette fonction \u00e9tant infinie, si nous voulons connaitre des valeurs il faut \u00e9chantillonner :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Clash.Prelude&gt; sampleN @System 10 counter\n&#91;1,1,2,3,4,5,6,7,8,9]\n<\/code><\/pre>\n\n\n\n<p>On constate que la premi\u00e8re valeur est en double car c&rsquo;est la valeur initiale, avant le premier coup d&rsquo;horloge. @System d\u00e9signe le domaine d&rsquo;horloge\/reset\/enable utilis\u00e9. @System est le domaine g\u00e9n\u00e9ral, nous pourrions appliquer un domaine (dom) sp\u00e9cifique \u00e0 une architecture comme <a href=\"http:\/\/hackage.haskell.org\/package\/clash-prelude-1.0.0\/docs\/src\/Clash.Signal.Internal.html#XilinxSystem\">@XilinxSystem<\/a> ou <a href=\"http:\/\/hackage.haskell.org\/package\/clash-prelude-1.0.0\/docs\/src\/Clash.Signal.Internal.html#IntelSystem\">@IntelSystem<\/a>.<\/p>\n\n\n\n<p>Le probl\u00e8me avec ce compteur c&rsquo;est qu&rsquo;il incr\u00e9mente \u00e0 l&rsquo;infini, nous on voudrait un compteur avec une limite et qui se remet \u00e0 0 \u00e0 une certaine valeur comme \u00e7a :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Clash.Prelude&gt; counter value = if(value &lt; 100) then value + 1 else 0\nClash.Prelude&gt; counter 10\n11\nClash.Prelude&gt; counter 0\n1\nClash.Prelude&gt; counter 101\n0\n<\/code><\/pre>\n\n\n\n<p>[notes]<br>Je ne sais pas si je vais r\u00e9ussir \u00e0 comprendre l&rsquo;exemple de led qui clignote donn\u00e9 <a href=\"http:\/\/christiaanb.github.io\/posts\/clash-fpga-starter\/\">sur le blog de l&rsquo;auteur de clash<\/a> en fait.<\/p>\n\n\n\n<p>Je suis parti un peu la fleur au fusil pour faire cette d\u00e9p\u00eache, mais je me rend compte que l&rsquo;apprentissage de Clash (et surtout Haskell) est un loooong chemin.<\/p>\n\n\n\n<p>Bref, je crois que je ne vais pas r\u00e9ussir \u00e0 finir cette d\u00e9p\u00eache. Peut-\u00eatre un jour aurais-je suffisamment de bouteille en Haskell pour comprendre Clash, mais l\u00e0 \u2026 <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/linuxfr.org\/redirect\/104765\">Site officiel de C\u03bbaSH<\/a><\/li><li><a href=\"https:\/\/linuxfr.org\/redirect\/104766\">Annonce de la version 1.0<\/a><\/li><li> <a href=\"https:\/\/linuxfr.org\/redirect\/105057\">Tutoriel pour d\u00e9buter en C\u03bbaSH<\/a><\/li><li> <a href=\"https:\/\/linuxfr.org\/redirect\/105246\">Pr\u00e9sentation de C\u03bbaSH \u00e0 l&rsquo;ORConf2019 \u00e0 Bordeaux<\/a><\/li><\/ul>\n","protected":false},"excerpt":{"rendered":"<p>La version 1.0 de C\u03bbaSH est sortie en septembre 2019. Profitons de cette sortie pour pr\u00e9senter ce langage de description mat\u00e9riel bas\u00e9 sur Haskell. Mais qu&rsquo;est-ce que C\u03bbaSH\u00a0? On pourrait commencer par le d\u00e9finir en d\u00e9crivant ce qu&rsquo;il n&rsquo;est pas : C\u03bbaSH (of c\u03bbaN&nbsp;?) n&rsquo;est pas un jeu vid\u00e9o se jouant en caressant un t\u00e9l\u00e9phone. &hellip; <a href=\"http:\/\/www.fabienm.eu\/flf\/clash-un-hdl-base-sur-haskell\/\" class=\"more-link\">Continuer la lecture de <span class=\"screen-reader-text\">ClaSH un HDL bas\u00e9 sur Haskell<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","footnotes":""},"categories":[1],"tags":[34,33,120],"class_list":["post-1638","post","type-post","status-publish","format-standard","hentry","category-non-classe","tag-clash","tag-haskell","tag-hdl"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false,"post-thumbnail":false},"uagb_author_info":{"display_name":"Fabien Marteau","author_link":"http:\/\/www.fabienm.eu\/flf\/author\/martoni\/"},"uagb_comment_info":0,"uagb_excerpt":"La version 1.0 de C\u03bbaSH est sortie en septembre 2019. Profitons de cette sortie pour pr\u00e9senter ce langage de description mat\u00e9riel bas\u00e9 sur Haskell. Mais qu&rsquo;est-ce que C\u03bbaSH\u00a0? On pourrait commencer par le d\u00e9finir en d\u00e9crivant ce qu&rsquo;il n&rsquo;est pas : C\u03bbaSH (of c\u03bbaN&nbsp;?) n&rsquo;est pas un jeu vid\u00e9o se jouant en caressant un t\u00e9l\u00e9phone.\u2026","_links":{"self":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/1638","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/comments?post=1638"}],"version-history":[{"count":4,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/1638\/revisions"}],"predecessor-version":[{"id":2226,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/1638\/revisions\/2226"}],"wp:attachment":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/media?parent=1638"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/categories?post=1638"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/tags?post=1638"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}