{"id":222,"date":"2015-01-15T19:34:27","date_gmt":"2015-01-15T18:34:27","guid":{"rendered":"http:\/\/www.fabienm.eu\/flf\/?p=222"},"modified":"2015-06-17T08:46:52","modified_gmt":"2015-06-17T07:46:52","slug":"pwm-en-chisel","status":"publish","type":"post","link":"http:\/\/www.fabienm.eu\/flf\/pwm-en-chisel\/","title":{"rendered":"Un modulateur PWM en Chisel"},"content":{"rendered":"<p>Pour changer des LED qui clignotent, voici un modulateur PWM \u00e9crit en <a title=\"Compiler les exemples Chisel sur Jessie\" href=\"http:\/\/www.fabienm.eu\/flf\/compiler-les-exemples-chisel-sur-jessie\/\">Chisel<\/a> avec son testbench.<\/p>\n<p>Le code ci-dessous (<strong>PWM.scala<\/strong>) est du Scala standard utilisant la librairie Chisel.<\/p>\n<pre>import Chisel._\r\n\/* Classe contenant le comportement du module *\/\r\nclass PWM extends Module {\r\n  \/* Bundle io obligatoire *\/\r\n  val io = new Bundle {\r\n    val duty  = UInt(INPUT,  8)\r\n    val out  = Bool(OUTPUT)\r\n  }\r\n\r\n  \/* Registre 8 bits pour le compteur *\/\r\n  val counter = Reg(UInt(width=8))\r\n  counter\u00a0:= counter + UInt(1)\r\n\r\n  \/* Registre de sortie avec le comparateur *\/\r\n  io.out\u00a0:= Reg(next=(counter&lt;io.duty))  \r\n}\r\n\r\n\/* Point d'entr\u00e9e du programme *\/\r\nobject Example {\r\n  def main(args: Array[String]): Unit = {\r\n    chiselMain(args, () =&gt; Module(new PWM()))\r\n  }\r\n}\r\n<\/pre>\n<p>Le code du modulateur ci-dessus est d\u00e9coup\u00e9 en deux parties.<\/p>\n<p>La premi\u00e8re d\u00e9crit le comportement du module. Elle comprend le bundle (similaire au record en VHDL) appel\u00e9 io, qui doit \u00eatre pr\u00e9sent dans chacun des modules pour d\u00e9crire les entr\u00e9es et les sorties, un compteur 8 bits, et le registre de sortie qui est aliment\u00e9 par le comparateur de rapport cyclique.<\/p>\n<p>La deuxi\u00e8me partie est n\u00e9cessaire pour le module qui se trouve au sommet de la hi\u00e9rarchie afin de d\u00e9crire le point d&rsquo;entr\u00e9e qui servira \u00e0 la g\u00e9n\u00e9ration du code.<\/p>\n<p>Il est aussi n\u00e9cessaire de fournir le fichier <strong>build.sbt<\/strong> qui sert \u00e0 indiquer a SBT (l&rsquo;outil de build Scala) qu&rsquo;il doit \u00e9galement aller chercher Chisel dans ses paquets avant de lancer la compilation. SBT va d&rsquo;office compiler tout les fichiers Scala (avec l&rsquo;extension .scala) qu&rsquo;il trouve dans le r\u00e9pertoire courant.<\/p>\n<pre>libraryDependencies += \"edu.berkeley.cs\"\u00a0%% \"chisel\"\u00a0% \"latest.release\"\r\n\r\nscalacOptions ++= Seq(\"-deprecation\", \"-feature\", \"-unchecked\", \"-language:reflectiveCalls\")\r\n<\/pre>\n<p>Il faut ensuite s&rsquo;assurer que Chisel g\u00e9n\u00e8re du Verilog en lan\u00e7ant la commande<\/p>\n<pre>sbt 'run --v'\r\n<\/pre>\n<p>Il manque un banc de test pour exercer le design. Chisel propose de compiler \u00e9galement pour nous un mod\u00e8le C++ du design qu&rsquo;on peut obtenir<br \/>\nen utilisant la commande suivante :<\/p>\n<pre>sbt 'run --test --genHarness --vcd'\r\n<\/pre>\n<p>On va maintenant cr\u00e9er un testbench C++ qui permettra de g\u00e9n\u00e9rer les VCD. Appelons ce fichier main_pwm.cpp.<\/p>\n<pre>#include \"PWM.h\"\r\n#include &lt;iostream&gt;\r\n\r\nint main (int argc, char* argv[]) { \r\n  \/\/ Cr\u00e9er l'objet PWM\r\n  PWM_t* c = new PWM_t();\r\n\r\n  \/\/ Recup\u00e9rer le nombre de cycles \u00e0 ex\u00e9cuter\r\n  int lim = (argc &gt; 1) ? atoi(argv[1]) : -1;\r\n  if(lim == -1) {\r\n     cout &lt;&lt; \"wrong argument, should be :\" &lt;&lt; endl;\r\n     cout &lt;&lt; \"a.out &lt;n&gt;\" &lt;&lt; endl;\r\n     return 1;\r\n  }\r\n  \/\/ Initialiser le mod\u00e8le\r\n  c-&gt;init();\r\n\r\n  \/\/ Ecrire l'ent\u00eate du VCD\r\n  c-&gt;dump_init(stdout);\r\n\r\n  \/\/ Ecrire le rapport cyclique\r\n  c-&gt;PWM__io_duty = LIT&lt;8&gt;(100);\r\n  for (int t = 0; lim &lt; 0 || t &lt; lim; t++) {\r\n    \/\/ Active le reset sur le premier cycle\r\n    dat_t&lt;1&gt; reset = LIT&lt;1&gt;(t == 0);\r\n\r\n    \/\/ Dump du VCD\r\n    c-&gt;dump(stdout,t);\r\n\r\n    \/\/ Avancer d'une p\u00e9riode d'horloge\r\n    c-&gt;clock(reset);\r\n    } \r\n}\r\n<\/pre>\n<p>Il reste juste \u00e0 compiler le tout avec g++.<\/p>\n<pre>g++ PWM.cpp main_pwm.cpp\r\n<\/pre>\n<p>\u00c0 ex\u00e9cuter<\/p>\n<pre>.\/a.out 10000 &gt; out.vcd\r\n<\/pre>\n<p>Et admirer le r\u00e9sultat dans gtkwave<\/p>\n<pre>gtkwave out.vcd\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Pour changer des LED qui clignotent, voici un modulateur PWM \u00e9crit en Chisel avec son testbench. Le code ci-dessous (PWM.scala) est du Scala standard utilisant la librairie Chisel. import Chisel._ \/* Classe contenant le comportement du module *\/ class PWM extends Module { \/* Bundle io obligatoire *\/ val io = new Bundle { val &hellip; <a href=\"http:\/\/www.fabienm.eu\/flf\/pwm-en-chisel\/\" class=\"more-link\">Continuer la lecture de <span class=\"screen-reader-text\">Un modulateur PWM en Chisel<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","footnotes":""},"categories":[4,3],"tags":[57,32,8],"class_list":["post-222","post","type-post","status-publish","format-standard","hentry","category-chisel-langages","category-langages","tag-chisel","tag-pwm","tag-scala"],"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":"S\u00e9bastien","author_link":"http:\/\/www.fabienm.eu\/flf\/author\/svancau\/"},"uagb_comment_info":0,"uagb_excerpt":"Pour changer des LED qui clignotent, voici un modulateur PWM \u00e9crit en Chisel avec son testbench. Le code ci-dessous (PWM.scala) est du Scala standard utilisant la librairie Chisel. import Chisel._ \/* Classe contenant le comportement du module *\/ class PWM extends Module { \/* Bundle io obligatoire *\/ val io = new Bundle { val\u2026","_links":{"self":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/222","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\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/comments?post=222"}],"version-history":[{"count":19,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/222\/revisions"}],"predecessor-version":[{"id":355,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/posts\/222\/revisions\/355"}],"wp:attachment":[{"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/media?parent=222"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/categories?post=222"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.fabienm.eu\/flf\/wp-json\/wp\/v2\/tags?post=222"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}