URL
https://opencores.org/ocsvn/rf68000/rf68000/trunk
Subversion Repositories rf68000
Compare Revisions
- This comparison shows the changes necessary to convert path
/rf68000
- from Rev 2 to Rev 3
- ↔ Reverse comparison
Rev 2 → Rev 3
/trunk/doc/rf68000.docx
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/rtl/cpu/io_bitmap.sv
148,7 → 148,7
.sbiterrb(), // 1-bit output: Status signal to indicate single bit error occurrence |
// on the data output of port B. |
|
.addra({asid_i[5:0],adr_i[ 8: 2]}), // ADDR_WIDTH_A-bit input: Address for port A write and read operations. |
.addra(adr_i[14: 2]), // ADDR_WIDTH_A-bit input: Address for port A write and read operations. |
.addrb({asid_i[5:0],adr_i[19:13]}), // ADDR_WIDTH_B-bit input: Address for port B write and read operations. |
.clka(clk_i), // 1-bit input: Clock signal for port A. Also clocks port B when |
// parameter CLOCKING_MODE is "common_clock". |
220,7 → 220,7
else |
dat_o <= 32'd0; |
|
always_comb |
gate_o <= doutb[adr_i[12:8]]; |
always_ff @(posedge clk_i) |
gate_o <= doutb[adr_i[12:8]] & enb; |
|
endmodule |
/trunk/rtl/cpu/rf68000.sv
48,6 → 48,8
//`define SUPPORT_010 1'b1 |
`define SUPPORT_BITPAIRS 1'b1 |
|
//`define HAS_MMU 1'b1 |
|
//`define SUPPORT_TASK 1'b1 |
|
//`define SUPPORT_B24 1'b1 // To support 23-bit branch displacements |
93,6 → 95,7
`define STH 16'b0010_xxx1xx_xxxxxx |
`define STW 16'b0011_xxx1xx_xxxxxx |
|
// DBcc also for Scc |
`define DBRA 8'h50 |
`define DBSR 8'h51 |
`define DBHI 8'h52 |
472,6 → 475,14
reg [31:0] a5 = 'd0; |
reg [31:0] a6 = 'd0; |
reg [31:0] sp = 'd0; |
reg [127:0] fp0 = 'd0; |
reg [127:0] fp1 = 'd0; |
reg [127:0] fp2 = 'd0; |
reg [127:0] fp3 = 'd0; |
reg [127:0] fp4 = 'd0; |
reg [127:0] fp5 = 'd0; |
reg [127:0] fp6 = 'd0; |
reg [127:0] fp7 = 'd0; |
reg [31:0] d0i; |
reg [31:0] d1i; |
reg [31:0] d2i; |
639,6 → 650,7
//wire [31:0] rfoRnn = rrrr==4'b1111 ? sp : regfile[rrrr]; |
wire clk_g; |
reg rfwrL,rfwrB,rfwrW; |
reg rfwrFp; |
reg takb; |
reg [8:0] resB; |
reg [16:0] resW; |
680,9 → 692,9
reg [31:0] tr; |
reg [31:0] tcba; |
reg [31:0] mmus, ios, iops; |
assign mmus_o = adr_o[31:2] >= mmus[31:2] && adr_o[31:2] < mmus[31:2]+10'd512; |
assign iops_o = adr_o[31:2] >= iops[31:2] && adr_o[31:2] < iops[31:2]+8'd128; |
assign ios_o = adr_o[31:2] >= ios [31:2] && adr_o[31:2] < ios [31:2]+24'h100000; |
assign mmus_o = adr_o[31:20] == mmus[31:20]; |
assign iops_o = adr_o[31:16] == iops[31:16]; |
assign ios_o = adr_o[31:20] == ios [31:20]; |
|
wire [16:0] lfsr_o; |
lfsr17 ulfsr1 |
1555,6 → 1567,7
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= pc; |
goto (IFETCH); |
end |
end |
else if (ack_i) begin |
1575,6 → 1588,7
stb_o <= 1'b1; |
sel_o <= 4'b1111; |
adr_o <= pc; |
goto (IFETCH2); |
end |
else if (ack_i) begin |
cyc_o <= 1'b0; |
1924,13 → 1938,13
//----------------------------------------------------------------------------- |
5'h5: |
begin |
casez(ir[7:4]) |
casez(ir[7:3]) |
// When optimizing DBRA for performance, the memory access cycle to fetch |
// the displacement constant is not done, instead the PC is incremented by |
// two if not doing the DBRA. This is an extra PC increment that increases |
// the code size. It is slower, but more hardware efficient to just always |
// fetch the displacement. |
4'b1100: // DBRA |
5'b11001: // DBRA |
`ifdef OPT_PERF |
if (~takb) begin |
call(FETCH_IMM16,DBRA); |
1942,7 → 1956,7
`else |
call(FETCH_IMM16,DBRA); |
`endif |
4'b11??: // Scc |
5'b11???: // Scc |
begin |
resL <= {32{takb}}; |
resW <= {16{takb}}; |
5391,14 → 5405,14
case(imm[11:0]) |
12'h000: begin sfc <= rfoRnn; ret(); end |
12'h001: begin dfc <= rfoRnn; ret(); end |
12'h003: begin asid <= rfoDnn[7:0]; ret(); end |
12'h010: begin apc <= rfoDnn; ret(); end |
12'h011: begin cpl <= rfoDnn[7:0]; ret(); end |
12'h012: begin tr <= rfoDnn; ret(); end |
12'h013: begin tcba <= rfoDnn; ret(); end |
12'h014: begin mmus <= rfoDnn; ret(); end |
12'h015: begin ios <= rfoDnn; ret(); end |
12'h016: begin iops <= rfoDnn; ret(); end |
12'h003: begin asid <= rfoRnn[7:0]; ret(); end |
12'h010: begin apc <= rfoRnn; ret(); end |
12'h011: begin cpl <= rfoRnn[7:0]; ret(); end |
12'h012: begin tr <= rfoRnn; ret(); end |
12'h013: begin tcba <= rfoRnn; ret(); end |
12'h014: begin mmus <= rfoRnn; ret(); end |
12'h015: begin ios <= rfoRnn; ret(); end |
12'h016: begin iops <= rfoRnn; ret(); end |
12'h800: begin usp <= rfoRnn; ret(); end |
12'h801: begin vbr <= rfoRnn; ret(); end |
/* |
/trunk/rtl/cpu/rf68000_mmu.sv
247,6 → 247,8
pea_o[15: 0] <= s_adr_i[15:0]; |
pea_o[31:16] <= doutb[15:0]; |
pdat_o <= s_dat_i; |
if (s_cs_i) |
pea_o <= 'd0; |
if (cs) begin |
cyc_o <= 1'b0; |
stb_o <= 1'b0; |
/trunk/software/examples/boot.asm
47,6 → 47,8
; |
;------------------------------------------------------------------------------- |
; |
HAS_MMU equ 0 |
|
CTRLC EQU $03 |
CTRLH EQU $08 |
CTRLS EQU $13 |
74,6 → 76,7
SC_LCTRL EQU $58 |
SC_TAB EQU $0D |
|
if HAS_MMU |
TEXTREG EQU $1E3FF00 ; virtual addresses |
txtscreen EQU $1E00000 |
semamem EQU $1E50000 |
83,6 → 86,14
ACIA_STAT EQU 4 |
ACIA_CMD EQU 8 |
ACIA_CTRL EQU 12 |
I2C2 equ $01E69000 |
I2C_PREL equ 0 |
I2C_PREH equ 1 |
I2C_CTRL equ 2 |
I2C_RXR equ 3 |
I2C_TXR equ 3 |
I2C_CMD equ 4 |
I2C_STAT equ 4 |
PLIC EQU $1E90000 |
MMU EQU $FDC00000 ; physical address |
leds EQU $1EFFF00 ; virtual addresses |
95,7 → 106,37
RAND_MW EQU $1EFFD0C |
RST_REG EQU $1EFFC00 |
IO_BITMAP EQU $1F00000 |
IOFocus EQU $0100000 |
else |
TEXTREG EQU $FD03FF00 ; virtual addresses |
txtscreen EQU $FD000000 |
semamem EQU $FD050000 |
ACIA EQU $FD060000 |
ACIA_RX EQU 0 |
ACIA_TX EQU 0 |
ACIA_STAT EQU 4 |
ACIA_CMD EQU 8 |
ACIA_CTRL EQU 12 |
I2C2 equ $FD069000 |
I2C_PREL equ 0 |
I2C_PREH equ 1 |
I2C_CTRL equ 2 |
I2C_RXR equ 3 |
I2C_TXR equ 3 |
I2C_CMD equ 4 |
I2C_STAT equ 4 |
PLIC EQU $FD090000 |
MMU EQU $FDC00000 ; physical address |
leds EQU $FD0FFF00 ; virtual addresses |
keybd EQU $FD0FFE00 |
KEYBD EQU $FD0FFE00 |
RAND EQU $FD0FFD00 |
RAND_NUM EQU $FD0FFD00 |
RAND_STRM EQU $FD0FFD04 |
RAND_MZ EQU $FD0FFD08 |
RAND_MW EQU $FD0FFD0C |
RST_REG EQU $FD0FFC00 |
IO_BITMAP EQU $FD100000 |
endif |
|
SERIAL_SEMA EQU 2 |
KEYBD_SEMA EQU 3 |
294,6 → 335,7
TimerStack equ $40BFC |
|
; Keyboard buffer is in shared memory |
IOFocus EQU $00100000 |
memend equ $00100004 |
KeybdLEDs equ $0010000E |
_KeyState1 equ $0010000F |
309,6 → 351,7
SerRcvXon equ $00100164 |
SerRcvXoff equ $00100165 |
SerRcvBuf equ $00101000 |
RTCBuf equ $00100200 ; to $0010023F |
|
include "..\Femtiki\source\kernel\Femtiki_vars.x68" |
|
315,9 → 358,28
code |
align 2 |
start: |
; fadd (a0)+,fp2 |
move.w #$2700,sr ; enable level 6 and higher interrupts |
moveq #0,d0 ; set address space zero |
movec d0,asid |
; Setup circuit select signals |
move.l #MMU,d0 |
movec d0,mmus |
if HAS_MMU |
move.l #$01F00000,d0 ; set virtual address for iop bitmap |
movec d0,iops |
move.l #$01E00000,d0 ; set virtual address for io block |
movec d0,ios |
else |
move.l #$FD100000,d0 ; set virtual address for iop bitmap |
movec d0,iops |
move.l #$FD000000,d0 ; set virtual address for io block |
movec d0,ios |
endif |
movec coreno,d0 ; set initial value of thread register |
swap d0 ; coreno in high eight bits |
lsl.l #8,d0 |
movec d0,tr |
; Prepare local variable storage |
move.w #1023,d0 ; 1024 longs to clear |
lea $40000,a0 ; non shared local memory address |
329,7 → 391,11
movec.l coreno,d0 ; get core number (2 to 9) |
subi.b #2,d0 ; adjust (0 to 7) |
mulu #16384,d0 ; compute screen location |
addi.l #$FD000000,d0 |
if HAS_MMU |
addi.l #$01E00000,d0 |
else |
addi.l #$FD000000,d0 |
endif |
move.l d0,TextScr |
move.b #64,TextCols ; set rows and columns |
move.b #32,TextRows |
337,8 → 403,10
cmpi.b #2,d0 |
bne start_other |
move.b d0,IOFocus ; Set the IO focus in global memory |
bsr InitMMU ; Can't access anything till this is done |
bsr InitIOBitmap ; not going to get far without this |
if HAS_MMU |
bsr InitMMU ; Can't access anything till this is done |
endif |
bsr InitIOPBitmap ; not going to get far without this |
bsr InitSemaphores |
bsr InitRand |
bsr Delay3s ; give devices time to reset |
347,6 → 415,8
bsr _KeybdInit |
; bsr InitIRQ |
bsr SerialInit |
bsr init_i2c |
; bsr rtc_read |
|
; Write startup message to screen |
|
378,6 → 448,7
|
start_other: |
bsr Delay3s2 ; need time for system setup (io_bitmap etc.) |
bsr Delay3s2 ; need time for system setup (io_bitmap etc.) |
bsr clear_screen |
movec coreno,d1 |
bsr DisplayByte |
391,6 → 462,7
;------------------------------------------------------------------------------ |
; Initialize the MMU to allow thread #0 access to IO |
;------------------------------------------------------------------------------ |
if HAS_MMU |
align 2 |
mmu_adrtbl: ; virtual address[24:16], physical address[31:16] bytes reversed! |
dc.l $0010,$10000300 ; global scratch pad |
403,6 → 475,7
dc.l $01E9,$09FD0300 |
dc.l $01EF,$0FFD0300 |
dc.l $01F0,$10FD0300 |
dc.l $01FF,$FFFF0300 ; all ones output for IRQ ack needed |
|
even |
InitMMU: |
417,7 → 490,7
dbra d0,.0002 |
lea MMU,a0 ; now program IO access |
lea mmu_adrtbl,a1 |
moveq #9,d0 |
moveq #10,d0 |
.0001 |
move.l (a1)+,d2 |
lsl.l #2,d2 |
424,37 → 497,39
move.l (a1)+,(a0,d2.w) |
dbra d0,.0001 |
rts |
endif |
|
;------------------------------------------------------------------------------ |
; The IO bitmap needs to be initialized to allow access to IO. |
;------------------------------------------------------------------------------ |
|
InitIOBitmap: |
; mark all IO inaccessible |
move.w #8191,d0 |
lea IO_BITMAP,a0 |
InitIOPBitmap: |
moveq #0,d3 ; d3 = asid value |
move.w #63,d0 ; 64 bitmaps to setup |
movec iops,a0 ; a0 = IOP bitmap address |
movea.l a0,a1 ; a1 = table address |
.0004 |
tst.b d3 |
seq d1 ; set entire bitmap for asid 0, otherwise clear entire bitmap |
ext.w d1 ; make into a long value |
ext.l d1 |
move.w #127,d4 |
.0001 |
clr.l (a0)+ |
dbra d0,.0001 |
; Give the system asid=0 complete access to the IO area |
move.w #127,d0 |
moveq #-1,d1 |
lea IO_BITMAP,a0 |
.0002 |
move.l d1,(a0)+ |
dbra d0,.0002 |
; Give all cores access to the screen |
lea IO_BITMAP+128,a0 |
move.l d1,(a1)+ ; set or clear entire table |
dbra d4,.0001 |
moveq #-1,d1 |
move.w #62,d0 ; 63 more bitmaps to fill |
.0004 |
move.l d1,160(a0) ; all cores have access to semaphores |
move.l d1,164(a0) |
move.l d1,168(a0) |
move.l d1,172(a0) |
swap d0 |
move.w #31,d0 ; 32 bytes for the screen area per bitmap |
move.w #31,d0 ; 32 long words for the screen area per bitmap |
.0003 |
move.l d1,(a0)+ |
move.l d1,(a0)+ ; all cores have access to a screen |
dbra d0,.0003 |
swap d0 |
lea 96(a0),a0 |
addi.b #1,d3 ; do next address space |
movea.l a1,a0 ; a0 points to area for next address space |
dbra d0,.0004 |
rts |
|
473,20 → 548,18
InitRand: |
RandInit: |
movem.l d0/d1,-(a7) |
movec coreno,d0 |
swap d0 |
moveq #RAND_SEMA,d1 |
bsr LockSemaphore |
swap d0 |
lsl.l #6,d0 ; allow 64 streams per core |
move.l d0,RAND_STRM ; select the stream |
move.l #$12345678,RAND_MZ ; initialize to some value |
move.l #$98765432,RAND_MW |
move.l #777777777,RAND_NUM ; generate first number |
movec coreno,d0 |
swap d0 |
moveq #RAND_SEMA,d1 |
bsr UnlockSemaphore |
moveq #37,d0 ; lock semaphore |
moveq #RAND_SEMA,d1 |
trap #15 |
movec coreno,d0 ; d0 = core number |
lsl.l #6,d0 ; allow 64 streams per core |
move.l d0,RAND_STRM ; select the stream |
move.l #$12345678,RAND_MZ ; initialize to some value |
move.l #$98765432,RAND_MW |
move.l #777777777,RAND_NUM ; generate first number |
moveq #38,d0 ; unlock semaphore |
moveq #RAND_SEMA,d1 |
trap #15 |
movem.l (a7)+,d0/d1 |
rts |
|
495,19 → 568,18
|
RandGetNum: |
movem.l d0/d2,-(a7) |
movec coreno,d0 |
swap d0 |
moveq #RAND_SEMA,d1 |
bsr LockSemaphore |
lsl.l #6,d0 |
move.l d0,RAND_STRM ; select the stream |
move.l RAND_NUM,d2 |
clr.l RAND_NUM ; generate next number |
movec coreno,d0 |
swap d0 |
moveq #RAND_SEMA,d1 |
bsr UnlockSemaphore |
move.l d2,d1 |
moveq #37,d0 ; lock semaphore |
moveq #RAND_SEMA,d1 |
trap #15 |
movec coreno,d0 |
lsl.l #6,d0 |
move.l d0,RAND_STRM ; select the stream |
move.l RAND_NUM,d2 ; d2 = random number |
clr.l RAND_NUM ; generate next number |
moveq #38,d0 ; unlock semaphore |
moveq #RAND_SEMA,d1 |
trap #15 |
move.l d2,d1 |
movem.l (a7)+,d0/d2 |
rts |
|
600,11 → 672,12
; ----------------------------------------------------------------------------- |
|
LockSemaphore: |
rts |
movem.l d1/a0,-(a7) ; save registers |
lea semamem,a0 ; point to semaphore memory lock area |
andi.w #255,d1 ; make d1 word value |
lsl.w #2,d1 ; align to memory |
.0001: |
.0001 |
move.l d0,(a0,d1.w) ; try and write the semaphore |
cmp.l (a0,d1.w),d0 ; did it lock? |
bne.s .0001 ; no, try again |
640,6 → 713,7
; ----------------------------------------------------------------------------- |
|
UnlockSemaphore: |
bra ForceUnlockSemaphore |
movem.l d1/a0,-(a7) ; save registers |
lea semamem+$1000,a0 ; point to semaphore memory unlock area |
andi.w #255,d1 ; make d1 word value |
654,13 → 728,11
; ----------------------------------------------------------------------------- |
|
T15LockSemaphore: |
movec coreno,d0 |
or.l RunningTCB,d0 |
movec tr,d0 |
bra LockSemaphore |
|
T15UnlockSemaphore: |
movec coreno,d0 |
or.l RunningTCB,d0 |
movec tr,d0 |
bra UnlockSemaphore |
|
; ----------------------------------------------------------------------------- |
3394,7 → 3466,162
nmeSerial: |
dc.b "Serial",0 |
|
;=============================================================================== |
; Generic I2C routines |
;=============================================================================== |
|
even |
; i2c |
i2c_setup: |
; lea I2C,a6 |
; move.w #19,I2C_PREL(a6) ; setup prescale for 400kHz clock |
; move.w #0,I2C_PREH(a6) |
init_i2c: |
lea I2C2,a6 |
move.b #19,I2C_PREL(a6) ; setup prescale for 400kHz clock, 40MHz master |
move.b #0,I2C_PREH(a6) |
rts |
|
; Wait for I2C transfer to complete |
; |
; Parameters |
; a6 - I2C controller base address |
|
i2c_wait_tip: |
move.l d0,-(a7) |
.0001 |
move.b I2C_STAT(a6),d0 ; wait for tip to clear |
btst #1,d0 |
bne.s .0001 |
move.l (a7)+,d0 |
rts |
|
; Parameters |
; d0.b - data to transmit |
; d1.b - command value |
; a6 - I2C controller base address |
; |
i2c_wr_cmd: |
move.b d0,I2C_TXR(a6) |
move.b d1,I2C_CMD(a6) |
bsr i2c_wait_tip |
move.b I2C_STAT(a6),d0 |
rts |
|
i2c_xmit1: |
move.l d0,-(a7) |
move.b #1,I2C_CTRL(a6) ; enable the core |
moveq #$76,d0 ; set slave address = %0111011 |
move.w #$90,d1 ; set STA, WR |
bsr i2c_wr_cmd |
bsr i2c_wait_rx_nack |
move.l (a7)+,d0 |
move.w #$50,d1 ; set STO, WR |
bsr i2c_wr_cmd |
bsr i2c_wait_rx_nack |
|
i2c_wait_rx_nack: |
move.l d0,-(a7) |
.0001 |
move.b I2C_STAT(a6),d0 ; wait for RXack = 0 |
btst #7,d0 |
bne.s .0001 |
move.l (a7)+,d0 |
rts |
|
;=============================================================================== |
; Realtime clock routines |
;=============================================================================== |
|
rtc_read: |
movea.l #I2C2,a6 |
lea RTCBuf,a5 |
move.b #$80,I2C_CTRL(a6) ; enable I2C |
move.b #$DE,d0 ; read address, write op |
move.b #$90,d1 ; STA + wr bit |
bsr i2c_wr_cmd |
tst.b d0 |
bmi .rxerr |
move.b #$00,d0 ; address zero |
move.b #$10,d1 ; wr bit |
bsr i2c_wr_cmd |
tst.b d0 |
bmi .rxerr |
move.b #$DF,d0 ; read address, read op |
move.b #$90,d1 ; STA + wr bit |
bsr i2c_wr_cmd |
tst.b d0 |
bmi .rxerr |
|
move.w #$20,d2 |
.0001 |
move.b #$20,I2C_CMD(a6) ; rd bit |
bsr i2c_wait_tip |
bsr i2c_wait_rx_nack |
move.b I2C_STAT(a6),d0 |
tst.b d0 |
bmi .rxerr |
move.b I2C_RXR(a6),d0 |
move.b d0,(a5,d2.w) |
addi.w #1,d2 |
cmpi.w #$5F,d2 |
bne .0001 |
move.b #$68,I2C_CMD(a6) ; STO, rd bit + nack |
bsr i2c_wait_tip |
bsr i2c_wait_rx_nack |
move.b I2C_STAT(a6),d0 |
tst.b d0 |
bmi .rxerr |
move.b I2C_RXR(a6),d0 |
move.b d0,(a5,d2.w) |
move.b #0,I2C_CTRL(a6) ; disable I2C and return 0 |
moveq #0,d0 |
rts |
.rxerr |
move.b #0,I2C_CTRL(a6) ; disable I2C and return status |
rts |
|
rtc_write: |
movea.l #I2C2,a6 |
lea RTCBuf,a5 |
move.b #$80,I2C_CTRL(a6) ; enable I2C |
move.b #$DE,d0 ; read address, write op |
move.b #$90,d1 ; STA + wr bit |
bsr i2c_wr_cmd |
tst.b d0 |
bmi .rxerr |
move.b #$00,d0 ; address zero |
move.b #$10,d1 ; wr bit |
bsr i2c_wr_cmd |
tst.b d0 |
bmi .rxerr |
move.w #$20,d2 |
.0001 |
move.b (a5,d2.w),d0 |
move.b #$10,d1 |
bsr i2c_wr_cmd |
tst.b d0 |
bmi .rxerr |
addi.w #1,d2 |
cmpi.w #$5F,d2 |
bne.s .0001 |
move.b (a5,d2.w),d0 |
move.b #$50,d1 ; STO, wr bit |
bsr i2c_wr_cmd |
tst.b d0 |
bmi .rxerr |
move.b #0,I2C_CTRL(a6) ; disable I2C and return 0 |
moveq #0,d0 |
rts |
.rxerr: |
move.b #0,I2C_CTRL(a6) ; disable I2C and return status |
rts |
|
msgRtcReadFail: |
dc.b "RTC read/write failed.",$0A,$0D,$00 |
|
even |
|
;------------------------------------------------------------------------------ |
;------------------------------------------------------------------------------ |
even |
/trunk/software/examples/cputest.asm
4303,6 → 4303,9
cmpi.b #$FF,$00010000 |
bne.s * |
|
scc d0 * Test setting a data register |
cmpi.b #$FF,d0 |
bne.s * |
rts |
|
|