📄 isp8asm.c
字号:
case 't':
nc = '\t';
break;
default:
break;
}
}
if (GETC() != '\'') {
error_exit("invalis character constant");
}
return nc;
}
/* parse constant */
static uint32 parse_const()
{
char nc;
char token[MAX_TOKEN_SIZE];
stab *esym;
nc = GETC();
UNGETC();
if (isdigit(nc) || nc == '+' || nc == '-') {
return parse_num();
}
if (nc == '\'') {
return parse_char();
}
if (nc == '$') {
GETC(); /* skip the $ */
return loc_counter;
}
/* must be an equate; lookit up */
get_token(token,"\n");
if (!(esym = sym_find(token,SYM_EQU))) {
error_exit("expected constant or equated symbol, found %s",
token);
}
return esym->value;
}
/* parse registers */
static uint32 parse_reg(uint32 maxreg)
{
char nc;
uint32 regno;
nc = skip_space();
if (toupper(nc) != 'R') {
error_exit("excpected register");
}
GETC(); /* skip r */
regno = parse_num();
if (regno >= maxreg) {
error_exit("invalid register number :"
" expected reg number < R%d",maxreg-1);
}
return regno;
}
/* parse instructions */
static int parse_instr()
{
char nc;
itab *itabp;
int ops = 0;
int fopcode = 0 ;
int rd = 0 , rb = 0 ;
uint32 konst = 0, port = 0;
stab *label = NULL;
nc = skip_space();
if (!nc) return 0;
nc = get_token(token,"\n:");
if (!isspace(nc)) {
UNGETC();
}
/* if next character is a ':' then this is
a label definition */
nc = skip_space();
if (nc == ':') {
parse_label_def(token);
return 1;
} else {
UNGETC();
}
if ((itabp = itab_find(token)) == NULL) {
error_exit("unrecognized instruction mnemonic '%s'",token);
return 0;
}
/* found instruction entry */
for (ops = 0 ; ops < itabp->nops ; ops++) {
switch (itabp->optypes[ops]) {
case OP_REGD:
rd = parse_reg(MAX_REG);
break;
case OP_REGB:
rb = parse_reg(MAX_REG);
break;
case OP_CONST:
konst = parse_const();
fopcode |= 1 << 13;
break;
case OP_LABEL:
label = parse_label_ref();
fopcode |= 1 << 13;
break;
case OP_PORT:
port = parse_const();
break;
}
/* if not last then separator must be present */
if (ops != (itabp->nops - 1)) {
nc = skip_space();
if (nc != ',') {
error_exit("expected ',' after first operand");
}
GETC();
nc = skip_space();
}
}
fopcode |= itabp->opcode;
fopcode |= (rd & 0x1f) << 8;
fopcode |= (rb & 0x1f) << 3;
fopcode |= (konst & 0xff);
fopcode |= (port & 0x01f) << 3;
code_insert(itabp, fopcode, rd, rb, konst, label, NULL, port, 0);
return 1;
}
/* go thru the code and resolve
all label references */
static void resolve_labels()
{
code *codep = croot;
while (codep) {
if (codep->label_ref) {
int diff;
if (codep->label_ref->loc_counter == -1) {
error_exit("undefined label %s",
codep->label_ref->name);
}
diff = (codep->label_ref->loc_counter - codep->loc_counter);
if ((codep->opcode == 0X00033000) || (codep->opcode == 0X00037000)) {
// unconditional branch/call
if ((diff > 2047) || (diff < -2048)) {
line_no = codep->line_no;
error_exit("branch out of range; must be"
" within +2047/-2048 instructions");
}
codep->opcode |= ((codep->label_ref->loc_counter -
codep->loc_counter) & 0xFFF);
}
else {
if ((diff > 511) || (diff < -512)) {
line_no = codep->line_no;
error_exit("branch out of range; must be"
" within +511/-512 instructions");
}
codep->opcode |= ((codep->label_ref->loc_counter -
codep->loc_counter) & 0x3FF);
}
}
codep = codep->next;
}
}
static void print18bits(uint32 val, FILE *of)
{
int i;
for (i = 0 ; i < 18; i++) {
fprintf(of,"%c", (val & (1 << 17)) ? '1' : '0');
val <<= 1;
}
}
static void print_listing(code *codep)
{
int i;
fprintf(lfile,"0x%04X\t",codep->loc_counter);
if (codep->flags & CODE_ISLDEF) {
fprintf(lfile,"\t%s:\n",codep->label_def->name);
return ;
}
fprintf(lfile,"0x%05X\t",codep->opcode);
print18bits(codep->opcode,lfile);
if (codep->flags & CODE_ISDATA) {
fprintf(lfile,"\t.data\t%d\n",codep->opcode);
return ;
}
fprintf(lfile,"\t%s\t",codep->itabp->opname);
for (i = 0 ; i < codep->itabp->nops; i++) {
switch (codep->itabp->optypes[i]) {
case OP_REGD:
fprintf(lfile,"R%02d",codep->rd);
break;
case OP_REGB:
fprintf(lfile,"R%02d",codep->rb);
break;
case OP_CONST:
fprintf(lfile,"0x%02X",codep->konst & 0xff);
break;
case OP_LABEL:
fprintf(lfile,"%s",codep->label_ref->name);
break;
case OP_PORT:
fprintf(lfile,"#%d",codep->port);
break;
}
/* if not last then separator must be present */
if (i != (codep->itabp->nops - 1)) {
fprintf(lfile,",");
}
}
fprintf(lfile,"\n");
}
static void print_code(int opcode)
{
if (omode == OBIN) {
print18bits(opcode,ofile);
fprintf(ofile,"\n");
} else if (omode == OHEX) {
fprintf(ofile,"%05X\n",opcode);
} else {
// push it into the stack , printed later
// in output_code()
vmstack[vmsp++] = opcode;
}
}
static void output_verilog()
{
int i, j;
if (vmsp % 16) {
error_exit("prom size must be multiple of 16. %d",vmsp - 1);
}
fprintf(ofile,"`ifdef INIT_DEFPARAM\n");
// output def param first
for (i = 0, j = 0; i < vmsp; i += 16 ) {
int k;
fprintf(ofile,"\tdefparam prom_0_0_0.INITVAL_%02X = 320'h",j);
for (k = i+15 ; k >= i ; k--) {
fprintf(ofile,"%05X",vmstack[k]);
}
fprintf(ofile,";\n");
j++;
}
fprintf(ofile,"`endif\n");
fprintf(ofile,"`ifdef INIT_SYNTHESIS\n");
// synthesis initvals
for (i = 0, j = 0; i < vmsp; i += 16 ) {
int k;
fprintf(ofile,"\t/* synthesis INITVAL_%02X=\"0x",j);
for (k = i+15 ; k >= i ; k--) {
fprintf(ofile,"%05X",vmstack[k]);
}
fprintf(ofile,"\" */\n");
j++;
}
fprintf(ofile,"`endif\n");
// exemplar initvals
fprintf(ofile,"`ifdef INIT_EXEMPLAR\n");
for (i = 0, j = 0; i < vmsp; i += 16 ) {
int k;
fprintf(ofile,"\t// exemplar attribute prom_0_0_0 INITVAL_%02X ",j);
for (k = i+15 ; k >= i ; k--) {
fprintf(ofile,"%05X",vmstack[k]);
}
fprintf(ofile,"\n");
j++;
}
fprintf(ofile,"`endif\n");
// synplicity bug patch edif file
if (eifile && eofile) {
static char ebuff[MAX_LINE_SIZE];
char *neof = NULL;
// copy to output file till first 'property INITVAL_" string
while ((neof = fgets(ebuff,MAX_LINE_SIZE,eifile))) {
if (strstr(ebuff,"property INITVAL_")) break;
fputs(ebuff,eofile);
}
if (neof) {
for (i = 0, j = 0; i < vmsp; i += 16 ) {
int k;
fprintf(eofile,
"\t(property INITVAL_%02X (string \"0x",j);
for (k = i+15 ; k >= i ; k--) {
fprintf(eofile,"%05X",vmstack[k]);
}
fprintf(eofile,"\"))\n");
j++;
}
// skip thru rest of INITVALs
while (fgets(ebuff,MAX_LINE_SIZE,eifile)) {
if (strstr(ebuff,"property INITVAL_")) continue;
break;
}
// copy rest of it to output
do {
fputs(ebuff,eofile);
} while (fgets(ebuff,MAX_LINE_SIZE,eifile));
}
}
}
static void output_vhdl()
{
int i, j;
if (vmsp % 16) {
error_exit("prom size must be multiple of 16. %d",vmsp - 1);
}
/* attribute values */
fprintf(ofile,"library ieee;\n");
fprintf(ofile,"use ieee.std_logic_1164;\n");
fprintf(ofile,"package prominitpackage is\n");
for (i = 0, j = 0; i < vmsp; i += 16 ) {
int k;
fprintf(ofile,"\tconstant INITVAL_%02X_str : string := \"0x",j);
for (k = i+15 ; k >= i ; k--) {
fprintf(ofile,"%05X",vmstack[k]);
}
fprintf(ofile,"\";\n");
j++;
}
fprintf(ofile,"end prominitpackage;\n");
}
static void output_code()
{
code *codep ;
int last_lc = 0;
if (lfile) {
fprintf(lfile,"Loc\tOpcode\tOpcode\t\n");
fprintf(lfile,"Counter\t(Hex)\t(Bin)\n");
}
/* allocate space for vhdl/verilog init */
vmstack = (int *) malloc((sizeof(int))*prom_size);
for (codep = croot; codep; codep = codep->next) {
if (lfile) {
print_listing(codep);
}
if (codep->flags & CODE_ISLDEF) continue;
if ((codep->loc_counter - last_lc) > 1) {
/* fill with zero */
while ((codep->loc_counter - 1) > last_lc) {
last_lc++;
print_code(0);
}
}
print_code(codep->opcode);
last_lc = codep->loc_counter;
}
/* fill the rest of program rom with zeros */
for (;last_lc < prom_size - 1; last_lc++) {
print_code(0);
}
if (omode == OVER) {
output_verilog();
} else if (omode == OVHD) {
output_vhdl();
}
}
static void parse_line()
{
char nc;
nc = skip_space();
if (nc == COMMENT_CHAR) return ;
if (nc == '\n') return;
GETC();
/* must be something recognizable.
instruction or directive */
if (nc == '.') {
parse_direct();
} else {
UNGETC();
parse_instr();
}
}
static void print_usage(char *pname)
{
printf("%s Usage : [options] input-file-name\n", pname);
printf("options:\n");
printf("\t[-o <filename>] : output filename (default STDOUT)\n");
printf("\t[-s <size>] : program rom size (default 512)\n");
printf("\t[-l <filename>] : generate assembler listing\n");
printf("\t[-vx] : output hexadecimal data(default)\n");
printf("\t[-vb] : output binary data\n");
printf("\t[-vm] : output Lattice memory format\n");
printf("\t[-ve] : output verilog init format\n");
printf("\t[-vh] : output vhdl init format>\n");
printf("\t-? <this message>\n");
}
int main(int argc, char *argv[])
{
int i;
if (argc < 1 ) {
print_usage(argv[0]);
exit(-1);
}
for (i = 1 ; i < argc; i++) {
if (argv[i][0] == '-') {
switch(argv[i][1]) {
case 'o':
i++;
ofilename = strdup(argv[i]);
break;
case 'l':
i++;
lfilename = strdup(argv[i]);
lgen = 1;
break;
case 's':
i++;
sscanf(argv[i],"%d",&prom_size);
break;
case 'v':
switch (argv[i][2]) {
case 'x':
omode = OHEX;
break;
case 'b':
omode = OBIN;
break;
case 'e':
omode = OVER;
break;
case 'h':
omode = OVHD;
break;
default:
fprintf(stderr,
"invalid output option\n"
"\t-vx - hex, -vb binary, -vh - vhdl, -ve verilog\n");
}
break;
case 'e':
switch (argv[i][2]) {
case 'i':
i++;
if (!(eifile=fopen(argv[i],"r"))) {
fprintf(stderr,"cannot open input edif file\n");
exit(-1);
}
break;
case 'o':
i++;
if (!(eofile=fopen(argv[i],"w"))) {
fprintf(stderr,"cannot open output edif file\n");
exit(-1);
}
break;
}
break;
case '?':
print_usage(argv[0]);
exit(0);
break;
default:
fprintf(stderr,"invalid option %s\n",argv[i]);
print_usage(argv[0]);
break;
}
} else {
/* assume it is the input file */
ifilename = (char *) strdup(argv[i]);
if (!(infile = fopen(ifilename,"r"))) {
error_exit("unable to open file %s\n",ifilename);
}
}
}
if ((eifile && !eifile) || (!eifile && eofile)) {
fprintf(stderr,"both input and output edif files must be provided\n");
exit(-1);
}
if (!ifilename) {
fprintf(stderr,"input file name missing\n");
print_usage(argv[0]);
exit(-1);
}
if (ofilename) {
if (!(ofile=fopen(ofilename,"w"))) {
error_exit("unable to open output file %s",ofilename);
}
} else {
ofile = stdout;
}
if (lgen) {
if (!(lfile=fopen(lfilename,"w"))) {
error_exit("unable to open listing file %s",lfilename);
}
} else {
lfile = NULL;
}
while (get_line()) {
parse_line();
}
resolve_labels();
output_code();
if (lfile) fclose(lfile);
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -