<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta http-equiv=Content-Type content="text/html; charset=utf-8"><meta name=Generator content="Microsoft Word 15 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.msonormal0, li.msonormal0, div.msonormal0
        {mso-style-name:msonormal;
        mso-margin-top-alt:auto;
        margin-right:0cm;
        mso-margin-bottom-alt:auto;
        margin-left:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.E-MailFormatvorlage18
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 70.85pt 2.0cm 70.85pt;}
div.WordSection1
        {page:WordSection1;}
--></style></head><body lang=DE-CH link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>J.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>There is no “AT” keyword in Oberon so far.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>So, it’s up to us to define the semantics, under the condition we would implement this.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>But as Chris pointed out, he works without it.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>What I normally do is: I have a several low level constant definitions (the same as Chris) and name them differently.<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>Then in the driver layer, I import them with alias<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>IMPORT </span>MCU := LPC1769<span lang=EN-US style='mso-fareast-language:EN-US'><o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>   and in other driver<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>IMPORT MCU := LCP1347<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>br<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'>Jörg<o:p></o:p></span></p><p class=MsoNormal><span lang=EN-US style='mso-fareast-language:EN-US'><o:p> </o:p></span></p><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm'><p class=MsoNormal><b><span style='font-size:12.0pt;color:black'>Von: </span></b><span style='font-size:12.0pt;color:black'>Oberon <oberon-bounces@lists.inf.ethz.ch> im Auftrag von Jan de Kruyf <jan.de.kruyf@gmail.com><br><b>Antworten an: </b>ETH Oberon and related systems <oberon@lists.inf.ethz.ch><br><b>Datum: </b>Mittwoch, 8. August 2018 um 16:50<br><b>An: </b>ETH Oberon and related systems <oberon@lists.inf.ethz.ch><br><b>Betreff: </b>Re: [Oberon] Oberon FPGA hardware point of view<o:p></o:p></span></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>Joerg,<o:p></o:p></p><div><p class=MsoNormal>Yes<o:p></o:p></p></div><div><p class=MsoNormal>But now it is not immediately obvious that you do an address overlay. Because I think that the AT keyword is wrong for what it does.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>Cheers<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div><div><p class=MsoNormal>j.<o:p></o:p></p></div><div><p class=MsoNormal><o:p> </o:p></p></div></div><div><p class=MsoNormal><o:p> </o:p></p><div><p class=MsoNormal>On Wed, Aug 8, 2018 at 3:58 PM, Jörg <<a href="mailto:joerg.straube@iaeth.ch" target="_blank">joerg.straube@iaeth.ch</a>> wrote:<o:p></o:p></p><blockquote style='border:none;border-left:solid #CCCCCC 1.0pt;padding:0cm 0cm 0cm 6.0pt;margin-left:4.8pt;margin-right:0cm'><p class=MsoNormal>Chris<br><br>With your file organization and Walter's syntax idea you could write something like this:<br><br>IMPORT MCU, SYSTEM;<br><br>PROCEDURE PutCh*(ch: CHAR);<br>    CONST txEmpty = 5;<br>    VAR<br>        lineStatus: SET AT MCU.ULSR;<br>        tx: CHAR AT MCU.UTHR;<br>    BEGIN<br>        REPEAT UNTIL txEmpty IN lineStatus;<br>        tx := ch<br>    END PutCh;<br><br>br<br>Jörg<br><br>Am 08.08.18, 15:33 schrieb "Oberon im Auftrag von Chris Burrows" <<a href="mailto:oberon-bounces@lists.inf.ethz.ch">oberon-bounces@lists.inf.ethz.ch</a> im Auftrag von <a href="mailto:chris@cfbsoftware.com">chris@cfbsoftware.com</a>>:<o:p></o:p></p><div><div><p class=MsoNormal><br>    > -----Original Message-----<br>    > From: Oberon [mailto:<a href="mailto:oberon-bounces@lists.inf.ethz.ch">oberon-bounces@lists.inf.ethz.ch</a>] On Behalf Of<br>    > Walter Gallegos<br>    > Sent: Wednesday, 8 August 2018 4:04 AM<br>    > To: <a href="mailto:oberon@lists.inf.ethz.ch">oberon@lists.inf.ethz.ch</a>; Walter Gallegos<br>    > Subject: [Oberon] Oberon FPGA hardware point of view<br>    > <br>    > A FPGA hardware designer point of view;<br>    > <br>    > In some projects (all my projects) the CPU executes software as<br>    > coprocessing; in parallel but outside the main data flow of hardware<br>    > DSP; hardware is faster and more efficient than software DSP.<br>    > <br>    > On this scenery, the memory map could change from one project to<br>    > another project. So, hardware/software designers need certain degree<br>    > of freedom to access memory mapped areas.<br>    > <br>    > I propose two modifications :<br>    > <br>    > 1/ Add memory mapped variables<br>    > <br>    > VAR [label] : [type] AT [address]<br>    > VAR [label] : ARRAY [size] OF [type] AT [address]<br>    > <br><br>    On the surface this sounds OK but in reality the sheer number of addresses<br>    involved led us to use a different approach.<br><br>    Our technique follows Paul Reed's recent advice here i.e. separate all of<br>    the hardware specific details from everything else into the lowest level<br>    modules. This has worked out really well for us. It avoids the software<br>    maintenance nightmare of having to track down / modify hard-coded addresses<br>    and other hardware-specific details scattered throughout a system.<br><br>    With the Astrobe for ARM Cortex-M3, M4 and M7 Oberon systems we were faced<br>    with the prospect of having to maintain hundreds of memory-mapped addresses<br>    for similar, but different, memory-mapped peripherals for more than 60<br>    different types of microcontroller from two different manufacturers (NXP and<br>    STMicroelectronics). You might expect to have a couple of different sets of<br>    common definitions for each manufacturer but we ended up needing 11<br>    altogether. Not as bad as 60 perhaps but I'm convinced the designers could<br>    have done a lot better at eliminating inconsistencies. <br><br>    The scheme we have used is this: There is a single module, called MCU.mod,<br>    for each family of microcontrollers e.g. LPC176x (NXP Cortex-M3), STM32F7<br>    (STM Cortex-M7) etc. There are eleven of these, all with the same name but<br>    stored in a folder named after the microcontroller family. <br><br>    The *key* feature is: the *only* items contained in the MCU module are CONST<br>    declarations. <br><br>    Each named constant represents a peripheral register address. Much of the<br>    time just the base address of each peripheral is different from one MCU to<br>    another so we take advantage of the fact that CONSTs can contain arithmetic<br>    expressions. We can then specify a single base address for each device and<br>    the other related registers are common offsets from that base. <br><br>    e.g. <br><br>    for UART0:<br><br>      U0Base* = 04000C000H;<br>      U0RBR* = U0Base+000H;<br>      U0THR* = U0Base+000H;<br>      U0DLL* = U0Base+000H;<br>      U0DLM* = U0Base+004H;<br>      ...<br><br>    For UART2:<br><br>      U2Base* = 040098000H;<br>      U2RBR* = U2Base+000H;<br>      U2THR* = U2Base+000H;<br>      U2DLL* = U2Base+000H;<br>      U2DLM* = U2Base+004H;<br>      ...<br>      ...<br><br>    RBR, THR, DLL, DLM etc. are the names used for each UART function exactly as<br>    used by NXP in their programming reference manual. In case you are<br>    wondering, yes - RBR, THR and DLL all map to the same absolute address.<br><br>    Now, just to be different, the corresponding base address for the LPC1347<br>    family is U0Base* = 040008000H. If that wasn't bad enough, sometimes the<br>    relative offset addresses are different as well! <br><br>    There are more than 500 of these definitions in the LPC176x version of<br>    MCU.mod and there are still a number of peripherals that we have not yet<br>    included.<br><br>    Now that we have isolated what is *different* in MCU.mod, we can then<br>    implement a common hardware-interface module (e.g. Serial.mod) which uses<br>    these constant definitions, with their generic names, when implementing the<br>    (still hardware-specific) functions:<br><br>      IMPORT MCU, SYSTEM;<br><br>      PROCEDURE PutCh*(ch: CHAR);<br>      BEGIN<br>        REPEAT UNTIL SYSTEM.BIT(ULSR, 5);<br>        SYSTEM.PUT(UTHR, ch)<br>      END PutCh;<br><br><br>    The next level up in the module hierarchy is the familiar common<br>    *hardware-independent* 'Out' module. This works with all the different<br>    microcontrollers providing functions Out.Char, Out.String. It includes the<br>    statement:<br><br>      IMPORT Serial;<br><br>    And the functions just call PutCh in different ways.<br><br>    The mechanism that we use to specify which particular MCU.mod and Serial.mod<br>    files are actually used when we compile an application which targets a<br>    particular family of microcontrollers is to associate the application with a<br>    configuration file containing mcu-specific 'search paths'. An extract from<br>    the map file for an application called 'Info' shows the consequences:<br><br>    LPC1769:<br>    MCU             D:\AstrobeM3-v6.4\Lib\LPC1769\MCU.arm<br>    Out             D:\AstrobeM3-v6.4\Lib\General\Out.arm<br>    Serial          D:\AstrobeM3-v6.4\Lib\LPC1769\Serial.arm<br>    Info            D:\AstrobeM3-v6.4\Examples\General\Info.arm<br><br>    LPC1347:<br>    MCU             D:\AstrobeM3-v6.4\Lib\LPC1347\MCU.arm<br>    Out             D:\AstrobeM3-v6.4\Lib\General\Out.arm<br>    Serial          D:\AstrobeM3-v6.4\Lib\LPC1347\Serial.arm<br>    Info            D:\AstrobeM3\Release\Examples\General\Info.arm<br><br>    Most of the time the only functions we need to use with these CONST<br>    addresses are SYSTEM.PUT to write a value, SYSTEM.GET to read a value and<br>    SYSTEM.BIT to test the value of a single bit. <br><br>    If multi-byte data needs to be efficiently read or written to an Oberon<br>    ARRAY or RECORD, SYSTEM.ADR, SYSTEM.COPY and SYSTEM.VAL (or ARRAY OF BYTE<br>    parameters) are the Oberon features that can be used. Once the conversion<br>    has been done from a byte-stream to an application-specific Oberon data<br>    structure at the hardware interface the Oberon data structure can be used<br>    naturally in the application from then on. It only needs to be converted<br>    back to a byte-stream when the hardware needs to be updated. <br><br>    Regards,<br>    Chris Burrows<br>    CFB Software<br>    <a href="http://www.astrobe.com" target="_blank">http://www.astrobe.com</a><br><br><br>    --<br>    <a href="mailto:Oberon@lists.inf.ethz.ch">Oberon@lists.inf.ethz.ch</a> mailing list for ETH Oberon and related systems<br>    <a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon" target="_blank">https://lists.inf.ethz.ch/mailman/listinfo/oberon</a><br><br><br><br>--<br><a href="mailto:Oberon@lists.inf.ethz.ch">Oberon@lists.inf.ethz.ch</a> mailing list for ETH Oberon and related systems<br><a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon" target="_blank">https://lists.inf.ethz.ch/mailman/listinfo/oberon</a><o:p></o:p></p></div></div></blockquote></div><p class=MsoNormal><o:p> </o:p></p></div><p class=MsoNormal>-- Oberon@lists.inf.ethz.ch mailing list for ETH Oberon and related systems https://lists.inf.ethz.ch/mailman/listinfo/oberon <o:p></o:p></p></div></body></html>