📄 macro_usage.uc
字号:
//------------------------------------------------------------------------------------
//
// I N T E L P R O P R I E T A R Y
//
// COPYRIGHT (c) 2001 BY INTEL CORPORATION. ALL RIGHTS
// RESERVED. NO PART OF THIS PROGRAM OR PUBLICATION MAY
// BE REPRODUCED, TRANSMITTED, TRANSCRIBED, STORED IN A
// RETRIEVAL SYSTEM, OR TRANSLATED INTO ANY LANGUAGE OR COMPUTER
// LANGUAGE IN ANY FORM OR BY ANY MEANS, ELECTRONIC, MECHANICAL,
// MAGNETIC, OPTICAL, CHEMICAL, MANUAL, OR OTHERWISE, WITHOUT
// THE PRIOR WRITTEN PERMISSION OF :
//
// INTEL CORPORATION
//
// 2200 MISSION COLLEGE BLVD
//
// SANTA CLARA, CALIFORNIA 95052-8119
//
//-----------------------------------------------------------------------------------
// macro_usage.uc
// Example to demonstrate the usage of ixpblock macros
//
//
#include "buf.uc"
#include "bytefield.uc"
#include "cam.uc"
#include "constants.uc"
#include "cycle.uc"
#include "dram.uc"
#include "localmem.uc"
#include "scratch.uc"
#include "sig.uc"
#include "sram.uc"
#include "stdmac.uc"
#include "util.uc"
#include "xbuf.uc"
#include "put_nv.uc"
// ==================================================================
// This demonstrates the usage of SCRATCH macros
// ==================================================================
#macro scratch_examples_1()
.begin
.sig tmp_sig1 tmp_sig2 tmp_sig3 tmp_sig4 SIG_SRAM
///////////////////////////////////////////////////////////////////////////////////////
// Example 1: This example shows the usage of Scratch read/write macros. It illustrate the
// following points via different tasks:
//
// 1) Allocate a transfer buffers of 8 registers
// Illustrate: Usage of transfer buffers as source of scratch read and
// destination of scratch write
// 2) Write 4 long words to a random base and a random multiply-of-4
// offset in scratch memory. Subsequent writes don't have to wait for this
// write to complete
// Illustrate: - Offsets of all scratch accesses must be multiple of 4
// - The unit of access for Scratch memory is long words (4 bytes)
// - Usage of SIG_NONE in accesses that can happen in parallel
// 3) Write another 4 long words to another random location. This write will have
// to finish before the read in task 4
// Illustrate: - Usage of signals to make sure an access is finished before
// next accesses
// 4) Read all 8 long words at the location written before
// Illustrate: - Each xfer registers allocated by xbuf_alloc include
// 1 SRAM read transfer register and 1 SRAM write transfer
// register. The instruction will select the right type of
// register to use
// 5) Free the transfer buffers
////////////////////////////////////////////////////////////////////////////////////////
// Allocate buffer of Xfer registers
xbuf_alloc($xfer, 8, read_write)
//Initialize the write transfer registers
move($xfer[0], 0xFFFFFFFF)
move($xfer[1], 0x1111111)
move($xfer[2], 0x222222)
move($xfer[3], 0x33333)
move($xfer[4], 0x4444)
move($xfer[5], 0x555)
move($xfer[6], 0x66)
move($xfer[7], 0x7)
immed32(base, 0x1000);
alu[offset1, --, b, 0x10]
alu[offset2, --, b, 0x20]
//Task 1: write from the write transfer regsiters
scratch_write($xfer[0], base, offset1, 4, tmp_sig1, SIG_NONE, ___);
//Task 2
scratch_write($xfer[4], base, offset2, 4, tmp_sig2, signals(tmp_sig1, tmp_sig2), ___);
//Task 3: read into the read transfer registers
scratch_read($xfer[0], base, offset1, 8, SIG_SRAM, SIG_SRAM, ___);
//Display the read result
put_nv(x0, $xfer[0]);
put_nv(x1, $xfer[1]);
put_nv(x2, $xfer[2]);
put_nv(x3, $xfer[3]);
put_nv(x4, $xfer[4]);
put_nv(x5, $xfer[5]);
put_nv(x6, $xfer[6]);
put_nv(x7, $xfer[7]);
// Free buffer of Xfer registers
xbuf_free($xfer)
///////////////////////////////////////////////////////////////////////////////////////
// Example 2: This example shows the usage of Scratch read/write macros. It illustrates the
// following points via different tasks:
//
// 1) Allocate local transfer registers
// Illusttrate: Using transfer registers in Scratch macros
//
// 2) 3 writes of 4 long words each to a random base and random multiply-of-4
// offsets in scratch memory. Subsequent accesses don't have to wait for previous
// write to complete
//
// 3) Write 4 more long words to another address. Subsequent accesses will have
// to wait for all 3 writes
// Illustrate: the number of signals in in_wait_sigs is not limited to 2
//
// 4) Read all 8 long words at the location written before
//
////////////////////////////////////////////////////////////////////////////////////////
// Allocate buffer of Xfer registers
.reg $w_xfer0 $w_xfer1 $w_xfer2 $w_xfer3 $w_xfer4 $w_xfer5 $w_xfer6 $w_xfer7 \
$w_xfer8 $w_xfer9 $w_xfer10 $w_xfer11 \
$r_xfer0 $r_xfer1 $r_xfer2 $r_xfer3 $r_xfer4 $r_xfer5 $r_xfer6 $r_xfer7 \
$r_xfer8 $r_xfer9 $r_xfer10 $r_xfer11 \
base_addr
.xfer_order $r_xfer0 $r_xfer1 $r_xfer2 $r_xfer3 $r_xfer4 $r_xfer5 $r_xfer6 $r_xfer7 \
$r_xfer8 $r_xfer9 $r_xfer10 $r_xfer11
.xfer_order $w_xfer0 $w_xfer1 $w_xfer2 $w_xfer3 $w_xfer4 $w_xfer5 $w_xfer6 $w_xfer7 \
$w_xfer8 $w_xfer9 $w_xfer10 $w_xfer11
//Initilize write transfer registers
#define_eval INDEX 0
#define_eval TEST_VAL 0x11111111
#while (INDEX < 12)
immed32($w_xfer/**/INDEX/**/, TEST_VAL);
#define_eval INDEX (INDEX+1)
#define_eval TEST_VAL TEST_VAL*2
#endloop
immed32(base_addr, 0x1000);
alu[offset1, --, b, 0x10]
alu[offset2, --, b, 0x20]
//Task 1
scratch_write($w_xfer0, base_addr, offset1, 4, tmp_sig1, SIG_NONE, ___);
//Task 2
scratch_write($w_xfer4, base_addr, offset2, 4, tmp_sig2, SIG_NONE, ___);
//Task 3
alu[offset2, --, b, 0x40]
scratch_write($w_xfer8, base_addr, offset2, 4, tmp_sig3, signals(tmp_sig1, tmp_sig2, tmp_sig3), ___);
//Task 4
scratch_read($r_xfer0, base_addr, offset1, 8, tmp_sig4, SIG_NONE, ___);
scratch_read($r_xfer8, base_addr, offset2, 4, SIG_SRAM, signals(SIG_SRAM, tmp_sig4), ___);
//display the result using put_nv debug utility
#define_eval INDEX 0
#while (INDEX < 12)
put_nv(r/**/INDEX/**/, $r_xfer/**/INDEX/**/);
#define_eval INDEX (INDEX+1)
#endloop
.end
#endm
// ==================================================================
// This demonstrates the usage of SCRATCH macros
// ==================================================================
#macro scratch_examples_2
.begin
///////////////////////////////////////////////////////////////////////////////////////
// Example 3: This example shows the use of Scratch read/write macros. It illustrates the
// following points:
//
// 1) Allocate a transfer buffers with 16 registers
// 2) Write 6 long words (8 bytes) to a random base_addr and a random multiply-of-4
// offset in scratch memory. Subsequent writes don't have to wait for this
// write to complete
//
// 3) Write 6 other long words to another random location. This write will have
// to before the read in task 4
//
// 4) Read all 12 long words at the location written before
// Illustrate: - If we want to access more than 8 long words we must
// do indirect access (meaning the counts of words must be in
// general register)
////////////////////////////////////////////////////////////////////////////////////////
// Allocate buffer of Xfer registers
.reg base_addr offset lw_count
xbuf_alloc($xfer1, 12, read_write)
#define_eval INDEX 0
#while (INDEX < 12)
immed32($xfer1[/**/INDEX/**/], INDEX);
#define_eval INDEX (INDEX+1)
#endloop
immed32(base_addr, 0x1000);
alu[offset1, --, b, 0x0]
alu[offset2, --, b, 0x20]
//Task 2
scratch_write($xfer1[0], base_addr, offset1, 6, tmp_sig1, SIG_NONE, ___);
//Task 3
scratch_write($xfer1[6], base_addr, offset2, 6, tmp_sig3, signals(tmp_sig1, tmp_sig3), ___);
//Task 4
alu[lw_count, --, b, 12]
scratch_read($xfer1[0], base_addr, offset1, lw_count, tmp_sig2, tmp_sig2, ___);
#define_eval INDEX (0)
#while (INDEX < 12)
put_nv(x/**/INDEX/**/, $xfer1[/**/INDEX/**/]);
#define_eval INDEX (INDEX+1)
#endloop
// Free buffer of Xfer registers
xbuf_free($xfer1);
///////////////////////////////////////////////////////////////////////////////////////
// Example 4: This example shows the use of Scratch_bits_clr and scratch_bits_set macro
//
// Illustrate: uasge of the mask:
// + each binary digit in the mask correspond to a bit in the
// data to be cleared or set
//
////////////////////////////////////////////////////////////////////////////////////////
.reg $w_xfer0 $r_xfer0
immed32($w_xfer0, 0xfffffffe);
alu[base_addr, --, b, 32]
scratch_write($w_xfer0, base_addr, 0, 1, tmp_sig1, tmp_sig1, ___);
scratch_bits_clr(0xf0, base_addr, 0, tmp_sig1, tmp_sig1, ___);
scratch_bits_set(0x1, base_addr, 0, tmp_sig2, tmp_sig2, ___);
scratch_read($r_xfer0, base_addr, 0, 1, tmp_sig1, tmp_sig1, ___);
//print expected result: 0xffffff0f
put_nv(result, $r_xfer0);
///////////////////////////////////////////////////////////////////////////////////////
// Example 4: This example shows the use of Scratch_bits_test_and_clr and
// scratch_bits_test_and_set macro
//
// Illustrate:
// - uasge of the mask: similar to in scratch_bits_clr and
// scratch_bits_set
// - besides clearing/setting the bits specified in the masks,
// the original value is saved in the out_data operand
//
////////////////////////////////////////////////////////////////////////////////////////
.reg $org_data $immed_result $test_result mask1 mask2
immed32($org_data, 0x12345678);
immed32(mask1, 0xff00);
immed32(mask2, 0x71000000);
alu[base_addr, --, b, 0x64]
alu[offset, --, b, 0x8]
scratch_write($org_data, base_addr, offset, 1, tmp_sig1, tmp_sig1, ___);
scratch_bits_test_and_clr($immed_result, mask1, base_addr, offset, tmp_sig2, tmp_sig2, ___);
scratch_bits_test_and_set($test_result, mask2, base_addr, offset, tmp_sig2, tmp_sig2, ___);
scratch_read($result, base_addr, offset, 1, tmp_sig1, tmp_sig1, ___);
// print expected value: 0x12345678
put_nv(org, $immed_result);
// print 0x12340078
put_nv(immediate, $test_result);
//print 0x73340078
put_nv(result, $result);
.end
#endm
// ==================================================================
// This demonstrates the usage of SRAM macros
// ==================================================================
#macro dram_examples
.begin
.sig tmp_sig5 SIG_DRAM
///////////////////////////////////////////////////////////////////////////////////////
// Example 1: This example shows the usage of DRAM read/write macros. It illustrates the
// following points via diffrent tasks:
//
// 1) Allocate a transfer buffers of 16 registers
// Illustrate: Each DRAM access is a quad word (8 bytes). Each DRAM transfer register is
// 4-byte long. So, for 8 DRAM accesses, you need 16 DRAM registers
//
// 2) 2 writes, each writes 2 quad words to a random base and a random multiply-of-8
// offset in DRAM memory. Subsequent writes don't have to wait for previous
// writes to complete
// Illustrate: - Offsets of all DRAM accesses must be multiple of 8
// - The unit of access for DRAM memory is quad words (8 bytes)
// - DRAM accesses always have to use signal with even number
// but the assembler takes care of that
// - Usage of SIG_NONE for accesses that can happen in parallel
//
// 3) Write another 2 words to another random location. This write will have
// to finish before the read in task 4
// Illustrate: - Usage of signals to make sure an access is finished before
// next accesses
// - Name can be in capital as SIG_DRAM. This name is similar to
// naming conmvention in IXP1200 macros, if any users used this before
// - The number of signals doesn't have to be 2
//
// 4) Read all 6 quad words at the location written before
//
////////////////////////////////////////////////////////////////////////////////////////
.reg $$wreg0 $$wreg1 $$wreg2 $$wreg3 $$wreg4 $$wreg5 $$wreg6 $$wreg7 \
$$wreg8 $$wreg9 $$wreg10 $$wreg11 \
$$rreg0 $$rreg1 $$rreg2 $$rreg3 $$rreg4 $$rreg5 $$rreg6 $$rreg7 \
$$rreg8 $$rreg9 $$rreg10 $$rreg11 \
base_addr
.xfer_order $$wreg0 $$wreg1 $$wreg2 $$wreg3 $$wreg4 $$wreg5 $$wreg6 $$wreg7 \
$$wreg8 $$wreg9 $$wreg10 $$wreg11
.xfer_order $$rreg0 $$rreg1 $$rreg2 $$rreg3 $$rreg4 $$rreg5 $$rreg6 $$rreg7 \
$$rreg8 $$rreg9 $$rreg10 $$rreg11
#define_eval TEST_VAL 0x11111111
#define_eval INDEX 0
#while (INDEX < 12)
immed32($$wreg/**/INDEX/**/, TEST_VAL);
#define_eval INDEX (INDEX+1)
#define_eval TEST_VAL TEST_VAL*2
#endloop
alu[base_addr, --, b, 0]
//since tmp_sig1, tmp)_sig2, tmp_sig3, tmp_sig5 are used for DRAM accesses,
//the assembler will assigned even-numbered signals to them. Also, the odd-numbered
//signals corresponding to them will be reserved and used
dram_write($$wreg0, base_addr, 0x10, 2, tmp_sig1, SIG_NONE, ___);
dram_write($$wreg4, base_addr, 0x20, 2, tmp_sig2, SIG_NONE, ___);
dram_write($$wreg8, base_addr, 0x30, 2, tmp_sig4, signals(tmp_sig1,tmp_sig2,tmp_sig4), ___);
dram_read($$rreg0, base_addr, 0x10, 6, SIG_DRAM, SIG_DRAM, ___);
#define_eval INDEX (0)
#while (INDEX < 12)
put_nv(wr/**/INDEX/**/, $$rreg/**/INDEX/**/);
#define_eval INDEX (INDEX+1)
#endloop
///////////////////////////////////////////////////////////////////////////////////////
// Example 2: This example illutrates the usage of DRAM read/write and dram_mask_write
// macros. It illustrate the following points via different tasks:
//
// 1) Allocate a transfer buffers of 16 registers
// Illustrate: Each DRAM access is a quad word (8 bytes). Each DRAM transfer register is
// 4-byte long. So, for 8 DRAM accesses, you need 16 DRAM registers
//
// 2) 1 writes to a random base and a random multiply-of-8
// offset in DRAM memory. Subsequent instructions don't have to wait for
// the write to complete
// Illustrate: - Base can be random number -- doesn't have to be multiple of 8 as offset
// - Usage of one signal as both request signal and wait signal
//
// 3) A mask-write another 2 words to the same location
// Illustrate: - Usage of a mask:.
// + each bit in the mask correspond to a byte. The order
// is from left to right
// + A 1 in the mask means the byte will be overwritten
// 4) Read the quad word at the location written before
//
////////////////////////////////////////////////////////////////////////////////////////
xbuf_alloc($$xfer, 4, read_write);
immed32($$xfer[0], 0xe8773dd3);
immed32($$xfer[1], 0x0f7357ef);
immed32($$xfer[2], 0x45118922);
immed32($$xfer[3], 0xad80fd90);
immed32(base_addr, 0x0838f766);
alu[offset, --, b, 0x20]
alu[mask, --, b, 0xf7]
dram_write($$xfer[0], base_addr, offset, 1, tmp_sig2, tmp_sig2, ___);
dram_mask_write($$xfer[2], base_addr, offset, mask, tmp_sig5, tmp_sig5, ___);
dram_read($$xfer[0], base_addr, offset, 1, tmp_sig3, tmp_sig3, ___);
//print 0xe8118922
put_nv(x0, $$xfer[0]);
//print 0xad80fd90
put_nv(x1, $$xfer[1]);
xbuf_free($$xfer);
.end
#endm
// ==================================================================
// This demonstrates the usage of CYCLE macros
// ==================================================================
#macro cycle_examples()
.begin
.reg out_cycle1 out_cycle2 out_diff
// sxfer reg to read and write misc_control reg
.reg $sxfer
.sig cap_sig
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -