OpenCores
URL https://opencores.org/ocsvn/ssbcc/ssbcc/trunk

Subversion Repositories ssbcc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 3 to Rev 4
    Reverse comparison

Rev 3 → Rev 4

/ssbcc/trunk/macros/9x8/pushByte.py
29,4 → 29,5
printValue = argument[0]['value'] if type(argument[0]['value']) == str else '0x%X' % argument[0]['value'];
printIx = argument[1]['value'] if type(argument[1]['value']) == str else '0x%X' % argument[1]['value'];
ad.EmitPush(fp,v,'.pushByte(%s,%s)' % (printValue,printIx,));
 
ad.EmitFunction['.pushByte'] = emitFunction;
/ssbcc/trunk/macros/9x8/push32.py
19,24 → 19,13
# Define the macro functionality.
def emitFunction(ad,fp,argument):
argument = argument[0];
if argument['type'] == 'value':
v = argument['value'];
elif argument['type'] == 'symbol':
name = argument['value'];
if not ad.IsSymbol(name):
raise asmDef.AsmException('Symbol "%s" not recognized at %s' % (argument['value'],argument['loc'],));
ix = ad.symbols['list'].index(name);
v = ad.symbols['body'][ix];
if len(v) != 1:
raise asmDef.AsmException('Argument can only be one value at %s' % argument['loc']);
v = v[0];
else:
raise asmDef.AsmException('Argument "%s" of type "%s" not recognized at %s' % (argument['value'],argument['type'],argument['loc'],));
if type(v) != int:
raise Exception('Program Bug -- value should be an "int"');
ad.EmitPush(fp,v%0x100,''); v >>= 8;
ad.EmitPush(fp,v%0x100,''); v >>= 8;
ad.EmitPush(fp,v%0x100,''); v >>= 8;
printValue = argument['value'] if type(argument['value']) == str else '0x%08X' % argument['value'];
ad.EmitPush(fp,v%0x100,'.push32(%s)' % printValue);
v = ad.Emit_IntegerValue(argument);
if not (-2**31 <= v < 2**32):
raise asmDef.AsmException('Argument "%s" should be a 32-bit integer at %s' % (argument['value'],argument['loc'],));
printString = argument['value'] if type(argument['value']) == str else '0x%04X' % (v % 2**32);
for ix in range(4-1):
ad.EmitPush(fp,v%0x100,'');
v >>= 8;
ad.EmitPush(fp,v%0x100,'.push32(%s)' % printString);
 
ad.EmitFunction['.push32'] = emitFunction;
/ssbcc/trunk/macros/9x8/push24.py
0,0 → 1,31
# Copyright 2014, Sinclair R.F., Inc.
 
def push24(ad):
"""
User-defined macro to push a 24 bit value onto the data stack so that the LSB
is deepest in the data stack and the MSB is at the top of the data stack.
Usage:
.push24(v)
where
v is a 24-bit value, a constant, or an evaluated expression\n
The effect is to push v%0x100, int(v/2**8)%0x100, and int(v/2**16)%0x100 onto
the data stack.\n
( - u_LSB u u_MSB )
"""
 
# Add the macro to the list of recognized macros.
ad.AddMacro('.push24', 3, [ ['','singlevalue','symbol'] ]);
 
# Define the macro functionality.
def emitFunction(ad,fp,argument):
argument = argument[0];
v = ad.Emit_IntegerValue(argument);
if not (-2**23 <= v < 2**24):
raise asmDef.AsmException('Argument "%s" should be a 24-bit integer at %s' % (argument['value'],argument['loc'],));
printString = argument['value'] if type(argument['value']) == str else '0x%04X' % (v % 2**24);
for ix in range(3-1):
ad.EmitPush(fp,v%0x100,'');
v >>= 8;
ad.EmitPush(fp,v%0x100,'.push24(%s)' % printString);
 
