ASH1 Assembler

During the last week, I worked on developing an assembler for ASH1! I have always wondered about the assemblers & compilers design… with AESTE, I had the chance to explore this field.

ASH1 assembler is developed using MATLAB. It takes an assembly language source file (text file) and translates it into ASH1 object file (mif file). This is done by carrying out three passes over the source file as the following:

  • In the first pass, comments and blank lines are omitted.
  • In the second pass, labels, constants and instructions are sorted out.
  • In the third pass, instruction arguments are classified and sorted out.

A typical source file would be composed of the following sections:

  1. defs:    In this part of the file, the programmer declares constants ( purely numeric value) or addresses (specific address within the register file) by using symbols that are alphanumeric representations.  The legal character set for the symbols is the set of letters, both upper and lower case (A-Z, a-z), the set of decimal numbers (0-9), and the underscore (_).  The range for the numbers that can be represented within the defs: are 8-bit unsigned integer numbers which is written in decimal number system.
  2. labels: In this part of the file, the programmer states all the labels. Labels are special cases of symbols that can be used only before assembly language instructions to denote the physical address associated with them. The legal character set for the symbols is the set of letters, both upper and lower case (A-Z, a-z), the set of decimal numbers (0-9), and the underscore (_).
  3. program: In this part of the file, the programmer writes down the various assembly language instructions that make up the code of interest. ASH1 assembly language has 38 instructions. Each has different set of arguments.

So after writing the code for ASH1 in a text file, ASH1 assembler can generate the mif file for that code. I developed a simple GUI that can be fired under MATLAB, where the source file can be loaded and assembled.

To ensure that the assembler could run under OCTAVE as well, I separated the GUI layer to enable users to use the assembler code via Command Line Interface (CLI).

 

 

ASH1 : An LCD Driver and VGA Colour Controller

After integrating Ethernet operations into ASH1.. I though of demonstrating ASH1 as an IOP .. so I looked for a simple I/O operation, yet a simple one to make my life easy when I am writing the code for it in binary. I decided to make ASH1 works as an LCD driver in addition to VGA colour controller.

For the LCD driver code, I wrote the code and compared it with the one used in PIC Projects: A Practical Approach for pic16f627a. ASH1 code took  143.5 bytes  whereas for pic16f627a, the code took up 161 bytes.

For VGA Colour Controller, I make it pretty simple since writing a code in binary for the whole VGA controller would take a lot of time. ASH1 was just responsible for the colour  patterns generated on the screen. The other functions required for the VGA was implemented in hardware.

And here is what I got ….. ASH1 driving an LCD with “ASH1=] says Hi !” message and controlling the colours of a displayed image on a VGA monitor.

CRC Operations: A follow-up

Cyclic Redundancy Checksums generation and checking were among the challenging things in implementing ASH1. Looking for the accurate way to calculate/check CRCs took me a lot of time as it was confusing in terms of the following:

  1. Bit Orientations (LSB first or MSB first).
  2. The Initial Value of the CRC register (0s or 1s).
  3. CRC Orientation and Inversion.

Through checking some online resources, I found out that it is not only me who faced this problem. People here were struggling to get the correct values of different CRCs.

My implementation of a CRC generator/checker was 100% correct..but yet different tools showed different CRCs until I found this online tool which enabled me to check along with ASH1 CRC unit the different conditions that might be used in CRC calculation/generation… and here’s what I got:( I calculated the CRC-32 for  0×16 and then check for it’s validity… and the result was 0xc704dd7b  ( the complement of 0x38fb2284) which is the residue for CRC-32…. So people, if you want to deal with CRCs… pay attention to the 3 points mentioned above!

Ethernet Operations: Random Generator

Back-off is an important feature of the Ethernet MAC protocol. After a collision is detected through the MII/RMII interface, ASH1 should stop transmitting (there are more specific details about when exactly to stop transmission) and then reschedule its retransmission by generating a period of time to wait before retransmission. The period of time is based on a random number chosen by ASH1 and used in its back-off calculations.

The amount of total back-off delay is calculated by multiplying the slot time by a randomly chosen integer. The range of integers used in the choice is generated according to the rules of the back-off algorithm, which create a range of integers that increases in size after each collision that occurs for a given frame transmission attempt. The interface then randomly chooses an integer from this range, and the product of this integer and the slot time creates a new back-off time.

The back-off algorithm uses the following formula for determining the integer r, which is used to multiply the slot time and generate a back-off delay: where k = min(n,10).

0 < r < 2^k

To translate into something closer to English:

• r is an integer randomly selected from a range of integers. The value of r may range from zero to one less than the value of two to the exponent, k.

• k is assigned a value that is equal to either the number of transmission attempts or the number 10, whichever is less.

This algorithm can be implemented by ASH1 by the following:

  1. Creating a 10-bit counter that is incremented on the rising edge of ASH1 clock. Thereby, we can have a random number generator.
  2. By keeping track of the number of collision happened so far, we can choose the random number range by ANDING the 10-bit counter with (no. of collisions -1).
  3. Keep in mind that after 10 collisions, the range will be the same. And after 16, ASH1 must report an error.

 

Now, how to implement this:

The main point is to come up with a random generator unit that will generate random integers based on the number of collisions taken place so far. so basically the random generator unit will have an 4-bit input ( top of stack) determining the range of the random number and the output will be a 10-bit number that can be pushed on the stack to make use of it for the back -off time.

Implementing the random generator can be done either by using a counter as we’re sampling this counter at an unknown random time, yet it might not be so random as it’s going up and rolls over again. A better way is to use some kind of linear feedback shift register.

After implementing the random generator, this is what I got (you can check with the range in the table at the bottom of the post):

I’ve generated a random light sequence of DE2 board using ASH1 here : Random_Generator_Light_Sequence

Ethernet Operations : an eye-opener!

I have mentioned many times that ASH1 should be as small and as fast as possible… The current version of ASH1 is able to perform USB functions pretty good ( more specifically 1.5 Mbps USB operations) and other simple I/O operations.

However, getting myself into Ethernet and trying to integrate it into ASH1 lets me see potential chances for  improvement of ASH1. For example:

  1. Although, PUSH & POP are frequent operations of a stack-based processor, I designed ASH1 to do most of the job with least number of PUSH/POPs, which adds up some complexity on FLAG/STACK units of ASH1.
  2. Instruction Width & Stack Width: Currently ASH1′s instructions are 14-bit wide instructions, which limits the amount of data to be deal with. Having 32-bit instructions would increase the chances of implementing absolute branching/jumping over a relative one. Also having a 16-bit wide stack would reduce the degree of complexity of the design when interfacing the stack with other unit of ASH1.
  3. ASH1/Master CPU Data Center: ASH1 is communicating with the master CPU via the wishbone bus through 3 data centers (storage) that are Tx, Rx buffers and a register file which complicates the wishbone interface and adds up additional things to care about. Ethernet operations made me think of excluding the the buffers and use the register file (RAM) only. The reason behind that was the fact that some data might need to be re-transmitted again which will be difficult when we’re dealing with buffers ( need to be re-filled again prior to re-transmission).
  4. CRC unit : CRC unit in ASH1 was implemented as a state machine that’s controlled by an instruction but now I am thinking of implementing a parallel architecture for CRC which makes it faster and smaller.
Follow

Get every new post delivered to your Inbox.