mem2hex component - read from memory and generate .hex character stream

A project log for Intel HEX files for FPGAs (no embedded CPUs!)

Uploading / downloading Intel HEX file stream during system runtime, implemented without embedded processor!

zpekiczpekic 09/15/2021 at 06:570 Comments

Refer to microcode and source code for the following description.

mem2hex is the simpler of two components. It is a linear memory reader, that adds some additional characters to the hex stream of memory bytes to produce a valid hex record. These records are 16 or 32 data bytes long, with the exception of last record which always has the same format (: 00 0000 01 FF)

Component structure (.vhd)

The main part are the registers that keep the state as the hex record is being assembled:

Conditions: to drive the microcode logic, state of some registers must be detected, for example if count has reached zero, address / page is zero etc. These are in line 160...163.

Memory bus interface: this is a "Z80" - like interface. mem2hex behaves as a DMA-output device:

Code structure (.mcc)

Microcode starts with the definition of storage and controller unit:

.code 6, 34, mem2hex_code.mif, mem2hex_code.cgf, mem2hex_code.coe, m2h:mem2hex_code.vhd, mem2hex_code.hex, mem2hex_code.bin, 8;
.mapper 8, 6, mem2hex_map.mif, mem2hex_map.cgf, mem2hex_map.coe, m2h:mem2hex_map.vhd, mem2hex_map.hex, mem2hex_map.bin, 1;
.controller mem2hex_control_unit.vhd, 4;

This defines:

After these, the fields in the microcode must be defined:

Alias definitions are convenience to minimize coding repetion. They are simple forms of "macros".

//	useful aliases, these are evaluated as simple text replacement of label with everything between .alias and ; 
goto:	.alias if false then next else;
noop:	.alias if true then next else next;
back:	.alias if true then return else return;

 with the above, writing "goto foo;" is a simple jump, and writing "back;" is unconditional return from subroutine etc.

Subroutine definitions:

The controller unit is wired to check the then and else part of the sequence and if they are same and not one of the first 4 reserved values (next, repeat, return, fork), branch to that location but pushing the current address + 1 on the stack. This is done in 1 cycle. There are two ways to achieve this in the microcode:

  1. use .sub pragma with label defined by it
  2. use "if condition then label else label" (which can be shortened as .alias)

#1 is preferred because is allows listing any number of regfield name definitions. These are not true "parameters" but handy way to indicate which register values will be set as the subroutine starts executing. 

(to be continued)