ad.EmitFunction['.push24'] = emitFunction;
/ssbcc/trunk/macros/9x8/push16.py
9,7 → 9,7
where
v is a 16-bit value, a constant, or an evaluated expression\n
The effect is to push v%0x100 and int(v/2**8)%0x100 onto the data stack.\n
( - u_LSB u u u_MSB )
( - u_LSB u_MSB )
"""
 
# Add the macro to the list of recognized macros.
18,22 → 18,12
# Define the macro functionality.
def emitFunction(ad,fp,argument):
argument = argument[0];
if argument['type'] == 'value':
v = argument['value'];
elif argument['type'] == 'symbol':
name = argument['value'];
if not ad.IsSymbol(name):
raise asmDef.AsmException('Symbol "%s" not recognized at %s' % (argument['value'],argument['loc'],));
ix = ad.symbols['list'].index(name);
v = ad.symbols['body'][ix];
if len(v) != 1:
raise asmDef.AsmException('Argument can only be one value at %s' % argument['loc']);
v = v[0];
else:
raise asmDef.AsmException('Argument "%s" of type "%s" not recognized at %s' % (argument['value'],argument['type'],argument['loc'],));
if type(v) != int:
raise Exception('Program Bug -- value should be an "int"');
ad.EmitPush(fp,v%0x100,''); v >>= 8;
printValue = argument['value'] if type(argument['value']) == str else '0x%08X' % argument['value'];
ad.EmitPush(fp,v%0x100,'.push16(%s)' % printValue);
v = ad.Emit_IntegerValue(argument);
if not (-2**15 <= v < 2**16):
raise asmDef.AsmException('Argument "%s" should be a 16-bit integer at %s' % (argument['value'],argument['loc'],));
printString = argument['value'] if type(argument['value']) == str else '0x%04X' % (v % 2**16);
ad.EmitPush(fp,v%0x100,'');
v >>= 8;
ad.EmitPush(fp,v%0x100,'.push16(%s)' % printString);
 
ad.EmitFunction['.push16'] = emitFunction;
/ssbcc/trunk/lib/9x8/deprecated/math.s
0,0 → 1,62
; Copyright 2012, Sinclair R.F., Inc.
;
; Multi-byte arithmetic
 
; Notation: Multi-byte values on the stack are xx[n] where n=0 is the least
; significant byte of the value
 
.function add_u16_u8__u16 ; ( u0[0] u0[1] u1[0] - us[0] us[1] )
swap >r +uu r> +
.return
 
.function add_u16_u8__u24 ; ( u0[0] u0[1] u1[0] - us[0] us[1] us[2] )
swap >r +uu r> +uu
.return
 
.function add_u16_u16__u16 ; ( u0[0] u0[1] u1[0] u1[1] - us[0] us[1] )
>r .call(add_u16_u8__u16) r> +
.return
 
.function add_u16_u16__u24 ; ( u0[0] u0[1] u1[0] u1[1] - us[0] us[1] us[2] )
>r .call(add_u16_u8__u24) r> .call(add_u16_u8__u16)
.return
 
.function add_u24_u8__u24 ; ( u0[0] u0[1] u0[2] u1[0] - us[0] us[1] us[2] )
swap >r .call(add_u16_u8__u24) r> +
.return
 
.function add_u24_u8__u32 ; ( u0[0] u0[1] u0[2] u1[0] - us[0] us[1] us[2] u[3] )
swap >r .call(add_u16_u8__u24) r> +uu
.return
 
.function add_u24_u16__u24 ; ( u0[0] u0[1] u0[2] u1[0] u1[1] - us[0] us[1] us[2] )
>r .call(add_u24_u8__u24) r> .call(add_u16_u8__u16)
.return
 
.function add_u24_u16__u32 ; ( u0[0] u0[1] u0[2] u1[0] u1[1] - us[0] us[1] us[2] us[3] )
>r .call(add_u24_u8__u32) r> .call(add_u24_u8__u24)
.return
 
.function add_u24_u24__u24 ; ( u0[0] u0[1] u0[2] u1[0] u1[1] u1[2] - us[0] us[1] us[2] )
>r .call(add_u24_u16__u24) r> +
.return
 
.function add_u24_u24__u32 ; ( u0[0] u0[1] u0[2] u1[0] u1[1] u1[2] - us[0] us[1] us[2] us[3] )
>r .call(add_u24_u16__u32) r> .call(add_u16_u8__u16)
.return
 
.function add_u32_u8__u32 ; ( u0[0] u0[1] u0[2] u0[3] u1[0] - us[0] us[1] us[2] us[3] )
swap >r .call(add_u24_u8__u32) r> +
.return
 
.function add_u32_u16__u32 ; ( u0[0] u0[1] u0[2] u0[3] u1[0] u1[1] - us[0] us[1] us[2] us[3] )
>r .call(add_u32_u8__u32) r> .call(add_u24_u8__u24)
.return
 
.function add_u32_u24__u32 ; ( u0[0] u0[1] u0[2] u0[3] u1[0] u1[1] u1[2] - us[0] us[1] us[2] us[3] )
>r .call(add_u32_u16__u32) r> .call(add_u16_u8__u16)
.return
 
.function add_u32_u32__u32 ; ( u0[0] u0[1] u0[2] u0[3] u1[0] u1[1] u1[2] u1[3] - us[0] us[1] us[2] us[3] )
>r .call(add_u32_u24__u32) r> +
.return
/ssbcc/trunk/lib/9x8/tb/.gitignore
1,6 → 1,5
ssbcc
tb
uc.9x8
uc.9x8-meta
uc.v
*.mem
/ssbcc/trunk/lib/9x8/tb/math/tb.gtkw
0,0 → 1,37
[*]
[*] GTKWave Analyzer v3.3.42 (w)1999-2012 BSI
[*] Mon Mar 24 17:27:25 2014
[*]
[dumpfile] "/home/rsinclair/Projects/SSBCC/lib/9x8/tb/math/tb.vcd"
[dumpfile_mtime] "Mon Mar 24 17:22:21 2014"
[dumpfile_size] 54584
[savefile] "/home/rsinclair/Projects/SSBCC/lib/9x8/tb/math/tb.gtkw"
[timestart] 593900
[size] 1920 1171
[pos] -1 -1
*-15.400721 750000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] tb.
[sst_width] 205
[signals_width] 223
[sst_expanded] 1
[sst_vpaned_height] 353
@28
tb.inst_uc.i_clk
tb.inst_uc.i_rst
@23
tb.inst_uc.s_R_stack_ptr[4:0]
@22
>10000
tb.inst_uc.s_PC[9:0]
>10000
tb.inst_uc.s_opcode[8:0]
@820
>0
tb.inst_uc.s_opcode_name[23:0]
@22
tb.inst_uc.s_R[9:0]
tb.inst_uc.s_T[7:0]
tb.inst_uc.s_N[7:0]
tb.inst_uc.s_Np_stack_ptr[6:0]
[pattern_trace] 1
[pattern_trace] 0
/ssbcc/trunk/lib/9x8/tb/math/run
0,0 → 1,18
#!/bin/bash
# Copyright 2013, Sinclair R.F., Inc.
# Run the test benches for the libraries.
 
NAME="math";
 
rm --force ssbcc;
ln -s ../../../../ssbcc;
 
./ssbcc -q -P monitor_stack --display-opcode uc.9x8 || { echo "FATAL ERROR testing ${NAME}" > /dev/stderr; exit 1; }
iverilog -o tb tb.v uc.v || exit 1;
if [ -n "`./tb | gawk -f tb.awk`" ]; then
echo "${NAME} failed" > /dev/stderr;
exit 1;
fi
echo "Passed: ${NAME}";
 
#rm --force ssbcc uc.9x8-meta uc.v tb;
ssbcc/trunk/lib/9x8/tb/math/run Property changes : Added: svn:executable ## -0,0 +1 ## +* \ No newline at end of property Index: ssbcc/trunk/lib/9x8/tb/math/tb.awk =================================================================== --- ssbcc/trunk/lib/9x8/tb/math/tb.awk (nonexistent) +++ ssbcc/trunk/lib/9x8/tb/math/tb.awk (revision 4) @@ -0,0 +1,8 @@ +/^VCD/{ next; } +{ + a=strtonum("0x" $1); + b=strtonum("0x" $3); + c=strtonum("0x" $5); + if (c != a + b) + print $0; +}
ssbcc/trunk/lib/9x8/tb/math/tb.awk Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: ssbcc/trunk/lib/9x8/tb/math/uc.s =================================================================== --- ssbcc/trunk/lib/9x8/tb/math/uc.s (nonexistent) +++ ssbcc/trunk/lib/9x8/tb/math/uc.s (revision 4) @@ -0,0 +1,146 @@ +; Copyright 2014, Sinclair R.F., Inc. +; Test bench for ../../math.s + +.include math.s + +.macro push16 +.macro push24 +.macro push32 + +.main + + ; Test u8 + u8 ==> u16 + 0x7F 0x80 + 0x7F 0x81 + 0x80 0x7F + 0x80 0x80 + 0x80 0x81 + 0xFF 0x00 + 0xFF 0x01 + 0xFF 0x02 + 0xFF 0xFE + 0xFF 0xFF + ${10-1} :loop__u8_u8_u16 >r + .call(out8,over) + .call(out8,dup) + .call(math__add_u8_u8_u16) .call(out16) + .outstrobe(O_VALUE_DONE) + r> .jumpc(loop__u8_u8_u16,1-) drop + + .push16(0x007F) 0x80 + .push16(0x007F) 0x81 + .push16(0x0080) 0x7F + .push16(0x0080) 0x80 + .push16(0x0080) 0x81 + .push16(0x00FF) 0x00 + .push16(0x00FF) 0x01 + .push16(0x00FF) 0x02 + .push16(0x00FF) 0xFE + .push16(0x00FF) 0xFF + .push16(0x017F) 0x80 + .push16(0x017F) 0x81 + .push16(0x0180) 0x7F + .push16(0x0180) 0x80 + .push16(0x0180) 0x81 + .push16(0x01FF) 0x00 + .push16(0x01FF) 0x01 + .push16(0x01FF) 0x02 + .push16(0x01FF) 0xFE + .push16(0x01FF) 0xFF + ${20-1} :loop__u16_u8_u16 >r + >r over .call(out16,over) + r> .call(out8,dup) + .call(math__add_u16_u8_u16) .call(out16) + .outstrobe(O_VALUE_DONE) + r> .jumpc(loop__u16_u8_u16,1-) drop + + .push24(0x0001FF) 0xFF + ${1-1} :loop__u24_u8_u24 >r + >r .call(preserve_out24) r> + .call(out8,dup) + .call(math__add_u24_u8_u24) + .call(out24) + .outstrobe(O_VALUE_DONE) + r> .jumpc(loop__u24_u8_u24,1-) drop + + .push24(0x0001FF) 0xFF + ${1-1} :loop__u24_u8_u32 >r + >r .call(preserve_out24) r> + .call(out8,dup) + .call(math__add_u24_u8_u32) + .call(out32) + .outstrobe(O_VALUE_DONE) + r> .jumpc(loop__u24_u8_u32,1-) drop + + .push32(0x00800000) 0xFF + ${1-1} :loop__u32_u8_u32 >r + >r .call(preserve_out32) r> + .call(out8,dup) + .call(math__add_u32_u8_u32) + .call(out32) + .outstrobe(O_VALUE_DONE) + r> .jumpc(loop__u32_u8_u32,1-) drop + + .push32(${0x00800000+0*1280*960*4}) .push24(${1280*960*4}) + .push32(${0x00800000+1*1280*960*4}) .push24(${1280*960*4}) + .push32(${0x00800000+2*1280*960*4}) .push24(${1280*960*4}) + .push32(${0x00800000+3*1280*960*4}) .push24(${1280*960*4}) + .push32(${0x00800000+4*1280*960*4}) .push24(${1280*960*4}) + ${5-1} :loop__u32_u24_u32 >r + >r >r >r .call(preserve_out32) r> r> r> + .call(preserve_out24) + .call(math__add_u32_u24_u32) + .call(out32) + .outstrobe(O_VALUE_DONE) + r> .jumpc(loop__u32_u24_u32,1-) drop + + .push32(${0x00800000+0*1280*960*4}) .push32(${1280*960*4}) + .push32(${0x00800000+1*1280*960*4}) .push32(${1280*960*4}) + .push32(${0x00800000+2*1280*960*4}) .push32(${1280*960*4}) + .push32(${0x00800000+3*1280*960*4}) .push32(${1280*960*4}) + .push32(${0x00800000+4*1280*960*4}) .push32(${1280*960*4}) + ${5-1} :loop__u32_u32_u32 >r + >r >r >r >r .call(preserve_out32) r> r> r> r> + .call(preserve_out32) + .call(math__add_u32_u32_u32) + .call(out32) + .outstrobe(O_VALUE_DONE) + r> .jumpc(loop__u32_u32_u32,1-) drop + + ; terminate and wait forever + .outstrobe(O_TERMINATE) :infinite .jump(infinite) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +; +; Routines to output results. +; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +.function preserve_out24 + 0 .outport(O_VALUE) + .outport(O_VALUE,>r) + .outport(O_VALUE,>r) + O_VALUE outport + r> r> + .return + +.function preserve_out32 + .outport(O_VALUE,>r) + .outport(O_VALUE,>r) + .outport(O_VALUE,>r) + O_VALUE outport + r> r> r> + .return + +.function out8 + 0 0 0 .call(out32) .return + +.function out16 + 0 0 .call(out32) .return + +.function out24 + 0 .call(out32) .return + +.function out32 + ${4-1} :loop swap .outport(O_VALUE) .jumpc(loop,1-) drop + .return Index: ssbcc/trunk/lib/9x8/tb/math/tb.v =================================================================== --- ssbcc/trunk/lib/9x8/tb/math/tb.v (nonexistent) +++ ssbcc/trunk/lib/9x8/tb/math/tb.v (revision 4) @@ -0,0 +1,48 @@ +/******************************************************************************* + * + * Copyright 2014, Sinclair R.F., Inc. + * + * Test bench for the core/9x8 math library. + * + ******************************************************************************/ + +`timescale 1ns/1ps + +module tb; + +reg s_clk = 1'b1; +always @ (s_clk) + s_clk <= #5 ~s_clk; + +reg s_rst = 1'b1; +initial begin + repeat (5) @ (posedge s_clk) + s_rst <= 1'b0; +end + +wire [95:0] s_value; +wire s_value_done; +wire s_terminate; +uc inst_uc( + // synchronous reset and processor clock + .i_rst (s_rst), + .i_clk (s_clk), + // 8-bit test values + .o_value (s_value), + .o_value_done (s_value_done), + // termination strobe + .o_terminate (s_terminate) +); + +always @ (posedge s_value_done) + $display("%08h + %08h = %08h", s_value[64+:32], s_value[32+:32], s_value[0+:32]); + +always @ (posedge s_terminate) + $finish; + +initial begin + $dumpfile("tb.vcd"); + $dumpvars(); +end + +endmodule
ssbcc/trunk/lib/9x8/tb/math/tb.v Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Author Date Id Revision \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: ssbcc/trunk/lib/9x8/tb/math/uc.9x8 =================================================================== --- ssbcc/trunk/lib/9x8/tb/math/uc.9x8 (nonexistent) +++ ssbcc/trunk/lib/9x8/tb/math/uc.9x8 (revision 4) @@ -0,0 +1,21 @@ +# Copyright 2014, Sinclair R.F., Inc. +# Test bench for the math library. + +ARCHITECTURE core/9x8 Verilog + +INSTRUCTION 1024 +DATA_STACK 128 +RETURN_STACK 32 + +PORTCOMMENT 32-bit addition result +PERIPHERAL big_outport outport=O_VALUE \ + outsignal=o_value \ + width=96 +OUTPORT strobe o_value_done \ + O_VALUE_DONE + +PORTCOMMENT termination strobe +OUTPORT strobe o_terminate \ + O_TERMINATE + +ASSEMBLY uc.s Index: ssbcc/trunk/lib/9x8/tb/char/uc.s =================================================================== --- ssbcc/trunk/lib/9x8/tb/char/uc.s (revision 3) +++ ssbcc/trunk/lib/9x8/tb/char/uc.s (revision 4) @@ -1,5 +1,5 @@ ; Copyright 2013, Sinclair R.F., Inc. -; Test bench for ../char.s +; Test bench for ../../char.s .include char.s
/ssbcc/trunk/lib/9x8/tb/char/uc.9x8
0,0 → 1,16
# Copyright 2013, Sinclair R.F., Inc.
# Test bench for the math libraries.
 
ARCHITECTURE core/9x8 Verilog
 
INSTRUCTION 1024
DATA_STACK 32
RETURN_STACK 32
 
PORTCOMMENT 8-bit test values
OUTPORT 8-bit,strobe o_value,o_value_wr O_VALUE
 
PORTCOMMENT termination strobe
OUTPORT strobe o_terminate_str O_TERMINATE
 
ASSEMBLY uc.s
/ssbcc/trunk/lib/9x8/tb/cmp_8bit_uu/uc.s
1,5 → 1,5
; Copyright 2013, Sinclair R.F., Inc.
; Test bench for ../cmp_8bit_uu.s
; Test bench for ../../cmp_8bit_uu.s
 
.include cmp_8bit_uu.s
 
/ssbcc/trunk/lib/9x8/tb/cmp_8bit_uu/uc.9x8
1,5 → 1,5
# Copyright 2013, Sinclair R.F., Inc.
# Test bench for the math libraries.
# Test bench for the icomparison math library.
 
ARCHITECTURE core/9x8 Verilog
 
/ssbcc/trunk/lib/9x8/math.s
1,62 → 1,60
; Copyright 2012, Sinclair R.F., Inc.
; Copyright 2014, Sinclair R.F., Inc.
;
; Multi-byte arithmetic
; Unsigned arithmetic operations.
 
; Notation: Multi-byte values on the stack are xx[n] where n=0 is the least
; significant byte of the value
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Add two unsigned 8-bit values to produce an unsigned 16-bit value.
; Method: Calculate the sum of the msb of the two raw values and the msb of the
; sums of the 7 lsbs of the two values to get the msb of the sum and
; the lsb of the MSB of the 16-bit sum.
; 36 instructions
;
; ( u1 u2 - (u1+u2)_LSB (u1+u2)_MSB )
.function math__add_u8_u8_u16
; and the two 7 lsbs and put the 7 lsb of that sum on the return stack
over 0x7F & over 0x7F & + dup 0x7F & >r
; add the msb of the sum of the 7 lsbs and the two inputs
0x80 & <<msb swap 0x80 & <<msb + swap 0x80 & <<msb +
; construct the MSB of the sum as bit 1 of the sums of the msbs
dup 0>> swap
; set the msb of the LSB if the lsb of the sum of the msbs is non-zero
0x01 & 0<> 0x80 & r> or
; swap the orders so that the MSB is on the top of the data stack
.return(swap)
 
.function add_u16_u8__u16 ; ( u0[0] u0[1] u1[0] - us[0] us[1] )
swap >r +uu r> +
.return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; miscellaneous unsigned addition operations
 
.function add_u16_u8__u24 ; ( u0[0] u0[1] u1[0] - us[0] us[1] us[2] )
swap >r +uu r> +uu
.return
.function math__add_u16_u8_u16
swap >r .call(math__add_u8_u8_u16) r> .return(+)
 
.function add_u16_u16__u16 ; ( u0[0] u0[1] u1[0] u1[1] - us[0] us[1] )
>r .call(add_u16_u8__u16) r> +
.return
.function math__add_u16_u8_u24
swap >r .call(math__add_u8_u8_u16) r> .call(math__add_u8_u8_u16) .return
 
.function add_u16_u16__u24 ; ( u0[0] u0[1] u1[0] u1[1] - us[0] us[1] us[2] )
>r .call(add_u16_u8__u24) r> .call(add_u16_u8__u16)
.return
.function math__add_u24_u8_u24
swap >r .call(math__add_u16_u8_u24)
r> .return(+)
 
.function add_u24_u8__u24 ; ( u0[0] u0[1] u0[2] u1[0] - us[0] us[1] us[2] )
swap >r .call(add_u16_u8__u24) r> +
.return
.function math__add_u24_u8_u32
swap >r .call(math__add_u16_u8_u24)
r> .call(math__add_u8_u8_u16)
.return
 
.function add_u24_u8__u32 ; ( u0[0] u0[1] u0[2] u1[0] - us[0] us[1] us[2] u[3] )
swap >r .call(add_u16_u8__u24) r> +uu
.return
.function math__add_u32_u8_u32
swap >r .call(math__add_u24_u8_u32)
r> .return(+)
 
.function add_u24_u16__u24 ; ( u0[0] u0[1] u0[2] u1[0] u1[1] - us[0] us[1] us[2] )
>r .call(add_u24_u8__u24) r> .call(add_u16_u8__u16)
.return
.function math__add_u32_u16_u32
>r .call(math__add_u32_u8_u32)
r> .call(math__add_u24_u8_u24)
.return
 
.function add_u24_u16__u32 ; ( u0[0] u0[1] u0[2] u1[0] u1[1] - us[0] us[1] us[2] us[3] )
>r .call(add_u24_u8__u32) r> .call(add_u24_u8__u24)
.return
.function math__add_u32_u24_u32
>r .call(math__add_u32_u16_u32)
r> .call(math__add_u16_u8_u16)
.return
 
.function add_u24_u24__u24 ; ( u0[0] u0[1] u0[2] u1[0] u1[1] u1[2] - us[0] us[1] us[2] )
>r .call(add_u24_u16__u24) r> +
.return
 
.function add_u24_u24__u32 ; ( u0[0] u0[1] u0[2] u1[0] u1[1] u1[2] - us[0] us[1] us[2] us[3] )
>r .call(add_u24_u16__u32) r> .call(add_u16_u8__u16)
.return
 
.function add_u32_u8__u32 ; ( u0[0] u0[1] u0[2] u0[3] u1[0] - us[0] us[1] us[2] us[3] )
swap >r .call(add_u24_u8__u32) r> +
.return
 
.function add_u32_u16__u32 ; ( u0[0] u0[1] u0[2] u0[3] u1[0] u1[1] - us[0] us[1] us[2] us[3] )
>r .call(add_u32_u8__u32) r> .call(add_u24_u8__u24)
.return
 
.function add_u32_u24__u32 ; ( u0[0] u0[1] u0[2] u0[3] u1[0] u1[1] u1[2] - us[0] us[1] us[2] us[3] )
>r .call(add_u32_u16__u32) r> .call(add_u16_u8__u16)
.return
 
.function add_u32_u32__u32 ; ( u0[0] u0[1] u0[2] u0[3] u1[0] u1[1] u1[2] u1[3] - us[0] us[1] us[2] us[3] )
>r .call(add_u32_u24__u32) r> +
.return
.function math__add_u32_u32_u32
>r .call(math__add_u32_u24_u32)
r> .return(+)
/ssbcc/trunk/core/9x8/macros/fetchvector.py
1,5 → 1,7
# Copyright 2014, Sinclair R.F., Inc.
 
from asmDef import AsmException
 
def fetchvector(ad):
"""
Built-in macro to move multiple bytes from memory to the data stack. The byte
16,7 → 18,10
"""
 
def length(ad,argument):
return int(argument[1]['value']) + 1;
N = ad.Emit_IntegerValue(argument[1]);
if not (N > 0):
raise asmDef.AsmException('Vector length must be positive at %s' % argument[1]['loc']);
return N+1;
 
# Add the macro to the list of recognized macros.
ad.AddMacro('.fetchvector', length, [
28,9 → 33,11
def emitFunction(ad,fp,argument):
variableName = argument[0]['value'];
(addr,ixBank,bankName) = ad.Emit_GetAddrAndBank(variableName);
N = int(argument[1]['value']);
ad.EmitPush(fp,addr+N-1,'%s+%d' % (variableName,N-1));
N = ad.Emit_IntegerValue(argument[1]);
offsetString = '%s-1' % argument[1]['value'] if type(argument[0]['value']) == str else '%d-1' % N;
ad.EmitPush(fp,addr+N-1,'%s+%s' % (variableName,offsetString));
for dummy in range(N-1):
ad.EmitOpcode(fp,ad.specialInstructions['fetch-'] | ixBank,'fetch- '+bankName);
ad.EmitOpcode(fp,ad.specialInstructions['fetch'] | ixBank,'fetch '+bankName);
 
ad.EmitFunction['.fetchvector'] = emitFunction;
/ssbcc/trunk/core/9x8/ssbccGenVerilog.py
752,6 → 752,7
signalType = signal[2];
signalInit = '%d\'d0' % signalWidth if len(signal)==3 else signal[3];
if signalType == 'data':
fp.write('initial %s = %s;\n' % (signalName,signalInit,));
if bitWidth > 0:
bitName += ', ';
bitInit += ', '
777,6 → 778,7
if signalType == 'data':
pass;
elif signalType == 'strobe':
fp.write('initial %s = 1\'b0;\n' % signalName);
fp.write('always @ (posedge i_clk)\n');
fp.write(' if (i_rst)\n');
fp.write(' %s <= 1\'b0;\n' % signalName);
/ssbcc/trunk/core/9x8/asmDef_9x8.py
902,6 → 902,27
self.emitLabelList = '';
return name;
 
def Emit_IntegerValue(self,token):
"""
Return the integer value associated with a constant or a numeric expression.
"""
if token['type'] == 'value':
v = token['value'];
elif token['type'] == 'symbol':
name = token['value'];
if not self.IsSymbol(name):
raise asmDef.AsmException('Symbol "%s" not recognized at %s' % (token['value'],token['loc'],));
ix = self.symbols['list'].index(name);
v = self.symbols['body'][ix];
if len(v) != 1:
raise asmDef.AsmException('Argument can only be one value at %s' % token['loc']);
v = v[0];
else:
raise asmDef.AsmException('Argument "%s" of type "%s" not recognized at %s' % (token['value'],token['type'],token['loc'],));
if type(v) != int:
raise Exception('Program Bug -- value should be an "int"');
return v;
 
#
# Utilities to write single instructions to the metacode file.
#
1272,7 → 1293,7
['','symbol'],
['drop','instruction','singlemacro','singlevalue','symbol']
]);
self.AddMacro('.return', 2, [ ['nop','instruction','singlevalue','symbol'] ]);
self.AddMacro('.return', 2, [ ['nop','instruction','singlemacro','singlevalue','symbol'] ]);
self.AddMacro('.store', 1, [ ['','symbol'] ]);
self.AddMacro('.store+', 1, [ ['','symbol'] ]);
self.AddMacro('.store-', 1, [ ['','symbol'] ]);
/ssbcc/trunk/core/9x8/peripherals/vivado_AXI4_Lite_Bus.py
45,6 → 45,8
ipx::remove_bus_interface {o_@BASEPORTNAME@} [ipx::current_core]
ipx::remove_bus_interface {i_@BASEPORTNAME@_signal_reset} [ipx::current_core]
ipx::remove_bus_interface {i_@BASEPORTNAME@_signal_clock} [ipx::current_core]
ipx::remove_memory_map {i_@BASEPORTNAME@} [ipx::current_core]
ipx::remove_memory_map {o_@BASEPORTNAME@} [ipx::current_core]
 
# Create the AXI4-Lite port.
ipx::add_bus_interface {@BASEPORTNAME@} [ipx::current_core]
88,10 → 90,14
body += """
# Fix the address space
ipx::add_address_space {@BASEPORTNAME@} [ipx::current_core]
set_property master_address_space_ref {@BASEPORTNAME@} [ipx::get_bus_interface @BASEPORTNAME@ [ipx::current_core]]
""";
if mode == 'master':
body += """set_property master_address_space_ref {@BASEPORTNAME@} [ipx::get_bus_interface @BASEPORTNAME@ [ipx::current_core]]
set_property range {@ADDR_WIDTH@} [ipx::get_address_space @BASEPORTNAME@ [ipx::current_core]]
set_property width {32} [ipx::get_address_space @BASEPORTNAME@ [ipx::current_core]]
""";
else:
body += "ipx::remove_address_space {@BASEPORTNAME@} [ipx::current_core]\n";
 
body += """
# Fix the reset port definition
/ssbcc/trunk/core/9x8/peripherals/AXI4_Lite_Slave_DualPortRAM.v
26,6 → 26,9
reg s__axi_got_wdata = 1'b0;
reg s__axi_got_raddr = 1'b0;
reg [L__NBITS_SIZE-1:2] s__axi_addr = {(L__NBITS_SIZE-2){1'b0}};
initial o_awready = 1'b0;
initial o_wready = 1'b0;
initial o_arready = 1'b0;
always @ (posedge i_aclk)
if (~i_aresetn) begin
s__axi_idle <= 1'b1;
33,6 → 36,9
s__axi_got_wdata <= 1'b0;
s__axi_got_raddr <= 1'b0;
s__axi_addr <= {(L__NBITS_SIZE-2){1'b0}};
o_awready <= 1'b0;
o_wready <= 1'b0;
o_arready <= 1'b0;
end else begin
s__axi_idle <= s__axi_idle;
s__axi_got_waddr <= s__axi_got_waddr;
75,9 → 81,22
initial o_bvalid = 1'b0;
always @ (*)
o_bvalid = s__axi_got_wdata;
reg s__axi_arready_s = 1'b0;
always @ (posedge i_aclk)
if (~i_aresetn)
s__axi_arready_s <= 1'b0;
else
s__axi_arready_s <= o_arready;
initial o_rvalid = 1'b0;
always @ (s__axi_got_raddr)
o_rvalid = s__axi_got_raddr;
always @ (posedge i_aclk)
if (~i_aresetn)
o_rvalid <= 1'b0;
else if (s__axi_arready_s)
o_rvalid <= 1'b1;
else if (i_rready)
o_rvalid <= 1'b0;
else
o_rvalid <= o_rvalid;
// signals common to both memory architectures
reg [L__NBITS_SIZE-1:2] s__axi_addr_s = {(L__NBITS_SIZE-2){1'b0}};
always @ (posedge i_aclk)
/ssbcc/trunk/core/9x8/peripherals/tb/AXI4_Lite_Slave_DualPortRAM/master.gtkw
0,0 → 1,50
[*]
[*] GTKWave Analyzer v3.3.42 (w)1999-2012 BSI
[*] Sun Mar 23 13:48:13 2014
[*]
[dumpfile] "/home/rsinclair/Projects/SSBCC/core/9x8/peripherals/tb/AXI4_Lite_Slave_DualPortRAM/tb.vcd"
[dumpfile_mtime] "Sun Mar 23 12:59:00 2014"
[dumpfile_size] 869113
[savefile] "/home/rsinclair/Projects/SSBCC/core/9x8/peripherals/tb/AXI4_Lite_Slave_DualPortRAM/master.gtkw"
[timestart] 20022900
[size] 1920 1171
[pos] -1 -1
*-16.801830 20420000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[treeopen] tb.
[treeopen] tb.uut.
[sst_width] 205
[signals_width] 276
[sst_expanded] 1
[sst_vpaned_height] 353
@28
tb.uut.i_axi_lite_aclk
tb.uut.i_axi_lite_aresetn
@200
-write side
@22
tb.uut.i_axi_lite_awaddr[6:0]
tb.uut.i_axi_lite_wdata[31:0]
tb.uut.i_axi_lite_wstrb[3:0]
@28
tb.uut.o_axi_lite_awready
tb.uut.i_axi_lite_awvalid
tb.uut.o_axi_lite_wready
tb.uut.i_axi_lite_wvalid
tb.uut.i_axi_lite_bready
tb.uut.o_axi_lite_bvalid
tb.uut.o_axi_lite_bresp[1:0]
@200
-read side
@22
tb.uut.i_axi_lite_araddr[6:0]
@29
tb.uut.o_axi_lite_arready
@28
tb.uut.i_axi_lite_arvalid
tb.uut.i_axi_lite_rready
tb.uut.o_axi_lite_rvalid
tb.uut.o_axi_lite_rresp[1:0]
@22
tb.uut.o_axi_lite_rdata[31:0]
[pattern_trace] 1
[pattern_trace] 0
/ssbcc/trunk/core/9x8/peripherals/tb/AXI4_Lite_Slave_DualPortRAM/tb.v
128,6 → 128,7
end
 
// Initiate reads and indicate their termination
localparam S_INIT_RREADY = 1'b1; // observed Xilinx behavior -- always high
initial s_rd_done = 1'b0;
reg [1:0] s_rd_acks = 2'b00;
reg s_arvalid = 1'b0;
137,7 → 138,7
always @ (posedge s_aclk) begin
s_rd_done <= 1'b0;
s_rd_acks <= s_rd_acks;
s_rready <= 1'b0;
s_rready <= S_INIT_RREADY;
if (s_rd_acks == 2'b11) begin
s_rd_done <= 1'b1;
s_rd_acks <= 2'b00;
205,4 → 206,9
if (s_done)
$finish;
 
//initial begin
// $dumpfile("tb.vcd");
// $dumpvars();
//end
 
endmodule
/ssbcc/trunk/core/9x8/peripherals/AXI4_Lite_Slave_DualPortRAM.py
46,7 → 46,7
optionally specifies using an 8-bit RAM for the dual-port memory instantiation
Note: This is the default
ram32
optionally specifies using a 32-bit RAM for the dual-port memrory instantiation
optionally specifies using a 32-bit RAM for the dual-port memory instantiation
Note: This is required for Vivado 2013.3.\n
Vivado Users:
The peripheral creates a TCL script to facilitate turning the micro
107,6 → 107,10
if not re.match(r'[1-9]\d*$', y):
raise SSBCCException('localparam must be a numeric constant, not "%s", to be used in "size=%s" at %s' % (y,x,loc,));
y = int(y);
elif re.match(r'C_\w+$',x):
if not config.IsConstant(x):
raise SSBCCException('"size=%s" is not a constant at %s' % (x,loc,));
y = int(config.constants[x]);
elif re.match(r'[1-9]\d*$',x):
y = int(x);
else:
/ssbcc/trunk/ssbccConfig.py
331,6 → 331,15
else:
return False;
 
def IsConstant(self,name):
"""
Indicate whether or not the specified symbol is a recognized constant.
"""
if re.match(r'C_\w+$',name) and name in self.constants:
return True;
else:
return False;
 
def IsMemory(self,name):
"""
Indicate whether or not the specified symbol is the name of a memory.
341,7 → 350,7
"""
Indicate whether or not the specified symbol is the name of a parameter.
"""
if re.match(r'[GL]_\w+',name) and name in self.symbols:
if re.match(r'[GL]_\w+$',name) and name in self.symbols:
return True;
else:
return False;
/ssbcc/trunk/README
1,10 → 1,16
SSBCC.9x8 is a free Small Stack-Based Computer Compiler with a 9-bit opcode,
8-bit data core. It creates vendor-independent, high-speed, low fabric
utilization micro controllers for FPGAs. It has been used in Spartan-3A,
Spartan-6, Virtex-6, and Artix-7 FPGAs and has been built for Altera, Lattice,
and other Xilinx devices. It is faster and usually smaller than vendor provided
processors.
8-bit data core designed to facilitate FPGA HDL development.
 
The primary design criteria are:
- high speed (to avoid timing issues)
- low fabric utilization
- vendor independent
- development tools available for all operating systems
 
It has been used in Spartan-3A, Spartan-6, Virtex-6, and Artix-7 FPGAs and has
been built for Altera, Lattice, and other Xilinx devices. It is faster and
usually smaller than vendor provided processors.
 
The compiler takes an architecture file that describes the micro controller
memory spaces, inputs and outputs, and peripherals and which specifies the HDL
language and source assembly. It generates a single HDL module implementing
11,6 → 17,19
the entire micro controller. No user-written HDL is required to instantiate
I/Os, program memory, etc.
 
The features are:
- high speed, low fabric utilization
- vendor-independent Verilog output with a VHDL package file
- simple Forth-like assembly language (41 instructions)
- single cycle instruction execution
- automatic generation of I/O ports
- configurable instruction, data stack, return stack, and memory utilization
- extensible set of peripherals (I2C busses, UARTs, AXI4-Lite busses, etc.)
- extensible set of macros
- memory initialization file to facilitate code development without rebuilds
- simulation diagnostics to facilitate identifying code errors
- conditionally included I/Os and peripherals, functions, and assembly code
 
SSBCC has been used for the following projects:
- operate a media translator from a parallel camera interface to an OMAP GPMC
interface, detect and report bus errors and hardware errors, and act as an
19,7 → 38,9
- operate and monitor the Artix-7 fabric in a Zynq system using AXI4-Lite
master and slave buses, I2C buses for timing-critical voltage measurements
 
The only external tool required is Python 2.7.
 
 
DESCRIPTION
================================================================================
 
28,18 → 49,18
output ports; RAM and ROM types and sizes; and peripherals.
 
The instructions are all single-cycle. The instructions include
- pushing an 8-bit value onto the data stack
- arithmetic operations: addition, subtraction, increment, and decrement
- bit-wise logical operations: and, or, and exclusive or
- rotations
- logical operations: 0=, 0<>, -1=, -1<>
- Forth-like data stack operations: dup, over, swap, drop, nip
- Forth-like return stack operations: >r, r>, r@
- input and output port operations
- memory read and write with optional address post increment and post decrement
- jumps and conditional jumps
- calls and conditional calls
- function return
- 4 arithmetic instructions: addition, subtraction, increment, and decrement
- 3 bit-wise logical instructions: and, or, and exclusive or
- 7 shift and rotation instructions: <<0, <<1, 0>>, 1>>, <<msb, >>msb, and >>lsb
- 4 logical instructions: 0=, 0<>, -1=, -1<>
- 6 Forth-like data stack instructions: drop, dup, nip, over, push, swap
- 3 Forth-like return stack instructions: >r, r>, r@
- 2 input and output
- 6 memory read and write with optional address post increment and post decrement
- 2 jump and conditional jump
- 2 call and conditional call
- 1 function return
- 1 nop
 
The 9x8 address space is up to 8K. This is achieved by pushing the 8 lsb of the
target address onto the data stack immediately before the jump or call
51,9 → 72,9
Up to four banks of memory, either RAM or ROM, are available. Each of these can
be up to 256 bytes long, providing a total of up to 1 kB of memory.
 
The assembly language is Forth-like. Macros are used to encode the jump and
call instructions and to encode the 2-bit memory bank index in memory store and
fetch instructions.
The assembly language is Forth-like. Built-in macros are used to encode the
jump and call instructions and to encode the 2-bit memory bank index in memory
store and fetch instructions.
 
The computer compiler and assembler are written in Python 2.7. Peripherals are
implemented by Python modules which generate the I/O ports and the peripheral
65,11 → 86,7
The computer compiler and assembler are fully functional and there are no known
bugs.
 
Features and peripherals are still being added and the documentation is
incomplete. The output HDL is currently restricted to Verilog although a VHDL
package file is automatically generated by the computer compiler.
 
 
SPEED AND RESOURCE UTILIZATION
================================================================================
These device speed and resource utilization results are copied from the build
97,7 → 114,7
numbers do provide is an estimate of the amount of slack available. For
example, you can't realistically expect to get 110 MHz from a processor that,
under ideal conditions, routes and places at 125 MHz, but you can with a
processor that synthesizes at more than 150 MHz.
processor that synthesizes at 150 MHz.
 
 
EXAMPLE:
276,9 → 293,8
 
C"Hello World!"
 
In this case the number of characters, 12 in this example, in the string is
pushed onto the data stack after the 'H', i.e., the instruction sequence would
be
In this case the number of characters, 12, in the string is pushed onto the data
stack after the 'H', i.e., the instruction sequence would be
 
'!' 'd' 'l' ... 'e' 'H' 12
 
1058,8 → 1074,13
The following macros are provided in macros/9x8:
.push16(v) push the 16-bit (2-byte) value "v" onto the data stack with the
MSB at the top of the data stack
.push24(v) push the 24-bit (3-byte) value "v" onto the data stack with the
MSB at the top of the data stack
.push32(v) push the 32-bit (4-byte) value "v" onto the data stack with the
MSB at the top of the data stack
.pushByte(v,ix)
push the ix'th byte of v onto the data stack
Note: ix=0 designates the LSB
 
Directories are searched in the following order for macros:
.
1072,7 → 1093,8
on the list provided when the macro is registered by the "AddMacro" method, but
additional type checking is often warranted by the macro "emitFunction" which
emits the actual assembly code. The ".fetchvector" and ".storevector" macros
demonstrates how to design variable-length macros.
demonstrates how to design variable-length macros. Several macros in
core/9x8/macros illustrate designing macros with optional arguments.
 
It is not an error to repeat the ".macro MACRO_NAME" directive for user-defined
macros. The assembler will issue a fatal error if a user-defined macro
1198,6 → 1220,10
MISCELLANEOUS
================================================================================
 
Features and peripherals are still being added and the documentation is
incomplete. The output HDL is currently restricted to Verilog although a VHDL
package file is automatically generated by the computer compiler.
 
The "INVERT_RESET" configuration command is used to indicate an active-low reset
is input to the micro controller rather than an active-high reset.
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.