8051-based Galois-Field Multipler for ARM
From Gezel2
This shows an example of an 8051 - running a Galois-Field Multiplication Algorithm - connected to an ARM. GEZEL is used to implement the communication channels between the two.
mpsoc.fdl
This design instantiates the ARM, the 8051, and the communication channels between the two.
ipblock my8051a {
iptype "i8051system";
ipparm "exec=slave51.ihx";
ipparm "verbose=1";
ipparm "period=1";
}
ipblock my8051a_P0(in data : ns(8)) {
iptype "i8051systemsink";
ipparm "core=my8051a";
ipparm "port=P0";
}
ipblock my8051a_P1(out data : ns(8)) {
iptype "i8051systemsource";
ipparm "core=my8051a";
ipparm "port=P1";
}
ipblock my8051a_P2(in data : ns(8)) {
iptype "i8051systemsink";
ipparm "core=my8051a";
ipparm "port=P2";
}
ipblock my8051a_P3(out data : ns(8)) {
iptype "i8051systemsource";
ipparm "core=my8051a";
ipparm "port=P3";
}
ipblock myarm {
iptype "armsystem";
ipparm "exec=drivearm";
ipparm "verbose=0";
ipparm "period=1";
}
ipblock myarm_P0(in data : ns(32)) {
iptype "armsystemsink";
ipparm "core=myarm";
ipparm "address=0x80000000";
}
ipblock myarm_P1(out data : ns(32)) {
iptype "armsystemsource";
ipparm "core=myarm";
ipparm "address=0x80000004";
}
ipblock myarm_P2(in data : ns(32)) {
iptype "armsystemsink";
ipparm "core=myarm";
ipparm "address=0x80000008";
}
ipblock myarm_P3(out data : ns(32)) {
iptype "armsystemsource";
ipparm "core=myarm";
ipparm "address=0x8000000C";
}
dp sys {
sig d0a, d1a, d2a, d3a : ns(8);
sig d0, d1, d2, d3 : ns(32);
use my8051a;
use my8051a_P0 (d0a); // in
use my8051a_P1 (d1a); // out
use my8051a_P2 (d2a); // in
use my8051a_P3 (d3a); // out
use myarm;
use myarm_P0 (d0);
use myarm_P1 (d1);
use myarm_P2 (d2);
use myarm_P3 (d3);
always {
d0a = d1;
d0 = d1a;
d2a = d3;
d2 = d3a;
}
}
system S {
sys;
}
slave51.c
The Galois-Field Multiplication Algorithm for 8051.
// Galois Field Multiplier Design for 8051
// (c) David Hwang (dhwang@ee.ucla.edu)
#include <8051.h>
typedef unsigned char uchar;
#define WORDMSB 0x80
#define SEGS 11
uchar a[] ={0x04,0xd0,0x03,0xee,0xf0,0xda,0x0e,0x00,0x00,0x00,0x00} ;
uchar b[] ={0x03,0xf0,0x03,0x0f,0x79,0x5a,0x0e,0x0f,0x20,0x00,0x02} ;
uchar c[] ={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} ;
void shift_left_copy(char l, uchar in[], uchar out[]) {
// plain old shift left of entire data copies in into out
char i;
char word_msb = 0;
char word_lsb = 0;
// shift left, making sure of boundaries between words
for (i=l-1;i>=0;i--) {
if ((in[(uchar)i] & WORDMSB) == WORDMSB)
word_msb = 1;
else
word_msb = 0;
out[(uchar)i] = in[(uchar)i] << 1;
out[(uchar)i] = out[(uchar)i] ^ word_lsb;
word_lsb = word_msb;
}
}
void shift_left_times (char l, uchar in[], char times) {
// plain old shift left of entire data a specified number of times
char i,j;
char word_msb = 0;
char word_lsb = 0;
for (j=1;j<=times;j++) {
word_lsb = 0;
// shift left, making sure of boundaries between words
for (i=l-1;i>=0;i--) {
if ((in[i] & WORDMSB) == WORDMSB)
word_msb = 1;
else
word_msb = 0;
in[i] = in[i] << 1;
in[i] = in[i] ^ word_lsb;
word_lsb = word_msb;
}
}
}
void gf_mul_comb_win_red (uchar a[], uchar b[], uchar c[]) {
// WINDOW = 2 bits
char k,j;
uchar i;
uchar b_shift[SEGS];
uchar b3[SEGS];
uchar c_long[2*SEGS];
uchar temp;
for (i=0;i<2*SEGS;i++)
c_long[i] = 0;
shift_left_copy(SEGS,b,b_shift);
for (i=0;i<SEGS;i++)
b3[i] = b[i] ^ b_shift[i];
for (k=0; k<=3; k++) { // 3 is WORD/WINDOW -1 = 8/2 -1
for (j=SEGS-1; j>=0; j--) {
temp = a[j] & (0xC0 >> (2*k));
temp = temp >> (2*(3-k));
if ( temp == 0x3) {
for (i=j+1; i<=j+SEGS; i++)
c_long[i] = c_long[i] ^ b3[(uchar)(i-j-1)];
}
else if (temp == 0x02) {
for (i=j+1; i<=j+SEGS; i++)
c_long[i] = c_long[i] ^ b_shift[(uchar)(i-j-1)];
}
else if (temp == 0x01) {
for (i=j+1; i<=j+SEGS; i++)
c_long[i] = c_long[i] ^ b[(uchar)(i-j-1)];
}
}
if (k!=3) {
shift_left_times(2*SEGS,c_long,2);
}
}
for (i=1;i<=10;i++) {
temp = c_long[i];
c_long[i+9] = c_long[i+9] ^ (temp>>4) ^ (temp>>7);
c_long[i+10] = c_long[i+10] ^ (temp<<4) ^ (temp<<1) ^ (temp>>1) ^ (temp>>3);
c_long[i+11] = c_long[i+11] ^ (temp<<7) ^ (temp<<5);
}
temp = c_long[11] & 0xF8;
c_long[20] = c_long[20] ^ (temp>>4) ^ (temp>>7);
c_long[21] = c_long[21] ^ (temp<<4) ^ (temp<<1) ^ (temp>>1) ^ (temp>>3);
c_long[11] = c_long[11] & 0x07;
for (i=0;i<=10;i++)
c[i] = c_long[11+i];
}
//-----------------------------------------------------
//
// Communication support
//
//-----------------------------------------------------
void synchronize() {
P3 = 0;
while (P2) ;
}
uchar sync_slave(uchar v) {
uchar r;
while (P2 == 0) ;
r = P0;
P1 = v;
P3 = 1;
return r;
}
void receive_seg(uchar n[]) {
char i;
for ( i=0 ; i<SEGS ; i++ ) {
n[i] = sync_slave(1);
synchronize();
}
}
void send_seg(uchar n[]) {
char i;
uchar r;
for (i=0 ; i<SEGS ; i++ ) {
r = sync_slave(n[i]);
synchronize();
}
}
int main() {
synchronize();
receive_seg(a);
receive_seg(b);
gf_mul_comb_win_red(a, b, c);
send_seg(c);
P3 = 0x55;
return 0;
}
