MDS Code Compatibility

Source Code Compatibility

If you don't want to learn a new assembler

There is a solution for that, since version 1.2 MDS supports compatibility mode with the Xilinx assembler for PicoBlaze, you can enable this mode in the project configuration dialog. With compatibility mode enabled you can simply use the syntax you are already used to; and possibly try the macro-assembler later, if you wish.

However, there is a couple of things you should probably know about before you start using this feature:

  • MDS is not equipped with an assembler that can accept the Xilinx syntax. the compatibility mode uses the Assembler Translator to translate your code from Xilinx syntax to MDS syntax, there is generally no problem with that but you will get much less useful error messages, compilation warnings, etc.
  • The MDS syntax offers considerably wider options for writing code, this cannot be explained in one sentence but there are two main ideas of innovation behind MDS:
    1. Very high simulation speed (almost real-time).
    2. A reasonably advanced assembler well suitable for developing moderately complex applications.
    When you choose not to use the MDS assembler, you are putting away one the main advantages of this IDE.
  • This manual does not take into account that the user chooses to use the Xilinx syntax, this option is meant primarily for users who just what a "quick start".

 

If you want to start using macro-assembler but you want to keep your options opened

We provide tool we call Assembler Translator, using this utility you can easily translate any source code written in Xilinx or Mediatronix syntax to MDS assembler syntax which is slightly different and enhanced to enable use of expressions, macros, conditions, and loops. The main difference between our assembler and the other two assemblers is that MDS assembler required explicit addressing mode specification, and is a good reason for that, it enables advanced assembler features for faster development, higher quality, and cheaper maintainability, that's the innovative idea behind its design.

This "code import" function, the Assembler Translator, is subjected to automated testing to ensure its reliability, we try it on hundreds of test cases before we ship this function with our products. And thus we are confident that this function actually really works as expected and can be relied on.

 Learn more about MDS assembler

Original code with Xilinx syntax
          warm_start: ADD sF, 01                          ;authentication check timer
                      JUMP C, authentication_check        ;Check made approximately every 8 seconds.
                      ;
 normal_LED_sequence: LOAD s2, 03                         ;simple delay loop (delay will be increased by ISR processing)
       delay_s2_loop: LOAD s1, FF
       delay_s1_loop: LOAD s0, FF
       delay_s0_loop: SUB s0, 01
                      JUMP NC, delay_s0_loop
                      SUB s1, 01
                      JUMP NC, delay_s1_loop
                      SUB s2, 01
                      JUMP NC, delay_s2_loop
                      ;
                      ;Pattern generation
                      ;
                      FETCH s0, LED0_sequence             ;read sequence for LED0
                      COMPARE s0, 00
                      JUMP Z, test_LED0_start
                      SUB s0, 20                          ;Count longer to ensure end stops then reset count if maximum
                      JUMP Z, update_LED0
                      ADD s0, 20
            inc_LED0: ADD s0, 01                          ;increment counter
                      JUMP update_LED0
     test_LED0_start: FETCH s1, LED1_sequence             ;start LED0 if LED1 = 4
                      COMPARE s1, 04
                      JUMP Z, inc_LED0
         update_LED0: STORE s0, LED0_sequence
                      CALL LED_to_duty
                      STORE s1, PWM_channel0

This code fragment is taken from s3kit_example2.psm by Ken Chapman - Xilinx Ltd, Version v1.00 - 9th November 2006.

     
Automatically translated code to MDS syntax
warm_start:             ADD             sf, #0x01               ;authentication check timer
                        JUMP            c, authentication_check ;Check made approximately every 8 seconds.
;
normal_led_sequence:    LOAD            s2, #0x03               ;simple delay loop (delay will be increased by ISR processing)
delay_s2_loop:          LOAD            s1, #0xff
delay_s1_loop:          LOAD            s0, #0xff
delay_s0_loop:          SUB             s0, #0x01
                        JUMP            nc, delay_s0_loop
                        SUB             s1, #0x01
                        JUMP            nc, delay_s1_loop
                        SUB             s2, #0x01
                        JUMP            nc, delay_s2_loop
;
;Pattern generation
;
                        FETCH           s0, led0_sequence       ;read sequence for LED0
                        COMPARE         s0, #0x00
                        JUMP            z, test_led0_start
                        SUB             s0, #0x20               ;Count longer to ensure end stops then reset count if maximum
                        JUMP            z, update_led0
                        ADD             s0, #0x20
inc_led0:               ADD             s0, #0x01               ;increment counter
                        JUMP            update_led0
test_led0_start:        FETCH           s1, led1_sequence       ;start LED0 if LED1 = 4
                        COMPARE         s1, #0x04
                        JUMP            z, inc_led0
update_led0:            STORE           s0, led0_sequence
                        CALL            led_to_duty
                        STORE           s1, pwm_channel0

 


Machine Code Compatibility

Do you need fill your VHDL templates with memory initializations for your PicoBlaze applications, or generate HEX files for your JTAG loader... MDS, of course, provides these functions, and supports even some data file formats which you might be used to from other processor architectures like Intel Hex, or raw binary files.

MEM file

@0000 0000D002 0000D000 0000D400 0000D500 0000D600 0000D700 0000210C 00002914 000031FF 000039FF 00006120 00006920 00007120 00007940 00000101 00000900
@0040 00001101 00001902 00004120 00004920 00005120 00005920 0000A20E 0000A20F 0000A20A 0000A208 0000A20C 0000A206 0000A207 0000A202 0000A200 0000A204
@0080 0000D825 0000DC25 0000DD25 0000DE25 0000DF25 00009000 00009400 00009500 00009600 00009700 00000000 00000000 00000000 00000000 00000000 00000000
... ... ...
... ... ...
... ... ...

VHDL

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

library unisim;
use unisim.vcomponents.all;

entity 0000_Instruction_opcodes.asm is
    Port (      address : in std_logic_vector(7 downto 0);
            instruction : out std_logic_vector(15 downto 0);
                    clk : in std_logic);
    end 0000_Instruction_opcodes.asm;

architecture low_level_definition of 0000_Instruction_opcodes.asm is

attribute INIT_00 : string;
attribute INIT_01 : string;
attribute INIT_02 : string;
attribute INIT_03 : string;
attribute INIT_04 : string;
attribute INIT_05 : string;
attribute INIT_06 : string;
attribute INIT_07 : string;
attribute INIT_08 : string;
attribute INIT_09 : string;
attribute INIT_0A : string;
attribute INIT_0B : string;
attribute INIT_0C : string;
attribute INIT_0D : string;
attribute INIT_0E : string;
attribute INIT_0F : string;

attribute INIT_00 of ram_256_x_16 : label is  "09000101794071206920612039FF31FF2914210CD700D600D500D400D000D002";
attribute INIT_01 of ram_256_x_16 : label is  "A204A200A202A207A206A20CA208A20AA20FA20E592051204920412019021101";
attribute INIT_02 of ram_256_x_16 : label is  "00000000000000000000000097009600950094009000DF25DE25DD25DC25D825";
attribute INIT_03 of ram_256_x_16 : label is  "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_04 of ram_256_x_16 : label is  "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_05 of ram_256_x_16 : label is  "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_06 of ram_256_x_16 : label is  "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_07 of ram_256_x_16 : label is  "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_08 of ram_256_x_16 : label is  "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_09 of ram_256_x_16 : label is  "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0A of ram_256_x_16 : label is  "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0B of ram_256_x_16 : label is  "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0C of ram_256_x_16 : label is  "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0D of ram_256_x_16 : label is  "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0E of ram_256_x_16 : label is  "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0F of ram_256_x_16 : label is  "0000000000000000000000000000000000000000000000000000000000000000";

begin
  ram_256_x_16: RAMB4_S16
  generic map (INIT_00 => X"09000101794071206920612039FF31FF2914210CD700D600D500D400D000D002",
               INIT_01 => X"A204A200A202A207A206A20CA208A20AA20FA20E592051204920412019021101",
               INIT_02 => X"00000000000000000000000097009600950094009000DF25DE25DD25DC25D825",
               INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000",
  port map(    DI => "0000000000000000",
               EN => '1',
               WE => '0',
              RST => '0',
              CLK => clk,
             ADDR => address,
               DO => instruction(15 downto 0));

end low_level_definition;

Raw HEX file

0D002
0D000
0D400
0D500
0D600
0D700
0210C
02914
031FF
039FF
06120
06920
07120
07940
00101
00900
01101
01902
04120
04920
05120
05920
0A20E
0A20F
0A20A
0A208
0A20C
0A206
0A207
0A202
0A200
0A204
0D825
0DC25
0DD25
0DE25
0DF25
09000
09400
09500
09600
09700
...
...
...

Intel 8 HEX

:10000000D002D000D400D500D600D700210C29148E
:1000100031FF39FF61206920712079400101090019
:10002000110119024120492051205920A20EA20F8E
:10003000A20AA208A20CA206A207A202A200A2047F
:10004000D825DC25DD25DE25DF25900094009500F0
:04005000960097007F
:00000001FF

S-Rec

S1230000D002D000D400D500D600D700210C291431FF39FF612069207120794001010900B3
S1230020110119024120492051205920A20EA20FA20AA208A20CA206A207A202A200A20439
S1170040D825DC25DD25DE25DF2590009400950096009700BB
S5030003F9
S9030000FC