(原創) 如何在DE2執行Checksum Master範例? (IC Design) (DE2) (Quartus II) (Nios II) (SOPC Builder)
Abstract
Checksum Master為Quartus II 7.2 Handbook Vol:4中,示範使用Component Editor將user logic包成component後,並撰寫software driver的範例,但手冊中的程式和步驟都無法在DE2上順利執行,本文提出解決的方法。
使用環境 : Quartus II 7.2 SP1 + Nios II 7.2 SP1 + DE2 (Cyclone II EP2C35F627C6)
手冊版本 :Quartus II Version 7.2 Handbook Volume4 : SOPC Builder
Introduction
Checksum Master是Altera在Quartus 7.1之後的範例程式,用以取代以前的PWM(pulse width modulator),PWM只示範了Avalon-MM slave interface,但Checksum Master同時示範了master和slave,且搭配SOPC Builder 7.1之後大改的介面。
不過很不幸的,Altera所附的範例和手冊中的步驟,僅適用於Altera原廠的版子,並不適用於DE2,經過幾天的搏鬥,總算修改成適用於Quartus 7.2 SP1和DE2的範例。
下載Checksum Master
我將Altera原廠的Checksum Master上傳了,請按此下載altera_avalon_checksum.zip。
原廠Checksum Master範例的問題
1.範例僅適用於Altera原廠的版子,並不適用於DE2。
2.範例中使用onchip memory,不過由於DE2上EP2C35F627C6 FPGA的logic element限制,onchip memory最多只能設定49K左右,但這樣的memory size仍無法執行此範例。
Solution
本文並沒有打算重寫整個tutorial,所以建議先將Quartus II 7.2 Handbook Vol.4 Ch.9 Developing Components for SOPC Builder瀏覽一次,在此只將與手冊中不適用於DE2之處列出。
1.使用DE2的reference design
在手冊中的P.9-9頁,Altera建議我們使用<Nios EDS install path>/examples/<verilog or vhdl>/<board version>/standard 目錄下的硬體,由於DE2用的是EP2C35F627C6這顆晶片,直覺會選Cyclone II的niosII_cycloneII_2c35這塊版子,但可惜這是Altera原廠的版子,並非DE2,若選擇這塊版子,Quartus II連編譯都不會過。
請在此下載DE2的reference design
http://www.terasic.com/downloads/cd-rom/de2/
根據你DE2的型號和使用Quartus II的版本,下載適當的DE2_System版本。
若你使用的是Quartus II 7.2,則建議下載Quartus II 7.1的版本,畢竟Quartus II 7.1大改,7.2和7.1較接近,遇到的問題會較少。
以我的狀況,是使用DE2_System_1.4b.zip這個版本。
DE2的Nios II reference design在壓縮檔內的
\DE2_demonstrations\SOPC_Builder\Reference_Design\DE2_NIOS\
將這個目錄複製到任何位置,並更改目錄名稱為checksum_master_onchip,使用Quartus II開起DE2_NIOS.qpf。
2.使用on-chip memory
在Quartus II Vol.4 Ch.9 P.9-24,有一段話,特別強調須使用on-chip memory。
當將on-chip memory加入DE2_NIOS後,儘管只是預設的4K,在Quartus II編譯也會有以下錯誤訊息:
Error : Can't fit design in device
原因是on-chip memory相當浪費logic element count,FPGA已經塞不下了,或許你會說,『DE2的Nios II reference design放了很多我沒用到的component,將其刪除就可放on-chip memory了』,聽起來是個可行方案,我試著將component刪到只剩下最簡,Nios II CPU也改成最簡單的Nios II/e,如此可將on-chip memory擴大到49K,也依照了手冊的步驟加入了user logic component,最後SOPC Builder如下:
DE2 reference design完整code如下
DE2_NIOS.v
// Copyright (c) 2005 by Terasic Technologies Inc.
// --------------------------------------------------------------------
//
// Permission:
//
// Terasic grants permission to use and modify this code for use
// in synthesis for all Terasic Development Boards and Altera Development
// Kits made by Terasic. Other use of this code, including the selling
// ,duplication, or modification of any portion is strictly prohibited.
//
// Disclaimer:
//
// This VHDL/Verilog or C/C++ source code is intended as a design reference
// which illustrates how these types of functions can be implemented.
// It is the user's responsibility to verify their design for
// consistency and functionality through the use of formal
// verification methods. Terasic provides no warranty regarding the use
// or functionality of this code.
//
// --------------------------------------------------------------------
//
// Terasic Technologies Inc
// 356 Fu-Shin E. Rd Sec. 1. JhuBei City,
// HsinChu County, Taiwan
// 302
//
// web: http://www.terasic.com/
// email: support@terasic.com
//
// --------------------------------------------------------------------
//
// Major Functions: DE2 NIOS Reference Design
//
// --------------------------------------------------------------------
//
// Revision History :
// --------------------------------------------------------------------
// Ver :| Author :| Mod. Date :| Changes Made:
// V2.0 :| Johnny Chen :| 06/07/19 :| Initial Revision
// --------------------------------------------------------------------
module DE2_NIOS
(
//////////////////// Clock Input ////////////////////
CLOCK_27, // On Board 27 MHz
CLOCK_50, // On Board 50 MHz
EXT_CLOCK, // External Clock
//////////////////// Push Button ////////////////////
KEY, // Pushbutton[3:0]
//////////////////// DPDT Switch ////////////////////
SW, // Toggle Switch[17:0]
//////////////////// 7-SEG Dispaly ////////////////////
HEX0, // Seven Segment Digit 0
HEX1, // Seven Segment Digit 1
HEX2, // Seven Segment Digit 2
HEX3, // Seven Segment Digit 3
HEX4, // Seven Segment Digit 4
HEX5, // Seven Segment Digit 5
HEX6, // Seven Segment Digit 6
HEX7, // Seven Segment Digit 7
//////////////////////// LED ////////////////////////
LEDG, // LED Green[8:0]
LEDR, // LED Red[17:0]
//////////////////////// UART ////////////////////////
UART_TXD, // UART Transmitter
UART_RXD, // UART Receiver
//////////////////////// IRDA ////////////////////////
IRDA_TXD, // IRDA Transmitter
IRDA_RXD, // IRDA Receiver
///////////////////// SDRAM Interface ////////////////
DRAM_DQ, // SDRAM Data bus 16 Bits
DRAM_ADDR, // SDRAM Address bus 12 Bits
DRAM_LDQM, // SDRAM Low-byte Data Mask
DRAM_UDQM, // SDRAM High-byte Data Mask
DRAM_WE_N, // SDRAM Write Enable
DRAM_CAS_N, // SDRAM Column Address Strobe
DRAM_RAS_N, // SDRAM Row Address Strobe
DRAM_CS_N, // SDRAM Chip Select
DRAM_BA_0, // SDRAM Bank Address 0
DRAM_BA_1, // SDRAM Bank Address 1
DRAM_CLK, // SDRAM Clock
DRAM_CKE, // SDRAM Clock Enable
//////////////////// Flash Interface ////////////////
FL_DQ, // FLASH Data bus 8 Bits
FL_ADDR, // FLASH Address bus 20 Bits
FL_WE_N, // FLASH Write Enable
FL_RST_N, // FLASH Reset
FL_OE_N, // FLASH Output Enable
FL_CE_N, // FLASH Chip Enable
//////////////////// SRAM Interface ////////////////
SRAM_DQ, // SRAM Data bus 16 Bits
SRAM_ADDR, // SRAM Address bus 18 Bits
SRAM_UB_N, // SRAM High-byte Data Mask
SRAM_LB_N, // SRAM Low-byte Data Mask
SRAM_WE_N, // SRAM Write Enable
SRAM_CE_N, // SRAM Chip Enable
SRAM_OE_N, // SRAM Output Enable
//////////////////// ISP1362 Interface ////////////////
OTG_DATA, // ISP1362 Data bus 16 Bits
OTG_ADDR, // ISP1362 Address 2 Bits
OTG_CS_N, // ISP1362 Chip Select
OTG_RD_N, // ISP1362 Write
OTG_WR_N, // ISP1362 Read
OTG_RST_N, // ISP1362 Reset
OTG_FSPEED, // USB Full Speed, 0 = Enable, Z = Disable
OTG_LSPEED, // USB Low Speed, 0 = Enable, Z = Disable
OTG_INT0, // ISP1362 Interrupt 0
OTG_INT1, // ISP1362 Interrupt 1
OTG_DREQ0, // ISP1362 DMA Request 0
OTG_DREQ1, // ISP1362 DMA Request 1
OTG_DACK0_N, // ISP1362 DMA Acknowledge 0
OTG_DACK1_N, // ISP1362 DMA Acknowledge 1
//////////////////// LCD Module 16X2 ////////////////
LCD_ON, // LCD Power ON/OFF
LCD_BLON, // LCD Back Light ON/OFF
LCD_RW, // LCD Read/Write Select, 0 = Write, 1 = Read
LCD_EN, // LCD Enable
LCD_RS, // LCD Command/Data Select, 0 = Command, 1 = Data
LCD_DATA, // LCD Data bus 8 bits
//////////////////// SD_Card Interface ////////////////
SD_DAT, // SD Card Data
SD_DAT3, // SD Card Data 3
SD_CMD, // SD Card Command Signal
SD_CLK, // SD Card Clock
//////////////////// USB JTAG link ////////////////////
TDI, // CPLD -> FPGA (Data in)
TCK, // CPLD -> FPGA (Clock)
TCS, // CPLD -> FPGA (CS)
TDO, // FPGA -> CPLD (Data out)
//////////////////// I2C ////////////////////////////
I2C_SDAT, // I2C Data
I2C_SCLK, // I2C Clock
//////////////////// PS2 ////////////////////////////
PS2_DAT, // PS2 Data
PS2_CLK, // PS2 Clock
//////////////////// VGA ////////////////////////////
VGA_CLK, // VGA Clock
VGA_HS, // VGA H_SYNC
VGA_VS, // VGA V_SYNC
VGA_BLANK, // VGA BLANK
VGA_SYNC, // VGA SYNC
VGA_R, // VGA Red[9:0]
VGA_G, // VGA Green[9:0]
VGA_B, // VGA Blue[9:0]
//////////// Ethernet Interface ////////////////////////
ENET_DATA, // DM9000A DATA bus 16Bits
ENET_CMD, // DM9000A Command/Data Select, 0 = Command, 1 = Data
ENET_CS_N, // DM9000A Chip Select
ENET_WR_N, // DM9000A Write
ENET_RD_N, // DM9000A Read
ENET_RST_N, // DM9000A Reset
ENET_INT, // DM9000A Interrupt
ENET_CLK, // DM9000A Clock 25 MHz
//////////////// Audio CODEC ////////////////////////
AUD_ADCLRCK, // Audio CODEC ADC LR Clock
AUD_ADCDAT, // Audio CODEC ADC Data
AUD_DACLRCK, // Audio CODEC DAC LR Clock
AUD_DACDAT, // Audio CODEC DAC Data
AUD_BCLK, // Audio CODEC Bit-Stream Clock
AUD_XCK, // Audio CODEC Chip Clock
//////////////// TV Decoder ////////////////////////
TD_DATA, // TV Decoder Data bus 8 bits
TD_HS, // TV Decoder H_SYNC
TD_VS, // TV Decoder V_SYNC
TD_RESET, // TV Decoder Reset
//////////////////// GPIO ////////////////////////////
GPIO_0, // GPIO Connection 0
GPIO_1 // GPIO Connection 1
);
//////////////////////// Clock Input ////////////////////////
input CLOCK_27; // On Board 27 MHz
input CLOCK_50; // On Board 50 MHz
input EXT_CLOCK; // External Clock
//////////////////////// Push Button ////////////////////////
input [3:0] KEY; // Pushbutton[3:0]
//////////////////////// DPDT Switch ////////////////////////
input [17:0] SW; // Toggle Switch[17:0]
//////////////////////// 7-SEG Display ////////////////////////
output [6:0] HEX0; // Seven Segment Digit 0
output [6:0] HEX1; // Seven Segment Digit 1
output [6:0] HEX2; // Seven Segment Digit 2
output [6:0] HEX3; // Seven Segment Digit 3
output [6:0] HEX4; // Seven Segment Digit 4
output [6:0] HEX5; // Seven Segment Digit 5
output [6:0] HEX6; // Seven Segment Digit 6
output [6:0] HEX7; // Seven Segment Digit 7
//////////////////////////// LED ////////////////////////////
output [8:0] LEDG; // LED Green[8:0]
output [17:0] LEDR; // LED Red[17:0]
//////////////////////////// UART ////////////////////////////
output UART_TXD; // UART Transmitter
input UART_RXD; // UART Receiver
//////////////////////////// IRDA ////////////////////////////
output IRDA_TXD; // IRDA Transmitter
input IRDA_RXD; // IRDA Receiver
/////////////////////// SDRAM Interface ////////////////////////
inout [15:0] DRAM_DQ; // SDRAM Data bus 16 Bits
output [11:0] DRAM_ADDR; // SDRAM Address bus 12 Bits
output DRAM_LDQM; // SDRAM Low-byte Data Mask
output DRAM_UDQM; // SDRAM High-byte Data Mask
output DRAM_WE_N; // SDRAM Write Enable
output DRAM_CAS_N; // SDRAM Column Address Strobe
output DRAM_RAS_N; // SDRAM Row Address Strobe
output DRAM_CS_N; // SDRAM Chip Select
output DRAM_BA_0; // SDRAM Bank Address 0
output DRAM_BA_1; // SDRAM Bank Address 0
output DRAM_CLK; // SDRAM Clock
output DRAM_CKE; // SDRAM Clock Enable
//////////////////////// Flash Interface ////////////////////////
inout [7:0] FL_DQ; // FLASH Data bus 8 Bits
output [21:0] FL_ADDR; // FLASH Address bus 22 Bits
output FL_WE_N; // FLASH Write Enable
output FL_RST_N; // FLASH Reset
output FL_OE_N; // FLASH Output Enable
output FL_CE_N; // FLASH Chip Enable
//////////////////////// SRAM Interface ////////////////////////
inout [15:0] SRAM_DQ; // SRAM Data bus 16 Bits
output [17:0] SRAM_ADDR; // SRAM Address bus 18 Bits
output SRAM_UB_N; // SRAM Low-byte Data Mask
output SRAM_LB_N; // SRAM High-byte Data Mask
output SRAM_WE_N; // SRAM Write Enable
output SRAM_CE_N; // SRAM Chip Enable
output SRAM_OE_N; // SRAM Output Enable
//////////////////// ISP1362 Interface ////////////////////////
inout [15:0] OTG_DATA; // ISP1362 Data bus 16 Bits
output [1:0] OTG_ADDR; // ISP1362 Address 2 Bits
output OTG_CS_N; // ISP1362 Chip Select
output OTG_RD_N; // ISP1362 Write
output OTG_WR_N; // ISP1362 Read
output OTG_RST_N; // ISP1362 Reset
output OTG_FSPEED; // USB Full Speed, 0 = Enable, Z = Disable
output OTG_LSPEED; // USB Low Speed, 0 = Enable, Z = Disable
input OTG_INT0; // ISP1362 Interrupt 0
input OTG_INT1; // ISP1362 Interrupt 1
input OTG_DREQ0; // ISP1362 DMA Request 0
input OTG_DREQ1; // ISP1362 DMA Request 1
output OTG_DACK0_N; // ISP1362 DMA Acknowledge 0
output OTG_DACK1_N; // ISP1362 DMA Acknowledge 1
//////////////////// LCD Module 16X2 ////////////////////////////
inout [7:0] LCD_DATA; // LCD Data bus 8 bits
output LCD_ON; // LCD Power ON/OFF
output LCD_BLON; // LCD Back Light ON/OFF
output LCD_RW; // LCD Read/Write Select, 0 = Write, 1 = Read
output LCD_EN; // LCD Enable
output LCD_RS; // LCD Command/Data Select, 0 = Command, 1 = Data
//////////////////// SD Card Interface ////////////////////////
inout SD_DAT; // SD Card Data
inout SD_DAT3; // SD Card Data 3
inout SD_CMD; // SD Card Command Signal
output SD_CLK; // SD Card Clock
//////////////////////// I2C ////////////////////////////////
inout I2C_SDAT; // I2C Data
output I2C_SCLK; // I2C Clock
//////////////////////// PS2 ////////////////////////////////
input PS2_DAT; // PS2 Data
input PS2_CLK; // PS2 Clock
//////////////////// USB JTAG link ////////////////////////////
input TDI; // CPLD -> FPGA (data in)
input TCK; // CPLD -> FPGA (clk)
input TCS; // CPLD -> FPGA (CS)
output TDO; // FPGA -> CPLD (data out)
//////////////////////// VGA ////////////////////////////
output VGA_CLK; // VGA Clock
output VGA_HS; // VGA H_SYNC
output VGA_VS; // VGA V_SYNC
output VGA_BLANK; // VGA BLANK
output VGA_SYNC; // VGA SYNC
output [9:0] VGA_R; // VGA Red[9:0]
output [9:0] VGA_G; // VGA Green[9:0]
output [9:0] VGA_B; // VGA Blue[9:0]
//////////////// Ethernet Interface ////////////////////////////
inout [15:0] ENET_DATA; // DM9000A DATA bus 16Bits
output ENET_CMD; // DM9000A Command/Data Select, 0 = Command, 1 = Data
output ENET_CS_N; // DM9000A Chip Select
output ENET_WR_N; // DM9000A Write
output ENET_RD_N; // DM9000A Read
output ENET_RST_N; // DM9000A Reset
input ENET_INT; // DM9000A Interrupt
output ENET_CLK; // DM9000A Clock 25 MHz
//////////////////// Audio CODEC ////////////////////////////
inout AUD_ADCLRCK; // Audio CODEC ADC LR Clock
input AUD_ADCDAT; // Audio CODEC ADC Data
inout AUD_DACLRCK; // Audio CODEC DAC LR Clock
output AUD_DACDAT; // Audio CODEC DAC Data
inout AUD_BCLK; // Audio CODEC Bit-Stream Clock
output AUD_XCK; // Audio CODEC Chip Clock
//////////////////// TV Devoder ////////////////////////////
input [7:0] TD_DATA; // TV Decoder Data bus 8 bits
input TD_HS; // TV Decoder H_SYNC
input TD_VS; // TV Decoder V_SYNC
output TD_RESET; // TV Decoder Reset
//////////////////////// GPIO ////////////////////////////////
inout [35:0] GPIO_0; // GPIO Connection 0
inout [35:0] GPIO_1; // GPIO Connection 1
wire CPU_CLK;
wire CPU_RESET;
wire CLK_18_4;
wire CLK_25;
// Flash
assign FL_RST_N = 1'b1;
// 16*2 LCD Module
assign LCD_ON = 1'b1; // LCD ON
assign LCD_BLON = 1'b1; // LCD Back Light
// All inout port turn to tri-state
assign SD_DAT = 1'bz;
assign AUD_ADCLRCK = AUD_DACLRCK;
assign GPIO_0 = 36'hzzzzzzzzz;
assign GPIO_1 = 36'hzzzzzzzzz;
// Disable USB speed select
assign OTG_FSPEED = 1'bz;
assign OTG_LSPEED = 1'bz;
// Turn On TV Decoder
assign TD_RESET = 1'b1;
// Set SD Card to SD Mode
assign SD_DAT3 = 1'b1;
Reset_Delay delay1 (.iRST(KEY[0]),.iCLK(CLOCK_50),.oRESET(CPU_RESET));
SDRAM_PLL PLL1 (.inclk0(CLOCK_50),.c0(DRAM_CLK),.c1(CPU_CLK),.c2(CLK_25));
Audio_PLL PLL2 (.areset(!CPU_RESET),.inclk0(CLOCK_27),.c0(CLK_18_4));
system_0 u0 (
// 1) global signals:
.clk(CPU_CLK),
.reset_n(CPU_RESET)
);
I2C_AV_Config u1 ( // Host Side
.iCLK(CLOCK_50),
.iRST_N(KEY[0]),
// I2C Side
.I2C_SCLK(I2C_SCLK),
.I2C_SDAT(I2C_SDAT) );
endmodule
如此修改後,Quartus II可順利編譯,並且用Programmer燒進DE2。
硬體部分解決了,但不代表軟體部分沒問題!!
接著如手冊的步驟,在Nios II EDS 7.2 build project,出現以下錯誤訊息:
make -s all includes
Compiling test_checksum.c
Linking test_checksum.elf
/cygdrive/c/altera/72/nios2eds/bin/nios2-gnutools/H-i686-pc-cygwin/bin/../lib/gcc/nios2-elf/3.4.1/http://www.cnblogs.com/http://www.cnblogs.com/nios2-elf/bin/ld: region onchip_ram is full (test_checksum.elf section .rwdata). Region needs to be 4976 bytes larger.
/cygdrive/c/altera/72/nios2eds/bin/nios2-gnutools/H-i686-pc-cygwin/bin/../lib/gcc/nios2-elf/3.4.1/http://www.cnblogs.com/http://www.cnblogs.com/nios2-elf/bin/ld: section .bss [00010020 -> 00010233] overlaps section .exceptions [00010020 -> 000101c7]
/cygdrive/c/altera/72/nios2eds/bin/nios2-gnutools/H-i686-pc-cygwin/bin/../lib/gcc/nios2-elf/3.4.1/http://www.cnblogs.com/http://www.cnblogs.com/nios2-elf/lib/mno-hw-mul//libc.a(sbrkr.o)(.text+0x14): In function `_sbrk_r':
/build/nios2eds-gnutools-win32-7.2/bin/nios2-gnutools/src/newlib/newlib/libc/reent/sbrkr.c:59: Unable to reach errno (at 0x00010020) from the global pointer (at 0x00025704) because the offset (-87780) is out of the allowed range, -32678 to 32767.
collect2: ld returned 1 exit status
make: *** [test_checksum.elf] Error 1
Build completed in 2.641 seconds
主要是這一句
on-chip memory不夠跑了,還需要4K的記憶體!!
但on-chip memory的49K已經是極限了!!
到了這邊,有兩條路可走
1.從軟體解決,想辦法將軟體的code size減少!!
2.從硬體解決,改用SRAM或SDRAM!!
軟體解決
修改System Library Properties選項
將Lightweight device driver API、Reduced device drivers、Small C library打勾,不要選取Support C++,這樣減少所產生的code size,可以節省些記憶體空間。
修改gcc參數
改為release mode和optimize size
如此修改後,可正常Build Project且Run As Hardware執行,結果如下
硬體解決
改用SRAM(或SDRAM)
從軟體解決雖然可以跑了,但並非長遠之道,且on-chip memory非常耗logic element,若日後在加上自己的verilog code,難保on-chip memory還夠用,且DE2上已經有SRAM和SDRAM,實應妥善運用這兩塊記憶體。
由於使用了SRAM,對DE2 reference design就不再做修改,但必須將altera_avalon_checksum_inst的m1(Avalon Master)改接在SRAM上。
軟體部分
由於改用了SRAM,System Library Properties必須改成run在SRAM上。
若直接使用原本的test_checksum.c,執行後會出現以下錯誤訊息。
make -s all includes
Compiling test_checksum.c
../test_checksum.c: In function `main':
../test_checksum.c:52: error: `ONCHIP_RAM_BASE' undeclared (first use in this function)
../test_checksum.c:52: error: (Each undeclared identifier is reported only once
../test_checksum.c:52: error: for each function it appears in.)
make: *** [obj/test_checksum.o] Error 1
Build completed in 3.203 seconds
因為硬體沒使用on-chip memory,故register map也沒有ONCHIP_RAM_BASE這個macro,由於我們改用了SRAM,故將macro名稱改為SRAM_0_BASE。
2/*alt_u8* buf = (alt_u8*) ONCHIP_RAM_BASE; */
3alt_u8* buf = (alt_u8*)SRAM_0_BASE;
完整的test_checksum.c如下
2* Copyright (c) 2007 Altera Corporation, San Jose, California, USA. *
3* All rights reserved. All use of this software and documentation is *
4* subject to the License Agreement located at the end of this file below. *
5*******************************************************************************/
6/* Simple C program that exercises the altera_avalon_checksum component by
7 * filling a memory buffer with test data and then configuring the
8 * altera_avalon_checksum to read back the data using the IOWR and IORD
9 * to directly write to the register locations as defined in the _regs.h
10 * file
11 *
12 * Version History
13 * BR 04/01/2007 Created
14 * ATJ 04/12/2007 Add additional comments
15 *
16*/
17
18#include <stdio.h>
19#include <stdlib.h>
20#include "altera_avalon_checksum_regs.h"
21#include "system.h"
22#include <alt_types.h>
23
24
25/* Simple function that sets all contents of a buffer to the specified value. */
26int set_buf_val( alt_u8* buffer, int length, alt_u8 val )
27{
28 int ret_code = 0;
29
30 /* Ok one byte at a time is not efficientC'est La Vie! */
31
32 while (length >= 0)
33 {
34 *(buffer + length) = val;
35 if( *(buffer+length) != val )
36 {
37 ret_code = -1;
38 }
39 length--;
40 }
41 return( ret_code );
42}
43
44/* This program points the checksum component at a small buffer and
45 * computes the checksum.
46 */
47
48int main()
49{
50 /* Point the buffer at the base of the onchip ram.*/
51 /* base of onchip ram defined in system.h file */
52 /*alt_u8* buf = (alt_u8*) ONCHIP_RAM_BASE; */
53 alt_u8* buf = (alt_u8*)SRAM_0_BASE;
54 /* Set the length small, to start with. */
55 int len = 12;
56 int status;
57 int result;
58
59
60 /* Set the buffer to all 0xF0's. */
61 printf( "Writing to test memory. \n");
62 if( (set_buf_val( buf, len, 0xf0 )<0) )
63 {
64 printf( "Error: Could not pre-set buffer at %d.\n", (int) buf );
65 return( -1 );
66 }
67
68 /* Setup the checksum component. */
69 /* IORD and IOWR macros setup in alter_avalon_checksum_regs.h and io.h */
70
71 /* Store the address (must be 32-bit word aligned address). */
72 printf( "Writing to address register. \n");
73 //IOWR_ALTERA_AVALON_CHECKSUM_ADDR( ALTERA_AVALON_CHECKSUM_INST_BASE, _RAM_BASE );
74 IOWR_ALTERA_AVALON_CHECKSUM_ADDR( ALTERA_AVALON_CHECKSUM_INST_BASE, SRAM_0_BASE );
75 /* Store the length in bytes (up to a 16-bit value). */
76 printf( "Writing to length register. \n");
77 IOWR_ALTERA_AVALON_CHECKSUM_LENGTH( ALTERA_AVALON_CHECKSUM_INST_BASE, len );
78 /* Tell it to "go". */
79 printf( "Writing to go bit in control register. \n");
80 IOWR_ALTERA_AVALON_CHECKSUM_CTRL( ALTERA_AVALON_CHECKSUM_INST_BASE+ALTERA_AVALON_CHECKSUM_CTRL_GO_OFST,
81 ALTERA_AVALON_CHECKSUM_CTRL_GO_MSK);
82 /* Polling loop waiting for the component to be done. */
83 status = IORD_ALTERA_AVALON_CHECKSUM_STATUS( ALTERA_AVALON_CHECKSUM_INST_BASE );
84
85 printf( "Polling for DONE bit in status register. . . \n");
86 while( !(status & ALTERA_AVALON_CHECKSUM_STATUS_DONE_MSK) )
87 {
88 status = IORD_ALTERA_AVALON_CHECKSUM_STATUS( ALTERA_AVALON_CHECKSUM_INST_BASE );
89 }
90 printf( "Done bit asserted, exiting polling loop. \n");
91
92 result = IORD_ALTERA_AVALON_CHECKSUM_RESULT( ALTERA_AVALON_CHECKSUM_INST_BASE );
93
94 printf( "DoneResult = 0x%x.\n", (int) result );
95
96 return 0;
97}
98
最後執行結果
完整程式碼下載
Altera原廠的altera_avalon_checksum.zip
Checksum Master on on-chip memory
Checksum Master on SRAM
Conclusion
凡是Altera原廠的範例,若要用在DE2,尤其是Nios II上,一定得改用DE2的reference design,這是跑不掉的。至於其他的修改,就得見招拆招了,畢竟DE2不是Altera原廠的版子。本文我們看到從軟體減少code size的方法,也看到從硬體從on-chip memory改用SRAM的方法。
See Also
(原創) 深入探討Altera的Checksum Master範例 (SOC) (SOPC Builder) (Nios II) (DE2)