(原創) 如何在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。
The test program uses an on-chip memory peripheral called onchip_ram. If your SOPC Builder system does not have an on-chip memory you should add an on-chip memory to the design. The test program requires that the name of the on-chip RAM and the component name used in the test program match. Connect the on-chip RAM to the Nios II data master.
當將on-chip memory加入DE2_NIOS後,儘管只是預設的4K,在Quartus II編譯也會有以下錯誤訊息:
Error : Cannot place all RAM cells in design
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,出現以下錯誤訊息:
**** Build of configuration Debug for project test_checksum ****
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主要是這一句
Region needs to be 4976 bytes larger.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,執行後會出現以下錯誤訊息。
**** Build of configuration Debug for project blank_project_0 ****
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。
/* base of onchip ram defined in system.h file */2
/*alt_u8* buf = (alt_u8*) ONCHIP_RAM_BASE; */3
alt_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
* file11
* 12
* Version History13
* BR 04/01/2007 Created14
* 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. */26
int 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 efficient
C'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 and45
* computes the checksum.46
*/47
48
int 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( "Done
Result = 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)
浙公网安备 33010602011771号