Shop OBEX P1 Docs P2 Docs Learn Events
Is there a testbench for opcodes ( instruction set exersizer) ? — Parallax Forums

Is there a testbench for opcodes ( instruction set exersizer) ?

AleAle Posts: 2,363
edited 2014-03-19 06:26 in Propeller 1
Hello all,

I am looking for a testbench, piece of code, instruction set exersizer for the propeller 1. The propeller manual has some examples for the different alu opcodes, but getting the info out of the manual means lots of copy, paste and conversion... I'd like some frendlier format...

I know that I did some tests a couple of years back as I did my propeller assembler/simulator... I could use that and hack a script together...

any ideas ?

Comments

  • prof_brainoprof_braino Posts: 4,313
    edited 2014-03-06 05:01
    Ale wrote: »
    I am looking for a testbench, piece of code, instruction set exersizer for the propeller 1.
    any ideas ?

    Are you looking to execute an arbitrary instruction with arbitrary parameters, and check the results?

    The propforth build automation does specific instructions, and logs the results, and allows us to compare the current results with previous results.

    For the most part, if the code succeeds in building the same identical kernel, it must work, so we don't need to check each instruction as part of the regular build automation.

    But you could easily use the same tool, and create a new test to exercise each instruction to any extent desired, run it automaticaly, and automatically check the results for differences (using your own code on the workstation etc)

    Unfortunately its in forth, the tests must be written as interactive execution (which follows what you would do in test development anyway), and then you have to deal with scripting which is not so bad.
  • AleAle Posts: 2,363
    edited 2014-03-06 05:20
    Something like that would be great. I am trying to validate an emulator I wrote, and short of using a propeller itself and logging the results, not a bad idea, I have found nothing...
    I'd have a look at propforth later, maybe I can modify it for my needs. Thanks !
  • mindrobotsmindrobots Posts: 6,506
    edited 2014-03-06 05:25
    Ale,

    OpenSpin, PropGCC GAS and other have to generate binary parts for instructions. I've been tempted to look in those to see how they actually generates an instruction opcode from a mnemonic but I haven't looked yet. They must have some sort of lookup table for the 7 bit opcode and then generate the remaining bits as needed depending on the instruction.

    For the P2, I've been tempted to take the relevant parts of Chip .txt file and then run a <insert favorite scripting language here> program against it to break out the opcodes and mnemonics...oince the dust settles down. You could do the same thing with the relevant part of the P1 .pdf but it would be nice to find a usable table some place.

    Edit: OK, now that I see what you are looking for, you can probably ignore most of the above post.
  • Heater.Heater. Posts: 21,230
    edited 2014-03-06 05:32
    Ale,

    What are you actually wanting to test? A simulator of FPGA implementation?

    There is an instruction set exerciser for the Z80 that I use to verify the ZiCog Z80 emulator which uses a cunning technique you might want to think about.

    Basically what it does is to write an instruction into a buffer and then jump to that buffer to execute it. Also in that buffer is any data the instruction should operate on and space for it to write results. Now you calculate a CRC of the results. Do this for all your instructions and preferably with lots different test data for each, zero, maximum int, positive, negative etc.

    Run such a program on a real device and record the results. Now run the same program on you simulator and compare the results. In the case of the Z80 instruction exerciser the check sums are incorporated into the program so it can check as it runs.

    The neat thing here is that it actually accumulates CRCs over many test cases. You only need to log one CRC for each instruction, say. In this way the amount of data you need to log is vastly smaller and can ultimately end up in the program itself.



    This at least tells you how well the simulator matches a real device. It does not tell you what is wrong when in instruction fails. Then you have to do a bit more work.
  • ctwardellctwardell Posts: 1,716
    edited 2014-03-06 06:02
    This was started but looks like it never took off.

    http://forums.parallax.com/showthread.php/153208-PASM-Single-Line-SImulation

    C.W.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-03-06 08:59
    I wrote some test code a few years ago when I added the PASM simulator to spinsim. I don't know if I still have it, but I'll search around for it. The Prop manual is ambiguous on how some of the instructions work, especially on how they set the zero and carry flags. And for some instructions the manual has some errors in describing how they work.

    I believe my test code used a script that specified an instruction along with the initial conditions of the zero and carry flags, and the initial value of the cog memory location that is used. The tester would execute the instruction and then print out the values of the flags and the memory location. I ran the tester on the hardware and under spinsim, and I compared the outputs to make sure the matched.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-03-06 09:39
    I searched around, but I couldn't find the test code. I pretty much treated it as throw-away code once I was done with it. The test code itself was pretty straight-forward. It just fetched instructions and initial conditions from a file, executed the instruction, and wrote out the results. The script file can be included using the FILE statement.

    The script file may take a little bit of work. There are 64+ instructions, and each instruction would have 4 or 5 tests for typical and boundary conditions. That's only about 300 lines in the script file. :)
  • AleAle Posts: 2,363
    edited 2014-03-06 23:49
    I see that we come to the same ideas :). I wrote a script to generate the testbench. But instead of looking individually if all the results make sense, I'd have to log the real behaviour from a real prop. Heater's idea is well quite what I'm most probably going to do :).
    For instance, the manual doesn't say what happens when the shift amount is zero (for ROR)... I would guess that the C flag is loaded with bit 0. I'll have to test in a real prop :).

    Here is the script:
    #!/usr/bin/python
    
    header = '''/*
     * Testbench for the alu
     * (c) Pacito.Sys
     */
    
    `include "acog_alu.v"
    module tb_alu();
    
    reg clk, C, Z;
    reg [31:0] S, D;
    reg [8:0] pc_plus_1;
    reg [5:0] opcode;
    wire [31:0] alu_q;
    wire alu_c;
    wire alu_z;
    
    
    acog_alu alu(
    	.clk_in(clk),
    	.opcode_in({opcode, 26'h0 }),
    	.flag_c_in(C),
    	.flag_z_in(Z),
    	.s_in(S),
    	.d_in(D),
    	.pc_plus_1_in(pc_plus_1),
    	.flag_c_o(alu_c),
    	.flag_z_o(alu_z),
    	.q_o(alu_q)
    	);
    	
    initial
    	begin
    	$dumpfile("tb_alu.vcd");
    	$dumpvars(0, tb_alu);
    '''
    	
    ending = '    end\nendmodule\n'
    opcodeList = [
    '`I_RDBYTE','`I_RDWORD','`I_RDLONG','`I_HUBOP','`I_UNDEF0','`I_UNDEF1','`I_UNDEF2','`I_UNDEF3',
    '`I_ROR','`I_ROL','`I_SHR','`I_SHL','`I_RCR','`I_RCL','`I_SAR','`I_REV',
    '`I_MINS','`I_MAXS','`I_MIN	','`I_MAX','`I_MOVS','`I_MOVD','`I_MOVI','`I_JMPRET',
    '`I_AND','`I_ANDN','`I_OR','`I_XOR','`I_MUXC','`I_MUXNC','`I_MUXNZ','`I_MUXZ',
    '`I_ADD','`I_SUB','`I_ADDABS','`I_SUBABS','`I_SUMC','`I_SUMNC','`I_SUMZ','`I_SUMNZ',
    '`I_MOV','`I_NEG','`I_ABS','`I_ABSNEG','`I_NEGC','`I_NEGZ','`I_NEGNC','`I_NEGNZ',
    '`I_CMPS','`I_CMPSX','`I_ADDX','`I_SUBX','`I_ADDS','`I_SUBS','`I_ADDSX','`I_SUBSX',
    
    '`I_CMPSUB','`I_DJNZ','`I_TJNZ','`I_TJZ','`I_WAITPEQ','`I_WAITPNE','`I_WAITCNT','`I_WAITVID' ]
    
    opcodeName = [
    'RDBYTE', 'RDWORD','RDLONG','HUBOP','UNDEF0','UNDEF1','UNDEF2','UNDEF3',
    'ROR','ROL','SHR','SHL','RCR','RCL','SAR','REV',
    'MINS',	'MAXS',	'MIN','MAX','MOVS','MOVD',	'MOVI','JMPRET',
    'AND','ANDN','OR','XOR','MUXC','MUXNC','MUXNZ','MUXZ',
    'ADD','SUB','ADDABS','SUBABS','SUMC','SUMNC','SUMZ','SUMNZ',
    'MOV','NEG','ABS','ABSNEG','NEGC','NEGZ','NEGNC','NEGNZ',
    'CMPS','CMPSX','ADDX','SUBX','ADDS','SUBS','ADDSX','SUBSX',
    'CMPSUB','DJNZ','TJNZ','TJZ','WAITPEQ','WAITPNE','WAITCNT','WAITVID' ]
    
    test_values = [ 0, 1, 2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff ]
    
    def writeTest(opcode):
    	fo.write('	$display("{0:8s}---D---- ---S---- CZ = ---Q---- CZ");\n'.format(opcodeName[opcode]))
    	fo.write('\n	#1\n    opcode = {0:s};\n'.format(opcodeList[opcode]))
    	for s in range(len(test_values)):
    		for d in range(len(test_values)):
    			fo.write('	S = 32\'h{0:08x};\n'.format(test_values[s]))
    			fo.write('	D = 32\'h{0:08x};\n'.format(test_values[d]))
    			fo.write('	C = 1\'b0;\n')
    			fo.write('	Z = 1\'b0;\n')
    			fo.write('	#1 $display("        %08x %08x %1x%1x = %08x %1x%1x", D, S, C, Z, alu_q, alu_c, alu_z);\n')
    			fo.write('	#1\n')
    			fo.write('	C = 1\'b0;\n')
    			fo.write('	Z = 1\'b1;\n')
    			fo.write('	#1 $display("        %08x %08x %1x%1x = %08x %1x%1x", D, S, C, Z, alu_q, alu_c, alu_z);\n')
    			fo.write('	#1\n')
    			fo.write('	C = 1\'b1;\n')
    			fo.write('	Z = 1\'b0;\n')
    			fo.write('	#1 $display("        %08x %08x %1x%1x = %08x %1x%1x", D, S, C, Z, alu_q, alu_c, alu_z);\n')
    			fo.write('	#1\n')
    			fo.write('	C = 1\'b1;\n')
    			fo.write('	Z = 1\'b1;\n')
    			fo.write('	#1 $display("        %08x %08x %1x%1x = %08x %1x%1x", D, S, C, Z, alu_q, alu_c, alu_z);\n')
    
    fo = open("tb_alu.v", "wt")
    fo.write(header)
    for j in range(8, len(	opcodeList)):
    	writeTest(j)
    fo.write(ending)
    

    Here is how the testbench looks like:
    	$display("ROR     ---D---- ---S---- CZ = ---Q---- CZ");
    
    	#1
        opcode = `I_ROR;
    	S = 32'h00000000;
    	D = 32'h00000000;
    	C = 1'b0;
    	Z = 1'b0;
    	#1 $display("        %08x %08x %1x%1x = %08x %1x%1x", D, S, C, Z, alu_q, alu_c, alu_z);
    

    and here the results, just ROR and a bit of ROL
    ROR     ---D---- ---S---- CZ = ---Q---- CZ
            00000000 00000000 00 = 00000000 01
            00000000 00000000 01 = 00000000 01
            00000000 00000000 10 = 00000000 01
            00000000 00000000 11 = 00000000 01
            00000001 00000000 00 = 00000001 10
            00000001 00000000 01 = 00000001 10
            00000001 00000000 10 = 00000001 10
            00000001 00000000 11 = 00000001 10
            00000002 00000000 00 = 00000002 00
            00000002 00000000 01 = 00000002 00
            00000002 00000000 10 = 00000002 00
            00000002 00000000 11 = 00000002 00
            7fffffff 00000000 00 = 7fffffff 10
            7fffffff 00000000 01 = 7fffffff 10
            7fffffff 00000000 10 = 7fffffff 10
            7fffffff 00000000 11 = 7fffffff 10
            80000000 00000000 00 = 80000000 00
            80000000 00000000 01 = 80000000 00
            80000000 00000000 10 = 80000000 00
            80000000 00000000 11 = 80000000 00
            80000001 00000000 00 = 80000001 10
            80000001 00000000 01 = 80000001 10
            80000001 00000000 10 = 80000001 10
            80000001 00000000 11 = 80000001 10
            fffffffe 00000000 00 = fffffffe 00
            fffffffe 00000000 01 = fffffffe 00
            fffffffe 00000000 10 = fffffffe 00
            fffffffe 00000000 11 = fffffffe 00
            ffffffff 00000000 00 = ffffffff 10
            ffffffff 00000000 01 = ffffffff 10
            ffffffff 00000000 10 = ffffffff 10
            ffffffff 00000000 11 = ffffffff 10
            00000000 00000001 00 = 00000000 01
            00000000 00000001 01 = 00000000 01
            00000000 00000001 10 = 00000000 01
            00000000 00000001 11 = 00000000 01
            00000001 00000001 00 = 80000000 10
            00000001 00000001 01 = 80000000 10
            00000001 00000001 10 = 80000000 10
            00000001 00000001 11 = 80000000 10
            00000002 00000001 00 = 00000001 00
            00000002 00000001 01 = 00000001 00
            00000002 00000001 10 = 00000001 00
            00000002 00000001 11 = 00000001 00
            7fffffff 00000001 00 = bfffffff 10
            7fffffff 00000001 01 = bfffffff 10
            7fffffff 00000001 10 = bfffffff 10
            7fffffff 00000001 11 = bfffffff 10
            80000000 00000001 00 = 40000000 00
            80000000 00000001 01 = 40000000 00
            80000000 00000001 10 = 40000000 00
            80000000 00000001 11 = 40000000 00
            80000001 00000001 00 = c0000000 10
            80000001 00000001 01 = c0000000 10
            80000001 00000001 10 = c0000000 10
            80000001 00000001 11 = c0000000 10
            fffffffe 00000001 00 = 7fffffff 00
            fffffffe 00000001 01 = 7fffffff 00
            fffffffe 00000001 10 = 7fffffff 00
            fffffffe 00000001 11 = 7fffffff 00
            ffffffff 00000001 00 = ffffffff 10
            ffffffff 00000001 01 = ffffffff 10
            ffffffff 00000001 10 = ffffffff 10
            ffffffff 00000001 11 = ffffffff 10
            00000000 00000002 00 = 00000000 01
            00000000 00000002 01 = 00000000 01
            00000000 00000002 10 = 00000000 01
            00000000 00000002 11 = 00000000 01
            00000001 00000002 00 = 40000000 10
            00000001 00000002 01 = 40000000 10
            00000001 00000002 10 = 40000000 10
            00000001 00000002 11 = 40000000 10
            00000002 00000002 00 = 80000000 00
            00000002 00000002 01 = 80000000 00
            00000002 00000002 10 = 80000000 00
            00000002 00000002 11 = 80000000 00
            7fffffff 00000002 00 = dfffffff 10
            7fffffff 00000002 01 = dfffffff 10
            7fffffff 00000002 10 = dfffffff 10
            7fffffff 00000002 11 = dfffffff 10
            80000000 00000002 00 = 20000000 00
            80000000 00000002 01 = 20000000 00
            80000000 00000002 10 = 20000000 00
            80000000 00000002 11 = 20000000 00
            80000001 00000002 00 = 60000000 10
            80000001 00000002 01 = 60000000 10
            80000001 00000002 10 = 60000000 10
            80000001 00000002 11 = 60000000 10
            fffffffe 00000002 00 = bfffffff 00
            fffffffe 00000002 01 = bfffffff 00
            fffffffe 00000002 10 = bfffffff 00
            fffffffe 00000002 11 = bfffffff 00
            ffffffff 00000002 00 = ffffffff 10
            ffffffff 00000002 01 = ffffffff 10
            ffffffff 00000002 10 = ffffffff 10
            ffffffff 00000002 11 = ffffffff 10
            00000000 7fffffff 00 = 00000000 01
            00000000 7fffffff 01 = 00000000 01
            00000000 7fffffff 10 = 00000000 01
            00000000 7fffffff 11 = 00000000 01
            00000001 7fffffff 00 = 00000002 10
            00000001 7fffffff 01 = 00000002 10
            00000001 7fffffff 10 = 00000002 10
            00000001 7fffffff 11 = 00000002 10
            00000002 7fffffff 00 = 00000004 00
            00000002 7fffffff 01 = 00000004 00
            00000002 7fffffff 10 = 00000004 00
            00000002 7fffffff 11 = 00000004 00
            7fffffff 7fffffff 00 = fffffffe 10
            7fffffff 7fffffff 01 = fffffffe 10
            7fffffff 7fffffff 10 = fffffffe 10
            7fffffff 7fffffff 11 = fffffffe 10
            80000000 7fffffff 00 = 00000001 00
            80000000 7fffffff 01 = 00000001 00
            80000000 7fffffff 10 = 00000001 00
            80000000 7fffffff 11 = 00000001 00
            80000001 7fffffff 00 = 00000003 10
            80000001 7fffffff 01 = 00000003 10
            80000001 7fffffff 10 = 00000003 10
            80000001 7fffffff 11 = 00000003 10
            fffffffe 7fffffff 00 = fffffffd 00
            fffffffe 7fffffff 01 = fffffffd 00
            fffffffe 7fffffff 10 = fffffffd 00
            fffffffe 7fffffff 11 = fffffffd 00
            ffffffff 7fffffff 00 = ffffffff 10
            ffffffff 7fffffff 01 = ffffffff 10
            ffffffff 7fffffff 10 = ffffffff 10
            ffffffff 7fffffff 11 = ffffffff 10
            00000000 80000000 00 = 00000000 01
            00000000 80000000 01 = 00000000 01
            00000000 80000000 10 = 00000000 01
            00000000 80000000 11 = 00000000 01
            00000001 80000000 00 = 00000001 10
            00000001 80000000 01 = 00000001 10
            00000001 80000000 10 = 00000001 10
            00000001 80000000 11 = 00000001 10
            00000002 80000000 00 = 00000002 00
            00000002 80000000 01 = 00000002 00
            00000002 80000000 10 = 00000002 00
            00000002 80000000 11 = 00000002 00
            7fffffff 80000000 00 = 7fffffff 10
            7fffffff 80000000 01 = 7fffffff 10
            7fffffff 80000000 10 = 7fffffff 10
            7fffffff 80000000 11 = 7fffffff 10
            80000000 80000000 00 = 80000000 00
            80000000 80000000 01 = 80000000 00
            80000000 80000000 10 = 80000000 00
            80000000 80000000 11 = 80000000 00
            80000001 80000000 00 = 80000001 10
            80000001 80000000 01 = 80000001 10
            80000001 80000000 10 = 80000001 10
            80000001 80000000 11 = 80000001 10
            fffffffe 80000000 00 = fffffffe 00
            fffffffe 80000000 01 = fffffffe 00
            fffffffe 80000000 10 = fffffffe 00
            fffffffe 80000000 11 = fffffffe 00
            ffffffff 80000000 00 = ffffffff 10
            ffffffff 80000000 01 = ffffffff 10
            ffffffff 80000000 10 = ffffffff 10
            ffffffff 80000000 11 = ffffffff 10
            00000000 80000001 00 = 00000000 01
            00000000 80000001 01 = 00000000 01
            00000000 80000001 10 = 00000000 01
            00000000 80000001 11 = 00000000 01
            00000001 80000001 00 = 80000000 10
            00000001 80000001 01 = 80000000 10
            00000001 80000001 10 = 80000000 10
            00000001 80000001 11 = 80000000 10
            00000002 80000001 00 = 00000001 00
            00000002 80000001 01 = 00000001 00
            00000002 80000001 10 = 00000001 00
            00000002 80000001 11 = 00000001 00
            7fffffff 80000001 00 = bfffffff 10
            7fffffff 80000001 01 = bfffffff 10
            7fffffff 80000001 10 = bfffffff 10
            7fffffff 80000001 11 = bfffffff 10
            80000000 80000001 00 = 40000000 00
            80000000 80000001 01 = 40000000 00
            80000000 80000001 10 = 40000000 00
            80000000 80000001 11 = 40000000 00
            80000001 80000001 00 = c0000000 10
            80000001 80000001 01 = c0000000 10
            80000001 80000001 10 = c0000000 10
            80000001 80000001 11 = c0000000 10
            fffffffe 80000001 00 = 7fffffff 00
            fffffffe 80000001 01 = 7fffffff 00
            fffffffe 80000001 10 = 7fffffff 00
            fffffffe 80000001 11 = 7fffffff 00
            ffffffff 80000001 00 = ffffffff 10
            ffffffff 80000001 01 = ffffffff 10
            ffffffff 80000001 10 = ffffffff 10
            ffffffff 80000001 11 = ffffffff 10
            00000000 fffffffe 00 = 00000000 01
            00000000 fffffffe 01 = 00000000 01
            00000000 fffffffe 10 = 00000000 01
            00000000 fffffffe 11 = 00000000 01
            00000001 fffffffe 00 = 00000004 10
            00000001 fffffffe 01 = 00000004 10
            00000001 fffffffe 10 = 00000004 10
            00000001 fffffffe 11 = 00000004 10
            00000002 fffffffe 00 = 00000008 00
            00000002 fffffffe 01 = 00000008 00
            00000002 fffffffe 10 = 00000008 00
            00000002 fffffffe 11 = 00000008 00
            7fffffff fffffffe 00 = fffffffd 10
            7fffffff fffffffe 01 = fffffffd 10
            7fffffff fffffffe 10 = fffffffd 10
            7fffffff fffffffe 11 = fffffffd 10
            80000000 fffffffe 00 = 00000002 00
            80000000 fffffffe 01 = 00000002 00
            80000000 fffffffe 10 = 00000002 00
            80000000 fffffffe 11 = 00000002 00
            80000001 fffffffe 00 = 00000006 10
            80000001 fffffffe 01 = 00000006 10
            80000001 fffffffe 10 = 00000006 10
            80000001 fffffffe 11 = 00000006 10
            fffffffe fffffffe 00 = fffffffb 00
            fffffffe fffffffe 01 = fffffffb 00
            fffffffe fffffffe 10 = fffffffb 00
            fffffffe fffffffe 11 = fffffffb 00
            ffffffff fffffffe 00 = ffffffff 10
            ffffffff fffffffe 01 = ffffffff 10
            ffffffff fffffffe 10 = ffffffff 10
            ffffffff fffffffe 11 = ffffffff 10
            00000000 ffffffff 00 = 00000000 01
            00000000 ffffffff 01 = 00000000 01
            00000000 ffffffff 10 = 00000000 01
            00000000 ffffffff 11 = 00000000 01
            00000001 ffffffff 00 = 00000002 10
            00000001 ffffffff 01 = 00000002 10
            00000001 ffffffff 10 = 00000002 10
            00000001 ffffffff 11 = 00000002 10
            00000002 ffffffff 00 = 00000004 00
            00000002 ffffffff 01 = 00000004 00
            00000002 ffffffff 10 = 00000004 00
            00000002 ffffffff 11 = 00000004 00
            7fffffff ffffffff 00 = fffffffe 10
            7fffffff ffffffff 01 = fffffffe 10
            7fffffff ffffffff 10 = fffffffe 10
            7fffffff ffffffff 11 = fffffffe 10
            80000000 ffffffff 00 = 00000001 00
            80000000 ffffffff 01 = 00000001 00
            80000000 ffffffff 10 = 00000001 00
            80000000 ffffffff 11 = 00000001 00
            80000001 ffffffff 00 = 00000003 10
            80000001 ffffffff 01 = 00000003 10
            80000001 ffffffff 10 = 00000003 10
            80000001 ffffffff 11 = 00000003 10
            fffffffe ffffffff 00 = fffffffd 00
            fffffffe ffffffff 01 = fffffffd 00
            fffffffe ffffffff 10 = fffffffd 00
            fffffffe ffffffff 11 = fffffffd 00
            ffffffff ffffffff 00 = ffffffff 10
            ffffffff ffffffff 01 = ffffffff 10
            ffffffff ffffffff 10 = ffffffff 10
            ffffffff ffffffff 11 = ffffffff 10
    ROL     ---D---- ---S---- CZ = ---Q---- CZ
            00000000 00000000 00 = 00000000 01
            00000000 00000000 01 = 00000000 01
            00000000 00000000 10 = 00000000 01
            00000000 00000000 11 = 00000000 01
            00000001 00000000 00 = 00000001 00
            00000001 00000000 01 = 00000001 00
    
  • AleAle Posts: 2,363
    edited 2014-03-07 04:41
    Checking the opcode tables in the manual, I see that ADDABS looks funny...

    $FFFF_FFFD + $0000_0003 = $0000_0000 z = 1, c = 1
    $FFFF_FFFD + $FFFF_FFFD = $0000_0000 z = 1, c = 0 // It should be 1...

    I also noticed (again, most probably) that RCR and RCL do not work like in the 6809 or z80... the carry is shifted in so many times as bits are specified in s,
  • ozpropdevozpropdev Posts: 2,791
    edited 2014-03-07 05:41
    See Phil's manual, it has some diagrams on the shifts and rotates operation.
    Tricks and traps
  • AleAle Posts: 2,363
    edited 2014-03-07 06:00
    It has been a while since I was this active with the propeller... I vaguely remember that thread... the document is pure gold, though. Thanks :)
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-03-07 06:18
    Ale, your test code looks great! I'll have to try that on spinsim to make sure it still matches the P1. This will also be good for testing the P2 since the current documentation doesn't say much about the carry and zero flags.
  • AleAle Posts: 2,363
    edited 2014-03-07 07:46
    Thanks,

    I haven't check all the opcodes yet, I'm at CMP. I look at the manual and at the results... more comprehensive will be when I write some code...something like what Heater said, a simple Spin server with serial io and a small PASM routine that does the required test... I have a suitable board with me.... now to see which version of BST works in Mavericks.... None :(. BST does not work :/...
    Let's get PropTool... then... :(
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-03-07 18:53
    Ale, I wrote a Spin program that used your test vectors, and I ran it with spinsim and on my QuickStart board. After comparing the outputs I found that I had an error in the C flag computation for CMPSX and an error in the Z flag computation for CMPSUB. After looking at the Prop manual for those instructions I was able to fix the problems.

    At some point I'll have to do the same exercise to compare my P2 simulator with the P2 FPGA emulator. Thanks for starting this thread and posting your work.

    EDIT: I attached a zip file that contains the Spin program I wrote. testbench.c is the source for the Spin file, which I converted using cspin 0.68. The program starts a PASM cog that runs an instruction given the initial values, and returns the results.
  • AleAle Posts: 2,363
    edited 2014-03-07 22:38
    Hei Dave that is awesome !... let's test my results now...
  • AleAle Posts: 2,363
    edited 2014-03-14 06:29
    I am testing now and see that I need to modify some of the opcodes, MINx, MAXx, MUXx. and ADDABS and SUBABS.
    I seem not to see how to implement ADDABS correctly, I mean the C flag behaviour. According to the manual:
    0xFFFF_FFFD + 3 = 0 + Carry set
    0xFFFF_FFFD + (-3) = 0 and carry clear !
    The manual says: The C flag is set (1) if the summation resulted in an unsigned carry...
    And for MOVS, MOVI and MOVD, the C flag is not specified at all... it looks like this odd parity on S... sometimes
  • kuronekokuroneko Posts: 3,623
    edited 2014-03-14 19:02
    re: addabs, carry is inverted for negative source operands (check latest manual and/or datasheet). For mov[sdi] carry is unsigned borrow.
  • AleAle Posts: 2,363
    edited 2014-03-18 00:34
    regarding addabs/subabs... something doesn't look right, here a test with results:
                        ------- C  A  L  C  U  L  A  T  E  D ---------   ----- R  E  A  L -----
    ---D---- ---S---- = C--ADDABS-  C--SUBABS-  C---ADD---  C---SUB---   C--ADDABS-  C--SUBABS-  
    fffffffd 00000004 = 1 00000001  0 fffffff9  1 00000001  0 fffffff9   1 00000001              
    fffffffd 00000003 = 1 00000000  0 fffffffa  1 00000000  0 fffffffa   1 00000000              
    fffffffd 00000002 = 0 ffffffff  0 fffffffb  0 ffffffff  0 fffffffb   0 ffffffff              
    fffffffd ffffffff = 0 fffffffe  0 fffffffc  1 fffffffc  1 fffffffe   1 fffffffe              
    fffffffd fffffffe = 0 ffffffff  0 fffffffb  1 fffffffb  1 ffffffff   1 ffffffff              
    fffffffd fffffffd = 1 00000000  0 fffffffa  1 fffffffa  0 00000000   0 00000000              
    fffffffd fffffffc = 1 00000001  0 fffffff9  1 fffffff9  0 00000001   0 00000001              
    ---D---- ---S---- = C--ADDABS-  C--SUBABS-  C---ADD---  C---SUB---   C--ADDABS-  C--SUBABS-  
    00000003 fffffffc = 0 00000007  1 ffffffff  0 ffffffff  1 00000007               0 ffffffff  
    00000003 fffffffd = 0 00000006  0 00000000  1 00000000  1 00000006               1 00000000  
    00000003 fffffffe = 0 00000005  0 00000001  1 00000001  1 00000005               1 00000001  
    00000003 ffffffff = 0 00000004  0 00000002  1 00000002  1 00000004               1 00000002  
    00000003 00000002 = 0 00000005  0 00000001  0 00000005  0 00000001               0 00000001  
    00000003 00000003 = 0 00000006  0 00000000  0 00000006  0 00000000               0 00000000  
    00000003 00000004 = 0 00000007  1 ffffffff  0 00000007  1 ffffffff               1 ffffffff  
    

    The manual says (page 256, v1.2)
    Note 3: ADDABS C out: If S is negative, C = the inverse of unsigned borrow (for D-S).
    Note 4: SUBABS C out: If S is negative, C = the inverse of unsigned carry (for D+S).

    If we take the carry from ADDABS for positive S and the borrow from SUB for negative S, without inverting it, we get what is displayed in the table for ADDABS.
    For SUBABS the carry can be the ADD carry for negative numbers and the borrow from SUBABS.

    any thoughts ?
  • kuronekokuroneko Posts: 3,623
    edited 2014-03-18 01:14
    Ale wrote: »
    regarding addabs/subabs... something doesn't look right, here a test with results:
    ---D---- ---S---- = C--ADDABS-
    [COLOR="#FFA500"]fffffffd 00000004 = 1 00000001
    fffffffd 00000003 = 1 00000000
    fffffffd 00000002 = 0 ffffffff
    [/COLOR]fffffffd ffffffff = 0 fffffffe
    fffffffd fffffffe = 0 ffffffff
    fffffffd fffffffd = 1 00000000
    fffffffd fffffffc = 1 00000001
    

    The manual says (page 256, v1.2)
    Note 3: ADDABS C out: If S is negative, C = the inverse of unsigned borrow (for D-S).
    Note 4: SUBABS C out: If S is negative, C = the inverse of unsigned carry (for D+S).
    The orange section sets carry when you get an overflow, OK. The remainder is wrong, with negative source carry is inverted so the last two lines (overflow) produce carry clear.
  • AleAle Posts: 2,363
    edited 2014-03-18 01:25
    The carry in every column is for every add/sub operation respectively.

    I will edit it for clarity..
  • AleAle Posts: 2,363
    edited 2014-03-18 02:39
    Ok. I edited the post with real (from manual) values.

    Now, NEGxx.
    According to the manual NEGNC is opcode 0x101101 = 45d and when tested using Davi'd code I get the following..
    NEGNC   ---D---- ---S---- ZC = ---Q---- ZC
            ffffffff 00000001 01 = 00000001 00
            ffffffff 00000001 11 = ffffffff 00
            00000000 00000002 00 = 00000002 00
            00000000 00000002 10 = fffffffe 00
            00000000 00000002 01 = 00000002 00
            00000000 00000002 11 = fffffffe 00
            00000000 7fffffff 00 = 7fffffff 00
            00000000 7fffffff 10 = 80000001 00
            00000000 7fffffff 01 = 7fffffff 00
            00000000 7fffffff 11 = 80000001 00
    

    If we look at the result they change with Z instead of with C... and NEGZ (0x101110, 46d) seems to have the same behaviour but changes with C instead of with Z:
    NEGZ    ---D---- ---S---- ZC = ---Q---- ZC
            ffffffff 00000001 00 = ffffffff 00
            ffffffff 00000001 10 = ffffffff 00
            ffffffff 00000001 01 = 00000001 00
            ffffffff 00000001 11 = 00000001 00
            00000000 00000002 00 = fffffffe 00
            00000000 00000002 10 = fffffffe 00
            00000000 00000002 01 = 00000002 00
            00000000 00000002 11 = 00000002 00
            00000000 7fffffff 00 = 80000001 00
            00000000 7fffffff 10 = 80000001 00
            00000000 7fffffff 01 = 7fffffff 00
            00000000 7fffffff 11 = 7fffffff 00
    

    It seems NEGNC & NEGZ have the wrong encoding...
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-03-18 08:43
    The original program printed the flags as CZ instead of ZC. Is it possible you have the flags swapped in your print?
  • AleAle Posts: 2,363
    edited 2014-03-19 06:26
    Yes, I changed the program to display the other way around to better compare with the tables in the propeller manual. I'll run the test again over the weekend to see if the opcodes are really swapped.
Sign In or Register to comment.