|
|
 |
FPGA design from scratch. Part 35
Generate simulation HDL files
We will take one step back and look at the Xilinx simulation environment and use the program Simgen.
Simgen
Simgen creates and configures various VHDL and Verilog simulation models for a specified hardware. It takes a Microprocessor Hardware Specification (MHS) file as input, which describes the instantiations and connections of hardware components. Simgen is also capable of creating scripts for a specified vendor simulation tool. The scripts compile the generated simulation models. The hardware component is defined by the MHS file. Refer to the "Microprocessor Hardware Specification (MHS)" chapter in the Platform Specification Format Reference Manual for more information. For more information about Simgen read the Embedded System Tools Reference Manual (chapter 3).
Before we run Simgen let's make sure we have our software project selected in Xilinx Platform Studio. We also make sure we ticked the Marked for BRAM initialization (right-click Project: ETC_system_program).

We invoke Simgen from the Xilinx Platform Studio using the menu command: Simulation->Generate HDL Simulation Files. When the Simgen program has finished we find a new sub directory (simulation) in our xps directory.

Data2MEM Memory Tool
Data2MEM is a command line executable that transforms CPU execution code (in the form of an ELF file), or pure data, into Block RAM initialization records. Simgen will use Data2MEM to convert our ETC_system_program.elf file to a VHDL file that can be used to initialize the BRAM. Here is more information about Data2Mem.
Here are some of the files that were generated during the Simgen run.
ETC_system_sim.bmm
ETC_system_sim.bmm defines the BRAM size and address space.
// File: /home/svenand/root/projects/ETC/xps/simulation/behavioral/ETC_system_sim.bmm
ADDRESS_MAP microblaze_0 MICROBLAZE 100 ADDRESS_SPACE lmb_bram_combined COMBINED [0x00000000:0x00001fff] ADDRESS_RANGE RAMB16 BUS_BLOCK lmb_bram/lmb_bram/ramb16_0 [31:24] ; lmb_bram/lmb_bram/ramb16_1 [23:16] ; lmb_bram/lmb_bram/ramb16_2 [15:8] ; lmb_bram/lmb_bram/ramb16_3 [7:0] ; END_BUS_BLOCK; END_ADDRESS_RANGE; END_ADDRESS_SPACE; END_ADDRESS_MAP;
ETC_system_init.vhd
The ETC_system_init.vhd is a VHDL configuration file used to initialize the BRAM.
-- File generated by ucf2vhdl.pl
-- Type: beh
library unisim; library lmb_bram_elaborate_v1_00_a;
configuration lmb_bram_conf of lmb_bram_wrapper is for STRUCTURE for lmb_bram : lmb_bram_elaborate use entity lmb_bram_elaborate_v1_00_a.lmb_bram_elaborate; for STRUCTURE for ramb16_0 : ramb16 use entity unisim.ramb16(ramb16_v) generic map( READ_WIDTH_A => READ_WIDTH_A, READ_WIDTH_B => READ_WIDTH_B, WRITE_WIDTH_A => WRITE_WIDTH_A, WRITE_WIDTH_B => WRITE_WIDTH_B, WRITE_MODE_A => WRITE_MODE_A, WRITE_MODE_B => WRITE_MODE_B, RAM_EXTENSION_A => RAM_EXTENSION_A, RAM_EXTENSION_B => RAM_EXTENSION_B, INIT_00 => X"B8BCF930E0B82080B93030310000000000000000000000B8000000B800B800B8", INIT_01 => X"F8BC062020F92030B6E98099BC3030B0BCF930E830B6E9F03030BEE8E88099F8",
.........................removed
INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000"); end for;
end for; end for; end for; end lmb_bram_conf;
configuration ETC_system_conf of etc_system is for STRUCTURE for all : lmb_bram_wrapper use configuration work.lmb_bram_conf; end for; end for; end ETC_system_conf;
ETC_system_tb.vhd
ETC_system_tb.vhd is the VHDL top testbench file.
------------------------------------------------------------------------------- -- ETC_system_tb.vhd ------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL;
library UNISIM; use UNISIM.VCOMPONENTS.ALL;
entity ETC_system_tb is end ETC_system_tb;
architecture STRUCTURE of ETC_system_tb is
constant fpga_0_DDR_CLK_FB_PERIOD : time := 10 ns; constant sys_clk_pin_PERIOD : time := 10 ns; constant sys_rst_pin_LENGTH : time := 160 ns;
component ETC_system is port ( fpga_0_RS232_Uart_RX_pin : in std_logic; fpga_0_RS232_Uart_TX_pin : out std_logic; fpga_0_LEDs_4Bit_GPIO_IO_pin : inout std_logic_vector(0 to 3); fpga_0_LEDs_Positions_GPIO_IO_pin : inout std_logic_vector(0 to 4); fpga_0_Push_Buttons_Position_GPIO_IO_pin : inout std_logic_vector(0 to 4); fpga_0_DDR_SDRAM_64Mx32_DDR_Clk_pin : out std_logic; fpga_0_DDR_SDRAM_64Mx32_DDR_Clkn_pin : out std_logic; fpga_0_DDR_SDRAM_64Mx32_DDR_Addr_pin : out std_logic_vector(0 to 12); fpga_0_DDR_SDRAM_64Mx32_DDR_BankAddr_pin : out std_logic_vector(0 to 1); fpga_0_DDR_SDRAM_64Mx32_DDR_CASn_pin : out std_logic; fpga_0_DDR_SDRAM_64Mx32_DDR_CKE_pin : out std_logic; fpga_0_DDR_SDRAM_64Mx32_DDR_CSn_pin : out std_logic; fpga_0_DDR_SDRAM_64Mx32_DDR_RASn_pin : out std_logic; fpga_0_DDR_SDRAM_64Mx32_DDR_WEn_pin : out std_logic; fpga_0_DDR_SDRAM_64Mx32_DDR_DM_pin : out std_logic_vector(0 to 3); fpga_0_DDR_SDRAM_64Mx32_DDR_DQS_pin : inout std_logic_vector(0 to 3); fpga_0_DDR_SDRAM_64Mx32_DDR_DQ_pin : inout std_logic_vector(0 to 31); fpga_0_DDR_CLK_FB : in std_logic; sys_clk_pin : in std_logic; sys_rst_pin : in std_logic; ETC_0_I_RESETS_pin : in std_logic; ETC_0_ETC_TDI_EX_pin : in std_logic; ETC_0_ETC_TCKI_pin : in std_logic; ETC_0_ETC_TRSTZI_pin : in std_logic; ETC_0_ETC_TMSI_pin : in std_logic; ETC_0_JTC_TDO_ENB_pin : in std_logic; ETC_0_JTC_TDO_pin : in std_logic; ETC_0_CE1_pin : in std_logic; ETC_0_JTC_TCK_pin : out std_logic; ETC_0_JTC_TRSTZ_pin : out std_logic; ETC_0_JTC_TMS_pin : out std_logic; ETC_0_JTC_TDI_pin : out std_logic; ETC_0_ETC_TCKO_pin : out std_logic; ETC_0_ETC_TMSO_pin : out std_logic; ETC_0_ETC_TDO_pin : out std_logic; ETC_0_ETC_TDO_ENB_pin : out std_logic; ETC_0_ETC_TRSTZO_pin : out std_logic; ETC_0_ETC_ENB_pin : out std_logic; ETC_0_ETC_TDI_FX_pin : in std_logic; ETC_0_O_INTERRUPT_pin : out std_logic; LCD_16x2_GPIO_IO_pin : inout std_logic_vector(0 to 6) ); end component;
.........................removed -- Clock generator for fpga_0_DDR_CLK_FB
process begin fpga_0_DDR_CLK_FB <= '0'; loop wait for (fpga_0_DDR_CLK_FB_PERIOD/2); fpga_0_DDR_CLK_FB <= not fpga_0_DDR_CLK_FB; end loop; end process;
-- Clock generator for sys_clk_pin
process begin sys_clk_pin <= '0'; loop wait for (sys_clk_pin_PERIOD/2); sys_clk_pin <= not sys_clk_pin; end loop; end process;
-- Reset Generator for sys_rst_pin
process begin sys_rst_pin <= '0'; wait for (sys_rst_pin_LENGTH); sys_rst_pin <= not sys_rst_pin; wait; end process;
-- START USER CODE (Do not remove this line)
-- User: Put your stimulus here. Code in this -- section will not be overwritten.
-- END USER CODE (Do not remove this line)
end architecture STRUCTURE;
configuration ETC_system_tb_conf of ETC_system_tb is for STRUCTURE for all : ETC_system use configuration work.ETC_system_conf; end for; end for; end ETC_system_tb_conf;
Modifying the testbench file
We normally run all our simulations in batch mode and we need a simple way to tell how long the simulation will run. Here is one method to run 80000 ns after reset is released.
process begin sys_rst_pin <= '0'; wait for (sys_rst_pin_LENGTH); sys_rst_pin <= not sys_rst_pin; wait for 800000 ns; assert false report "NONE. End of simulation." severity failure; end process;
Compiling the BRAM initialization file
We compile the ETC_system_init.vhd together with the wrapper files and store it in the top library.
Compiling the testbench file
We compile the ETC_system_tb.vhd testbench file into the ETC_system_tb library and after elaboration we have the following database structure.

Simulating program execution
Here is the whole sequence to add a new application program to our simulation environment.
- Compile and link the program
- Convert the ELF file to a BRAM memory image (ETC_system_init.vhd)
- Compile the ETC_system_init.vhd using ncvhdl
- Elaborate everything using ncelab
- Run the simulation using ncsim (ETC_SYSTEM_TB_CONF)
- Save the waveforms
- When the simulation has finish look at the waveforms in Simvision.
Here is the program.
// The following constant maps to the name of the hardware instances that // were created in the EDK XPS system. #define GPIO_LCD_DEVICE_ID XPAR_LCD_16X2_DEVICE_ID #define GPIO_LED4_DEVICE_ID XPAR_LEDS_4BIT_DEVICE_ID #define GPIO_LEDP_DEVICE_ID XPAR_LEDS_POSITIONS_DEVICE_ID
// The following constant is used to determine which channel of the GPIO is // used if there are 2 channels supported.
#define LCD_CHANNEL 1 #define LED_CHANNEL 1
// The following are declared globally so they are zeroed and so they are // easily accessible from a debugger
XGpio GpioLCD; /* The Instance of the GPIO LCD Driver */ XGpio GpioLED4; /* The Instance of the GPIO LED4 Driver */ XGpio GpioLEDPOS; /* The Instance of the GPIO LEDPOS Driver */
int main(void) {
XStatus Status; // Initialize the GPIO component Status = XGpio_Initialize(&GpioLCD, GPIO_LCD_DEVICE_ID); if (Status != XST_SUCCESS) return XST_FAILURE; Status = XGpio_Initialize(&GpioLED4, GPIO_LED4_DEVICE_ID); if (Status != XST_SUCCESS) return XST_FAILURE; Status = XGpio_Initialize(&GpioLEDPOS, GPIO_LEDP_DEVICE_ID); if (Status != XST_SUCCESS) return XST_FAILURE; // Set the direction for all bits to be outputs XGpio_SetDataDirection(&GpioLCD, LCD_CHANNEL, 0x00); XGpio_SetDataDirection(&GpioLED4, LED_CHANNEL, 0x00); XGpio_SetDataDirection(&GpioLEDPOS, LED_CHANNEL, 0x00); // Turn on LEDs XGpio_DiscreteWrite(&GpioLED4, LED_CHANNEL, 0xa); XGpio_DiscreteWrite(&GpioLEDPOS, LED_CHANNEL, 0xa); // Write to LCD XGpio_DiscreteWrite(&GpioLCD, LCD_CHANNEL, 0xa); return XST_SUCCESS;
}
Here is the result.

The simulation runs as expected. One more milestone reached.
Top Next Previous
Posted at 05:56 pm by svenand
Permalink
FPGA design from scratch. Part 34
Program disassembly
What happened to our c program after we compiled and built it. Let's disassemble the ETC_system_program.elf to find out. We will us the command mb-objdump -d ETC_system_program.elf. Here is the printout:
Assembly code
Disassembly of section .vectors.reset:
00000000 <_start>: 0: b8080050 brai 80 // 50 <_TEXT_START_ADDR> Disassembly of section .vectors.sw_exception:
00000008 <_vector_sw_exception>: 8: b80801a0 brai 416 // 1a0 <_exception_handler> Disassembly of section .vectors.interrupt:
00000010 <_vector_interrupt>: 10: b80801bc brai 444 // 1bc <__interrupt_handler> Disassembly of section .vectors.hw_exception:
00000020 <_vector_hw_exception>: 20: b80801b8 brai 440 // 1b8 <_hw_exception_handler> Disassembly of section .text:
00000050 <_start1>: 50: 31a003d0 addik r13, r0, 976 // 3d0 <_SDA_BASE_> 54: 304003b0 addik r2, r0, 944 // 3b0 <_SDA2_BASE_> 58: 30200750 addik r1, r0, 1872 5c: b9f40088 brlid r15, 136 // e4 <_crtinit> 60: 80000000 or r0, r0, r0 64: 20210010 addi r1, r1, 16
00000068 <exit>: 68: b8000000 bri 0 // 68 <exit>
0000006c <__do_global_dtors_aux>: 6c: e0600350 lbui r3, r0, 848 // 350 <_essro> 70: 3021ffe4 addik r1, r1, -28 74: f9e10000 swi r15, r1, 0 78: bc030014 beqi r3, 20 // 8c 7c: b8000028 bri 40 // a4 80: f8600338 swi r3, r0, 824 // 338 <p.0> 84: 99fc2000 brald r15, r4 88: 80000000 or r0, r0, r0 8c: e8600338 lwi r3, r0, 824 // 338 <p.0> 90: e8830000 lwi r4, r3, 0 94: be24ffec bneid r4, -20 // 80 98: 30630004 addik r3, r3, 4 9c: 30600001 addik r3, r0, 1 a0: f0600350 sbi r3, r0, 848 // 350 <_essro> a4: e9e10000 lwi r15, r1, 0 a8: b60f0008 rtsd r15, 8 ac: 3021001c addik r1, r1, 28
000000b0 <frame_dummy>: b0: e860034c lwi r3, r0, 844 // 34c <_edata> b4: 3021ffe4 addik r1, r1, -28 b8: f9e10000 swi r15, r1, 0 bc: bc03001c beqi r3, 28 // d8 c0: b0000000 imm 0 c4: 30600000 addik r3, r0, 0 c8: 30a0034c addik r5, r0, 844 // 34c <_edata> cc: bc03000c beqi r3, 12 // d8 d0: 99fc1800 brald r15, r3 d4: 80000000 or r0, r0, r0 d8: e9e10000 lwi r15, r1, 0 dc: b60f0008 rtsd r15, 8 e0: 3021001c addik r1, r1, 28
000000e4 <_crtinit>: e4: 2021ffec addi r1, r1, -20 e8: f9e10000 swi r15, r1, 0 ec: 20c00350 addi r6, r0, 848 // 350 <_essro> f0: 20e00350 addi r7, r0, 848 // 350 <_essro> f4: 06463800 rsub r18, r6, r7 f8: bc720014 blei r18, 20 // 10c fc: f8060000 swi r0, r6, 0 100: 20c60004 addi r6, r6, 4 104: 06463800 rsub r18, r6, r7 108: bc92fff4 bgti r18, -12 // fc 10c: 20c00350 addi r6, r0, 848 // 350 <_essro> 110: 20e0035c addi r7, r0, 860 // 35c <__bss_end> 114: 06463800 rsub r18, r6, r7 118: bc720014 blei r18, 20 // 12c 11c: f8060000 swi r0, r6, 0 120: 20c60004 addi r6, r6, 4 124: 06463800 rsub r18, r6, r7 128: bc92fff4 bgti r18, -12 // 11c 12c: b9f40084 brlid r15, 132 // 1b0 <_program_init> 130: 80000000 or r0, r0, r0 134: b9f401ac brlid r15, 428 // 2e0 <_etext> 138: 80000000 or r0, r0, r0 13c: 20c00000 addi r6, r0, 0 140: 20e00000 addi r7, r0, 0 144: b9f40024 brlid r15, 36 // 168 <main> 148: 20a00000 addi r5, r0, 0 14c: b9f401b8 brlid r15, 440 // 304 <__fini> 150: 80000000 or r0, r0, r0 154: b9f40054 brlid r15, 84 // 1a8 <_program_clean> 158: 80000000 or r0, r0, r0 15c: c9e10000 lw r15, r1, r0 160: b60f0008 rtsd r15, 8 164: 20210014 addi r1, r1, 20
00000168 <main>: 168: 3021ffe8 addik r1, r1, -24 16c: fa610014 swi r19, r1, 20 170: 12610000 addk r19, r1, r0 174: b00041f0 imm 16880 178: f800c004 swi r0, r0, -16380 17c: 3060007f addik r3, r0, 127 180: b00041f0 imm 16880 184: f860c000 swi r3, r0, -16384 188: b00041f0 imm 16880 18c: f800c000 swi r0, r0, -16384 190: 3060002a addik r3, r0, 42 194: b00041f0 imm 16880 198: f860c000 swi r3, r0, -16384 19c: b8000000 bri 0 // 19c
000001a0 <_exception_handler>: 1a0: b6110000 rtsd r17, 0 1a4: 80000000 or r0, r0, r0
000001a8 <_program_clean>: 1a8: b60f0008 rtsd r15, 8 1ac: 80000000 or r0, r0, r0
000001b0 <_program_init>: 1b0: b60f0008 rtsd r15, 8 1b4: 80000000 or r0, r0, r0
000001b8 <_hw_exception_handler>: 1b8: b8000000 bri 0 // 1b8 <_hw_exception_handler>
000001bc <__interrupt_handler>: 1bc: 3021ffb0 addik r1, r1, -80 1c0: f9e10000 swi r15, r1, 0 1c4: f8610020 swi r3, r1, 32 1c8: f8810024 swi r4, r1, 36 1cc: f8a10028 swi r5, r1, 40 1d0: f8c1002c swi r6, r1, 44 1d4: f8e10030 swi r7, r1, 48 1d8: f9010034 swi r8, r1, 52 1dc: f9210038 swi r9, r1, 56 1e0: f941003c swi r10, r1, 60 1e4: f9610040 swi r11, r1, 64 1e8: f9810044 swi r12, r1, 68 1ec: fa210048 swi r17, r1, 72 1f0: 95608001 mfs r11, rmsr 1f4: e8a00340 lwi r5, r0, 832 1f8: e860033c lwi r3, r0, 828 // 33c <MB_InterruptVectorTable> 1fc: fa41004c swi r18, r1, 76 200: f961001c swi r11, r1, 28 204: 99fc1800 brald r15, r3 208: 80000000 or r0, r0, r0 20c: e9e10000 lwi r15, r1, 0 210: e961001c lwi r11, r1, 28 214: e8610020 lwi r3, r1, 32 218: e8810024 lwi r4, r1, 36 21c: 940bc001 mts rmsr, r11 220: e8a10028 lwi r5, r1, 40 224: e8c1002c lwi r6, r1, 44 228: e8e10030 lwi r7, r1, 48 22c: e9010034 lwi r8, r1, 52 230: e9210038 lwi r9, r1, 56 234: e941003c lwi r10, r1, 60 238: e9610040 lwi r11, r1, 64 23c: e9810044 lwi r12, r1, 68 240: ea210048 lwi r17, r1, 72 244: ea41004c lwi r18, r1, 76 248: b62e0000 rtid r14, 0 24c: 30210050 addik r1, r1, 80
00000250 <microblaze_register_handler>: 250: f8a0033c swi r5, r0, 828 // 33c <MB_InterruptVectorTable> 254: f8c00340 swi r6, r0, 832 258: b60f0008 rtsd r15, 8 25c: 80000000 or r0, r0, r0
00000260 <XAssert>: 260: e8600354 lwi r3, r0, 852 // 354 <XAssertCallbackRoutine> 264: 3021ffe4 addik r1, r1, -28 268: f9e10000 swi r15, r1, 0 26c: bc230018 bnei r3, 24 // 284 270: e8600344 lwi r3, r0, 836 // 344 <XWaitInAssert> 274: bc230000 bnei r3, 0 // 274 278: e9e10000 lwi r15, r1, 0 27c: b60f0008 rtsd r15, 8 280: 3021001c addik r1, r1, 28 284: 99fc1800 brald r15, r3 288: 80000000 or r0, r0, r0 28c: b800ffe4 bri -28 // 270
00000290 <XAssertSetCallback>: 290: f8a00354 swi r5, r0, 852 // 354 <XAssertCallbackRoutine> 294: b60f0008 rtsd r15, 8 298: 80000000 or r0, r0, r0
0000029c <XNullHandler>: 29c: b60f0008 rtsd r15, 8 2a0: 80000000 or r0, r0, r0
000002a4 <__do_global_ctors_aux>: 2a4: 3021ffe0 addik r1, r1, -32 2a8: fa61001c swi r19, r1, 28 2ac: e8600320 lwi r3, r0, 800 // 320 <__CTOR_LIST__> 2b0: 32600320 addik r19, r0, 800 // 320 <__CTOR_LIST__> 2b4: f9e10000 swi r15, r1, 0 2b8: b8000010 bri 16 // 2c8 2bc: 99fc1800 brald r15, r3 2c0: 3273fffc addik r19, r19, -4 2c4: e8730000 lwi r3, r19, 0 2c8: aa43ffff xori r18, r3, -1 2cc: bc32fff0 bnei r18, -16 // 2bc 2d0: e9e10000 lwi r15, r1, 0 2d4: ea61001c lwi r19, r1, 28 2d8: b60f0008 rtsd r15, 8 2dc: 30210020 addik r1, r1, 32 Disassembly of section .init:
000002e0 <__init>: 2e0: 3021fff8 addik r1, r1, -8 2e4: d9e00800 sw r15, r0, r1 2e8: b9fc00b0 bralid r15, 176 // b0 <frame_dummy> 2ec: 80000000 or r0, r0, r0 2f0: b9fc02a4 bralid r15, 676 // 2a4 <__do_global_ctors_aux> 2f4: 80000000 or r0, r0, r0 2f8: c9e00800 lw r15, r0, r1 2fc: b60f0008 rtsd r15, 8 300: 30210008 addik r1, r1, 8 Disassembly of section .fini:
00000304 <__fini>: 304: 3021fff8 addik r1, r1, -8 308: d9e00800 sw r15, r0, r1 30c: b9fc006c bralid r15, 108 // 6c <__do_global_dtors_aux> 310: 80000000 or r0, r0, r0 314: c9e00800 lw r15, r0, r1 318: b60f0008 rtsd r15, 8 31c: 30210008 addik r1, r1, 8
MicroBlaze Software Reference Guide
The MicroBlaze Software Reference Guide will tell us all about writing software for the MicroBlaze soft processor.
System memory layout
How is the system memory allocated. Let's try to find out. Address range 0x00000000-0x0000004f is reserved for reset, exceptions, interrupt and break vectors.
| Event | Vector Address
| Register File Return Address
| | Reset | 0x00000000-0x00000004 | - | User Vector (Exception)
| 0x00000008-0x0000000c | Rx | | Interrrupt | 0x00000010-0x00000014 | R14 | Break
| 0x00000018-0x0000001c | R16 | Hardware Exception
| 0x00000020-0x00000024 | R17 or BTR
| Reserved by Xilinx for future use
| 0x00000028-0x0000004f | - | To allow for 64 bit addressing two 32 bit worlds are reserved for each vector.
Reset sequence

When a Reset occurs, MicroBlaze flushes the pipeline and starts fetching instructions from the reset vector (address 0x0). The external reset signal is active high and should be asserted for a minimum of 16 cycles.
The branch instruction <brai _TEXT_START_ADDR> stored in address 0x0 will be executed (see Simvision plot). _TEXT_START_ADDR marks the start of the executable code.
ELF file content
C routine
| Description | | _start1 | | | exit | End of program loop | | _do_global_dtors_aux | | | frame_dummy | | | _crtinit | | | main | Our program
| _exception_handler
| | _program_clean
|
| _program_init
|
| _hw_exception_handler
|
| __interrupt_handler
|
| microblaze_register_handler
|
| XAssert
|
| XAssertSetCallback
|
| XNullHandler
|
| __do_global_ctors_aux
|
| __init
|
| __fini
|
| Here are some more information about the different files used when compiling and linking a typical MicroBlaze executable. Startup files
The compiler includes pre-compiled startup and end files in the final link command when forming an executable. Startup files set up the language and the platform environment before your application code executes. The following actions are typically performed by startup files:
- Set up any reset, interrupt, and exception vectors as required.
- Set up stack pointer, small-data anchors, and other registers. Refer to Table 10-9 for details.
- Clear the BSS memory regions to zero.
- Invoke language initialization functions, such as C++ constructors.
- Initialize the hardware sub-system.
- Set up arguments for the main procedure and invoke it.
Similarly, end files are used to include code that must execute after your program ends. The following actions are typically performed by end files:
- Invoke language cleanup functions, such as C++ destructors.
- De-initialize the hardware sub-system. For example, if the program is being profiled, clean up the profiling sub-system.
First stage initialization files
crt0.o
This initialization file is used for programs which are to be executed in standalone mode, without the use of any bootloader or debugging stub such as xmdstub. This CRT populates the reset, interrupt, exception, and hardware exception vectors and invokes the second stage startup routine _crtinit. On returning from _crtinit, it ends the program by infinitely looping in the exit label.
Second stage initialization files
According to the C standard specification, all global and static variables must be initialized to 0. This is a common functionality required by all the CRTs above. Another routine _crtinit is invoked. The _crtinit routine initializes memory in the .bss section of the program. _crtinit is also the wrapper that invokes the main procedure. Before invoking the main procedure, it may invoke other initialization functions. _crtinit is supplied by the following startup files, as described below.
crtinit.o This is the default second stage C startup file. This startup file performs the following steps:
- Clears the .bss section to zero.
- Invokes _program_init.
- Invokes "constructor" functions (__init).
- Sets up the arguments for main and invokes main.
- Invokes "destructor" functions (__fini).
- Invokes _program_clean and returns.
Top Next Previous
Posted at 06:59 pm by svenand
Permalink
FPGA design from scratch. Part 33
Simulating the LCD driver
I have been fighting for a few days to the get the LCD driver to display "Hello World" on the LCD without success. Now it's time to setup our simulation environment and run some simulations to try to figure out what is going on. See part 23 and 24 for more information on how to setup and run a simulation. We can also take a look in EDK System Simulation Tutorial. C program
Here is the first program we are going to use. We load the code into SDK and compile and link it and then convert the load module to a memory image that we can use in our simulation.
#include "xparameters.h"
#define poke(addr,val) (*(unsigned char*) (addr) = (val)) #define pokew(addr,val) (*(unsigned*) (addr) = (val)) #define peek(addr) (*(unsigned char*) (addr)) #define peekw(addr) (*(unsigned*) (addr))
int main(void) {
unsigned char byte_of_data; unsigned word_of_data; int i,j; // Define GPIO bus as outputs only pokew(XPAR_LCD_16X2_BASEADDR+4,0x00); // Write data to LCD pokew(XPAR_LCD_16X2_BASEADDR,0x7f); pokew(XPAR_LCD_16X2_BASEADDR,0x00); pokew(XPAR_LCD_16X2_BASEADDR,0x2a); // Stay in this loop while(1); return 0; }
Program execution
Here is the result.

Looks perfectly fine to me. So far so good. Let's do the same thing using the Xilinx's software drivers. Like this:
//$$INCLUDE /*************************************************************************/ /* */ /* I N C L U D E H E A D E R F I L E S */ /* */ /*************************************************************************/
#include "xparameters.h" #include "xgpio.h"
//$$DEFINE /*************************************************************************/ /* */ /* D E F I N E C O N S T A N T S */ /* */ /*************************************************************************/
// The following constant maps to the name of the hardware instances that // were created in the EDK XPS system. #define GPIO_LCD_DEVICE_ID XPAR_LCD_16X2_DEVICE_ID
// The following constant is used to determine which channel of the GPIO is // used for the LCD if there are 2 channels supported.
#define LCD_CHANNEL 1
// The following are declared globally so they are zeroed and so they are // easily accessible from a debugger
XGpio GpioLCD; /* The Instance of the GPIO Driver */
//$$MAIN /*************************************************************************/ /* */ /* M A I N P R O G R A M */ /* */ /*************************************************************************/
int main(void) {
XStatus Status; // Initialize the GPIO component Status = XGpio_Initialize(&GpioLCD, GPIO_LCD_DEVICE_ID); if (Status != XST_SUCCESS) return XST_FAILURE; // Set the direction for all bits to be outputs XGpio_SetDataDirection(&GpioLCD, LCD_CHANNEL, 0x00000000); // Write data XGpio_DiscreteWrite(&GpioLCD, LCD_CHANNEL, 0x7f); XGpio_DiscreteWrite(&GpioLCD, LCD_CHANNEL, 0x00); XGpio_DiscreteWrite(&GpioLCD, LCD_CHANNEL, 0x2a); while(1); return XST_SUCCESS;
}
Before we continue to compile and build a complete application program let's take a look at Xilinx software platform.
Generating the software libraries and BSPs
The Library Generation tool (Libgen) configures libraries, device drivers, file systems, and interrupt handlers for the embedded processor system, creating a software platform. For more information about Libgen, refer to the "Library Generator (Libgen)" chapter in the Embedded System Tools Reference Manual. For more information on libraries and device drivers, see the OS and Libraries Document Collection. To generate the software libraries and BSPs (Board Support Packages), right-click on the specific Software Platform project <microblaze_0_sw_platform> and select . This invokes Libgen. The software library for the project is created in the project area: .../microblaze_0/lib/libxil.a The address map of the system is created in the header file: .../microblaze_0/include/xparameters.h A status message appears in the Console window at the bottom of the SDK main window. 
The following libraries are generated during the libgen run: | Library | Description | Included
| Size | | libc.a | Standard C functions compiled for MicroBlaze | Yes
| 382620 | | libm.a | Math functions
| Use -lm
| 414260 | | libxil.a | Xilinx software drivers
| Yes
| 175302 | For more information about the libraries read the document <sa_oslib_libxil_stdc.pdf > found in the directory: .../edk_install/doc/usenglish.
GNU Compiler Tools
EDK includes the GNU compiler (GCC) tools for both the PowerPC™ and MicroBlaze processors. The EDK GNU tools support both the C and C++ languages. The MicroBlaze GNU tools include mb-gcc and mb-g++ compilers, mb-as assembler and mb-ld loader/linker.
The GNU compiler is named mb-gcc for MicroBlaze and powerpc-eabi-gcc for PowerPC. The GNU compiler is a wrapper that calls the following executables:
Pre-processor (cpp0) – This is the first pass invoked by the compiler. The pre-processor replaces all macros with definitions as defined in the source and header files.
Machine and language specific compiler – This compiler works on the pre-processed code, which is the output of the first stage. The language-specific compiler is one of the following:
- C Compiler (cc1) – The compiler is responsible for most of the optimizations done on the input C code and generating assembly code.
- C++ Compiler (cc1plus) – The compiler is responsible for most of the optimizations done on the input C++ code and generates assembly code.
Assembler (mb-as for MicroBlaze and powerpc-eabi-as for PowerPC) – The assembly code has mnemonics in assembly language. The assembler converts these to machine language. The assembler also resolves some of the labels generated by the compiler. It creates an object file, which is passed on to the linker.
Linker (mb-ld for MicroBlaze and powerpc-eabi-ld for PowerPC) – The linker links all the object files generated by the assembler. If libraries are provided on the command line, the linker resolves some of the undefined references in the code by linking in some of the functions from the assembler. For more information read Embedded System Tools Reference Manual chapter 10. Input files
The compilers take one or more of the following files as input:
- C source files
- C++ source files
- Assembly files
- Object files
- Linker scripts
If not specified, the default linker script embedded in the linker (mb-ld or powerpc-eabi-ld) is used. In addition to the files mentioned above, the compiler implicitly refers to the libraries files libc.a, libgcc.a, libm.a, and libxil.a.
Output files
The compiler generates the following files as output:
- An ELF file; the default output file name is a.out
- Assembly file, if -save-temps or -S option is used
- Object file, if -save-temps or -c option is used
- Preprocessor output, .i or .ii file, if -save-temps option is used
Output from SDK build process
When we select Project->Build Project in SDK the following process takes place.
make all mb-gcc -c -mno-xl-soft-mul -mxl-pattern-compare -mcpu=v6.00.b -I../../microblaze_0_sw_platform/microblaze_0/include -xl-mode-executable -g -O0 -omain.o ../main.c Building target: ETC_system_program.elf mb-gcc -o ETC_system_program.elf main.o -mno-xl-soft-mul -mxl-pattern-compare -mcpu=v6.00.b -L../../microblaze_0_sw_platform/microblaze_0/lib -xl-mode-executable Finished building: ETC_system_program.elf
************** Validating ELF File **************
Validating ELF Section Addresses with Hardware Address Map... elfcheck -mhs /home/svenand/root/projects/ETC/xps/ETC_system.mhs -p xc4vfx12ff668-10 -xmpdir /home/svenand/root/projects/ETC/xps -pe microblaze_0 ETC_system_program.elf elfcheck Xilinx EDK 9.1.01 Build EDK_J_SP1.3 Copyright (c) 1995-2007 Xilinx, Inc. All rights reserved.
Command Line: elfcheck -mhs /home/svenand/root/projects/ETC/xps/ETC_system.mhs -p xc4vfx12ff668-10 -xmpdir /home/svenand/root/projects/ETC/xps -pe microblaze_0 ETC_system_program.elf
ELF file : ETC_system_program.elf
Populating list of memories for processor microblaze_0...
Analyzing file ETC_system_program.elf...
Elfcheck on ETC_system_program.elf completed successfully!
************** Determining Size of ELF File **************
mb-size ETC_system_program.elf text data bss dec hex filename 1794 112 1088 2994 bb2 ETC_system_program.elf
Build complete for project ETC_system_program
Program size
The mb-size program displays the size of the text, data and bss parts. The total size is displayed in decimal (dec) and hexadecimal (hex) format.
Text
This section of the object file contains executable program instructions. This section has the x (executable), r (read-only) and i (initialized) flags. This means that this section can be assigned to an initialized read-only memory (ROM).
Data
This section contains read-write data. This section has the w (read-write) and the i (initialized) flags. It must be mapped to initialized random access memory (RAM). It cannot be mapped to a ROM.
BSS
This section contains un-initialized data. The program stack and the heap are also allocated to this section. This section has the w (read-write) flag and must be mapped to RAM.
Top Next Previous
Posted at 09:45 am by svenand
Permalink
FPGA design from scratch. Part 32
FPGA design from scratch. Part 31
Adding a 16x2 character LCD display
To write the "Hello world" program we need a place to display the greeting. We will add an LCD display. We are going to use the General Purpose IO interface to drive the LCD display. In the IP catalog we open the General Purpose IO entry and choose the OPB General Purpose IO and select Add IP from the menu. For more information about adding a new IP block see Part 17.

Set address range
We will select a 4k address range and click Generate Addresses to define the Base Address and the High Address for the IP block.

Connecting ports
We will make GPIO_IO an external port. All other ports are left unconnected.

The easy way to add a new block
Probably the easiest way to add a new peripheral is to edit the ETC_system.mhs file. This file will be read when we start XPS and the information will be displayed in the System Assembly window. To add a new GPIO block we can copy one of the existing GPIO block and edit the information to fit our new block. Like this:
BEGIN opb_gpio PARAMETER INSTANCE = LEDs_4Bit PARAMETER HW_VER = 3.01.b PARAMETER C_GPIO_WIDTH = 4 PARAMETER C_IS_DUAL = 0 PARAMETER C_IS_BIDIR = 1 PARAMETER C_ALL_INPUTS = 0 PARAMETER C_BASEADDR = 0x40040000 PARAMETER C_HIGHADDR = 0x4004ffff BUS_INTERFACE SOPB = mb_opb PORT GPIO_IO = fpga_0_LEDs_4Bit_GPIO_IO END
Copy, paste and edit.
BEGIN opb_gpio PARAMETER INSTANCE = LCD_16x2 PARAMETER HW_VER = 3.01.b PARAMETER C_GPIO_WIDTH = 7 PARAMETER C_IS_DUAL = 0 PARAMETER C_IS_BIDIR = 1 PARAMETER C_ALL_INPUTS = 0 PARAMETER C_BASEADDR = 0x41f0c000 PARAMETER C_HIGHADDR = 0x41f0cfff BUS_INTERFACE SOPB = mb_opb PORT GPIO_IO = LCD_16x2_GPIO_IO END
The next time we start Xilinx Platform Studio the LCD_16x2_GPIO_IO block will be added.
Configure the IP block
Before we can configure the IP block we need to know more about the LCD display on the ML403 evaluation board. Let's read the ML403 User Guide. Here is what it has to say about the LCD display:
The ML403 board has a 16-character x 2-line LCD (Lumex LCM-S01602DTR/M) on the board to display text information. Potentiometer R1 adjusts the contrast of the LCD. The data interface to the LCD is connected to the FPGA to support 4-bit mode only. A level translator chip is used to shift the voltage level between the FPGA and the LCD.
The Spartan-3A Starter Kit Board User Guide gives us some more information about the LCD display (see chapter 5), but observe that this is not the same implementation as used on the ML403 board. To find out more about the LCD implementation on the ML403 board we take a look at the schematics.
 (Courtesy of Xilinx) The LCD driver
The LCD driver used on the ML403 board is a Samsung S6A0069 dot matrix LCD driver & controller LSI device. It can display 1 or 2 lines with a 5x8 or a 5x11 dots matrix. It can be set to use an 8 bit or 4 bit data bus. On the ML403 board the bus is 4 bits.
| RS | RW | Operation | | L | L | Instruction write operation (MPU writes instruction code into IR)
| | L | H | Read Busy Flag (DB7) and address counter
| | H | L | Data write operation (MPU writes data into DR)
| | H | H | Data read operation (MPU reads data from DR) | LCD display timingThe LCD display is a practical way to display a variety of information using standard ASCII characters and even allows you to create some of your own. However, these displays are not fast. This design scrolls the display at 0.5 second intervals and that really is the practical limit for clarity. This low performance rate also relates to the signals used for communication. Compared with a Virtex-4 operating at 100MHz, the display can appear extremely slow. This is where MicroBlaze can be used to efficiently implement timing delays as well as control the actual content of the display.
4-bit write operation
This timing diagram shows a single write operation being performed. The diagram is approximately to scale showing the minimum times allowed for setup, hold and enable pulse length relative to a 50MHz clock (20ns period). The data D[7:4], Register Select (RS) and write control (RW) must be set up at least 40ns before the enable E goes High. Enable must be High or at least 230ns which is almost 12 clock cycles at 50MHz. In our write only system, the R/W signal can be tied Low permanently.
 8-bit write operation
After initial display communication is established, all data transfers are 8-bit ASCII character codes, data bytes or 8-bit addresses. Each 8-bit transfer obviously has to be decomposed into two 4-bit transfers which must be spaced by at least 1μs. Following an 8-bit write operation, there must be an interval of at least 40μs before the next communication. This delay must be increased to 1.64ms following a clear display command.

Programming sequence
Here are all the steps needed to send an 8 bit instruction to the LCD driver in 4 bit mode:
- Keep LCD_RW low (write mode)
- Set LCD_RS high (data mode)
- Put data bits 7:4 on the bus (LCD_D7:LCD_D4)
- Wait 100ns
- Set LCD_E high
- Wait 300ns
- Set LCD_E low
- Wait 1500ns
- Put data bits 3:0 on the bus (LCD_D7:LCD_D4)
- Wait 100ns
- Set LCD_E high
- Wait 300ns
- Set LCD_E low
- Wait 60us
Display setup
Before the display can be used for the first time, there is an initialisation sequence which must be followed to allow communication to take place. These sequences are ideally suited to an processor such as MicroBlaze. Besides the relative complexity of the sequence, the process is only executed once and then the processor is available to perform other tasks including the control on the display itself.
More reading
Signal wiring on the ML403 board
Signal Name
| Description | GP IO pin
| FPGA Pin Location
| LCD_E
| Read/Write Enable Pulse 0: Disabled 1: Read/Write operation enabled | 0
| AE13
| | LCD_RS | Register Select 0:Instruction register during write 1:Data for read or write operation
| 1
| AC17 | | LCD_RW | Read/Write Control 0:Write, LCD accepts data 1:Read, LCD presents data
| 2
| AB17 | | LCD_DB7 | Data Bus bit 7
| 3
| AF12 | | LCD_DB6 | Data Bus bit 6
| 4
| AE12 | | LCD_DB5 | Data Bus bit 5
| 5
| AC10 | | LCD_DB4 | Data Bus bit 4
| 6
| AB10 | It looks like we need seven General Purpose IO pins to control the LCD display. The rest is software. We will set the GPIO Data Bus Width to 7 and leave everything else untouched.

Adding constraints
The following constraints will be added to the constraints file .../ETC/xps/data/ETC_system.ucf
#### Module LCD_16x2 constraints
NET "LCD_16x2_GPIO_IO_pin<0>" LOC="AE13" | IOSTANDARD = LVCMOS33 | TIG ; NET "LCD_16x2_GPIO_IO_pin<1>" LOC="AC17" | IOSTANDARD = LVCMOS33 | TIG ; NET "LCD_16x2_GPIO_IO_pin<2>" LOC="AB17" | IOSTANDARD = LVCMOS33 | TIG ; NET "LCD_16x2_GPIO_IO_pin<3>" LOC="AF12" | IOSTANDARD = LVCMOS33 | TIG ; NET "LCD_16x2_GPIO_IO_pin<4>" LOC="AE12" | IOSTANDARD = LVCMOS33 | TIG ; NET "LCD_16x2_GPIO_IO_pin<5>" LOC="AC10" | IOSTANDARD = LVCMOS33 | TIG ; NET "LCD_16x2_GPIO_IO_pin<6>" LOC="AB10" | IOSTANDARD = LVCMOS33 | TIG ;
Generate Netlist
After adding the new IP block we have to rerun netlist generation Hardware->Generate Netlist. The netlist generation generates a number of warnings but finish successfully.
WARNING:MDT - INST:dcm_1 PORT:LOCKED CONNECTOR:dcm_1_lock - /home/svenand/root/projects/ETC/xps/ETC_system.mhs line 306 - floating connection!
WARNING:Xst:2211 - "/home/svenand/root/projects/ETC/xps/hdl/ETC_system.vhd" line 2217: Instantiating black box module <IOBUF>.
Xst:387 - The KEEP property attached to the net <microblaze_0/microblaze_0/Performance.Decode_I/of_PipeRun_Prefetch> may hinder timing optimization. You may achieve better results by removing this property
Generate Bitstream
Next step is to generate a new bitstream Hardware->Generate Bitstream. The bitstream generation generates a number of warnings but finish successfully.
WARNING:NgdBuild:440 - FF primitive 'ddr_sdram_64mx32/ddr_sdram_64mx32/DDR_CTRL_I/WO_ECC.RDDATA_PATH_I/V2_ASYNCH_ FIFO_I/BU520' has unconnected output pin WARNING:NgdBuild:478 - clock net debug_module/bscan_drck1 with clock driver debug_module/debug_module/BUFG_DRCK1 drives no clock pins
WARNING:PhysDesignRules:372 - Gated clock. Clock net DCM_AUTOCALIBRATION_dcm_0/dcm_0/Using_DCM_ADV.DCM_ADV_INST/dcm_0/dcm_0/Using_ DCM_ADV.DCM_ADV_INST/cd/CLK<1> is sourced by a combinatorial pin. This is not good design practice. Use the CE pin to control the loading of data into the flip-flop.
Can someone explain the meaning of these warnings to me.
Top Next Previous
Posted at 10:25 am by svenand
Permalink
FPGA design from scratch. Part 30
Running demonstration software applications
To understand the process of running software applications in our embedded system we will start by reading the ML40x EDK Processor Reference Design user guide (Chapter 3. EDK Tutorial and Demonstrations). ML403 Reference Systems on the CD
The ML403 development kit comes with three reference systems on the Development Kit Reference CD.
- ML403 Embedded Processor Reference System (MicroBlaze-based)
- ML403 Embedded Processor Reference System (PoerPC 405-based)
- ML403 DCM Phase Shift Reference System (MicroBlaze-based)
Here is the content of the CD. Read the Getting Started with the PowerPC and MicroBlaze Development Kit - Virtex-4 FX12 Edition for more information. Top Next Previous
Posted at 02:19 pm by svenand
Permalink
FPGA design from scratch. Part 29
Hardware setup
Before we start running application programs. Let's take a look at our hardware setup.

- Apple MacBook Intel Core 2 Duo, Mac OS X 10.4.9. VMware Fusion virtual machine with Ubuntu 7.04 installed.
- Apple PowerBook G4 setup as a VT100 terminal emulator. The screen program emulates the HyperTerminal program. We can use any terminal we have available. We just happened to have a PowerBook lying around doing nothing.
- Apple CInema Display 23", the main display where ISE and EDK windows are displayed.
- Xilinx Platform Cable USB used to communicate with the ML403 evaluation board.
- Keyspan USB to Serial converter for connecting to the VT100 terminal.
- Xilinx ML403 evaluation board.
Software setup
Read the EDK Concept, Tools and Techniques guide to find out more about the software flow. (system.bit should be download.bit) (Courtesy of Xilinx) Download and execute a simple program
We will use the memory test program TestApp_Memory.c as our first simple example to see if the hardware and software will function on our board.

Start the Xilinx Platform Studio
==> xps &

Download the bitstream
The file system.bit, created after hardware generation (completion of Xflow), is an uninitialized bitstream and does not include the ELF file. It is only when we execute the command to download or update the bitstream that the system.bit and ELF files merge into download.bit. When we select Device Configuration > Download Bitstream, XPS downloads the bitstream (download.bit file) onto the target board using iMPACT in batch mode. XPS uses the file etc/download.cmd for downloading the bitstream. Because XPS tools are makefile based, the download button calls on the makefile and executes the steps necessary to create the bitstream with the Executable Linked Format (ELF) file populated within the bitstream. Get program size To ensure that the compiled TestApp_Memory code fits into the BRAM we will use the command Software->Get Program Size. At Local date and time: Mon Jun 4 19:46:49 2007 mb-size /home/svenand/root/projects/ETC/xps/TestApp_Memory/executable.elf started... text data bss dec hex filename 3944 332 2064 6340 18c4 /home/svenand/root/projects/ETC/xps/TestApp_Memory/executable.elf
Done!
Running the program
After we downloaded the bitstream the included program will start executing and display the result in the VT100 terminal.

The DDR SDRAM test program TestApp_Memory executes and it passes. We have reach one more milestone.
Top Next Previous
Posted at 11:10 am by svenand
Permalink
FPGA design from scratch. Part 28
Power calculations
Xilinx provides a number of spreadsheet- and web-based power estimation tools, power analyzers, and power-related documentation to meet our power solutions needs.
XPower
XPower is a power-analysis and detailed power estimation software available for programmable logic design. Included in all configurations of ISE™, XPower allows you to analyze total device power, power per-net, routed, partially routed or unrouted designs. XPower provides these capabilites through a comprehensive graphical user interface (GUI), or via command-line driven batch-mode. XPower also reads HDL simulation data to quickly set estimation stimulus, reducing setup time. Let's try XPower.
==> export DISPLAY=0: ==> xpower &

We will launch the design wizard.

Set voltage sources.

Set frequences for all clocks, feedback signals and inputs.

Set capacitive loads for outputs.

Set DC loads for outputs.

XPower power calculation

We will add more data into XPower at a later stage when we know more about our design.
Low power consumption
Meeting our power budget is essential for attaining system performance and cost goals. Low power enables higher clock frequency, higher reliability, better noise margins, and reduced capital and operational costs.
Top Next Previous
Posted at 04:32 pm by svenand
Permalink
FPGA design from scratch. Part 27
Pin assignment closure process
Closing on a pin assignment that will meet requirements from both the PCB and FPGA environments is becoming more challenging. On one side of the interface, ever-increasing FPGA performance, density, and I/O count are placing tighter board constraints on the layout of the signal to and from the FPGA. On the other side, timing, congestion, and signal integrity of ever-faster signals on the PCB are placing constraints on FPGA pin assignment. Here is an article by Philippe Garrault from Xilinx describing the pin assignment closure process.
 (Courtesy of Xilinx) Tools to help you in pin assignment closure
PACE Pin and Area Constraint Editor
ISE includes PACE (Pinout and Area Constraints Editor), a powerful, yet fast and easy way to map design pins to your device, and floorplan logic areas. Drag-and-drop pins onto a graphical display of the device, group pins logically by color-coding for easy recognition, specify I/O standards and banks, assign and place differential I/Os, and much more. As devices grow ever larger, PACE brings a new level of ease to the difficult task of assigning design pins.
Running PACE
Let's start the PACE program.
==> pace &
/home/svenand/cad/xilinx91i/bin/lin/_pace: error while loading shared libraries: libXm.so.3: cannot open shared object file: No such file or directory
To fix this problem we have to load the following Ubuntu packages: libmotif3 libmotif-dev
==> pace &
Wind/U X-toolkit Error: wuDisplay: Can't open display
We have to change the DISPLAY variable from :0.0 to :0
==> export DISPLAY=:0 ==> pace &

We specify our constraints file ETC_system.ucf as the input file to PACE and click OK.

PACE allows you to edit both location and area constraints, define logic areas graphically, and display I/Os on the periphery for connectivity checking. PACE allows area mapping by examining the defined HDL hierarchy and checks logic areas against expected gate size, making area definitions quick, accurate, and easy. Pins can be assigned using PACE before HDL coding has even started, and then write the HDL starting templates for you to edit. Pin information can be exported or imported to PCB layout editors through standard CSV files, greatly simplifying the design planning stage. PACE contains built-in design rule checks like Simultaneous Switching Outputs to help predict ground bounce problems, unique displays like Package Flight Time allow you to see I/O to package lead delays for super-accurate timing. Topi the Top Code Generator
Ever heard of table driven design. That is exactly what Topi is all about. When designing an FPGA with more than 1000 signal pins you need an exact and precise way of adding all the signal names. Topi will help you generate the top testbench, the top instantiation and the FPGA pin layout, all in the same tool.
Topi Setup
 Using Topi to modify the Xilinx user constraints file
Let's start Topi. ==> topi &

We open the Setup->Pin Table window and select the Xilinx CSV table format.

Let's load the Xilinx CSV file into the Topi Spreadsheet Editor.
Here is the result. ' The next step is to import the pin layout information into the Topi Pin Layout Editor. From the Load menu we select Pin Names (Match Package Balls).

In the pin layout editor we can easily change the pin placement by editing each indivudual signal name or by moving pins around using the move function. When we are satisfied with the result we can save the information in a Xilinx user constraints file (ucf).
Xilinx Floorplanner
Xilinx Floorplanner is a graphical placement tool that provides "drag and drop" control over design placement within an FPGA. Floorplanning is particularly useful on structured designs and data path logic. With the Xilinx Floorplanner, designers can see where to place logic for optimal results, placing data paths exactly at the desired location on the die. The Xilinx Floorplanner enables designers to plan a design prior to or after using Place-and-Route (PAR) software. Invoking Floorplanner after a design has been placed and routed allows designers to view and possibly improve the results of the automatic implementation. In an iterative floorplan design flow, designers floorplan and place and route interactively. When we started the PACE program we were told it will be replaced by the Floorplanner program. Why not give it a try.
==> floorplanner &

We enter the name of the ngd file and all the other files are found automatically. Click OK.

Viewing pin placement
If we select view Package Pins from the View menu we get the following display.

Xilinx PlanAhead
Here is an article about using PlanAhead Design and Analysis Tool.
Top Next Previous
Posted at 09:52 am by svenand
Permalink
FPGA design from scratch. Part 26
Using the iMPACT configuration tool
After we have connected the USB JTAG programming cable and started iMPACT it will detect the JTAG chain on the ML403 evaluation board and display it in the boundary scan window.

The FPGA, Platform Flash memory, and CPLD can be configured through the JTAG port. The JTAG chain of the board is illustrated in this figure.
 (Courtesy of Xilinx) Boundary -Scan and JTAG configuration
Virtex-4 devices support the new IEEE 1532 standard for In-System Configuration (ISC), based on the IEEE 1149.1 standard. The IEEE 1149.1 Test Access Port and Boundary-Scan Architecture is commonly referred to as JTAG. JTAG is an acronym for the Joint Test Action Group, the technical subcommittee initially responsible for developing the standard. This standard provides a means to ensure the integrity of individual components and the interconnections between them at the board level. With multi-layer PC boards becoming increasingly dense and more sophisticated surface mounting techniques in use, Boundary- Scan testing is becoming widely used as an important debugging standard.
IEEE standard 1149.1 (JTAG) The Virtex-4 family is fully compliant with the IEEE Standard 1149.1 Test Access Port and Boundary-Scan Architecture. The architecture includes all mandatory elements defined in the IEEE 1149.1 Standard. These elements include the Test Access Port (TAP), the TAP controller, the instruction register, the instruction decoder, the Boundary-Scan register, and the bypass register. The Virtex-4 family also supports a 32-bit identification register and a configuration register in full compliance with the standard.
 (Courtesy of Xilinx) The identification register
Virtex devices have a 32-bit identification register called the IDCODE register. The IDCODE is based on the IEEE 1149.1 standard, and is a fixed, vendor-assigned value that is used to identify electrically the manufacturer and the type of device that is being addressed. This register allows easy identification of the part being tested or programmed by Boundary-Scan, and it can be shifted out for examination by using the IDCODE instruction.
Read IDCODE
Select one of the devices displayed in the Boundary Scan window and and double-click the Get Device ID entry in the Operations window. The result is displayed in the Output window.
// *** BATCH CMD : ReadIdcode -p 3 Maximum TCK operating frequency for this device chain: 10000000. Validating chain... Boundary-scan chain validated successfully. '3': IDCODE is '00100001111001011000000010010011' '3': IDCODE is '21e58093' (in hex). '3': : Manufacturer's ID =Xilinx xc4vfx12, Version : 2 Read the FPGA status register
Select the Virtex-4 device in the Boundary Scan window and double-click the Read Status Register entry in the Operations window, The result is displayed in the Output window.
// *** BATCH CMD : ReadStatusRegister -p 3 Maximum TCK operating frequency for this device chain: 10000000. Validating chain... Boundary-scan chain validated successfully. '3': Reading status register contents... CRC error : 0 Decryptor security set : 0 DCM locked : 1 DCI matched : 1 End of startup signal from Startup block : 1 status of GTS_CFG_B : 1 status of GWE : 1 status of GHIGH : 1 value of MODE pin M0 : 1 value of MODE pin M1 : 1 Value of MODE pin M2 : 1 Internal signal indicates when housecleaning is completed: 1 Value driver in from INIT pad : 1 Internal signal indicates that chip is configured : 1 Value of DONE pin : 1 Indicates when ID value written does not match chip ID : 0 Decryptor error Signal : 0 System Monitor Over-Temperature Alarm : 0
Device configuration Configuring and programming are often used interchangeably. However, there is a distinction between these two terms. Configuration refers to the process of loading design-specific data into one or more volatile FPGAs using an external data source such as a PROM. Programming refers to the process of loading design-specific data into one or more non-volatile PROMs or CPLD devices. Configuring or programming a device defines the functional operations of the device. For simplification, we refer both configuring and programming as the device configuration. For general configuration guidelines, see XAPP501 Application Note. Using Xilinx Platform StudioNow when we are confident about our usb cable connection we are ready for the final step, downloading the bitstream to the FPGA device. We will start Xilinx Platform Studio (xps) to help us do the job.
==> cd $ETC_PROJECT ==> xps

To start the bitstream download select Device Configuration->Download Bitstream. The result is displayed in the output window. It says Programmed successfully. Huzzah!
Top Next Previous
Posted at 03:47 pm by svenand
Permalink
|