Reviving my Amiga hobby

dizzy · 1599

dizzy

  • Junior Member
  • **
    • Posts: 59
    • Karma: +60/-0
    • YouTube channel
on: December 07, 2021, 01:56:03 AM
After dusting the dirt out of my old Amigas (500) a thought crossed on my mind after seeing all those PiStorm etc. boards that I'll need something like that too...

I had added the 1Mb chip mod to my rev6 A500 but that's not enough. I had also bought the newest Picasso 96 drivers and I want my A500 to use it.

My endeavours with the stm32(f/h) arm boards lead me thinking that I must connect it to my A500...  :o

https://youtu.be/rmbd9AJsqUE
https://youtu.be/cbj7k8EI1Pw

I think I could emulate the m68k with the Arm thumb microprosessor (stm32h7 at 480MHz)
On my Arm board I have 32-bit wide sdram (32 megabytes) and it outputs video to hdmi with sound.

I can up the memory to 256Mb(512Mb?) by using full length pc133 dimms (can be read with 32-bit wide bus unlike the smaller so-dimms)

Some logic needs to be in between the Arm sram bus and Amiga as the Arm shares lines with its sdram and sram controller.
While sram is being delayed by _dtack the video can't be fetched from sdram... enter spartan-6 fpga...

I ordered some PCM9211 216-kHz Digital Audio Interface Transceivers so I could digitize the Amiga sound and redirect it to hdmi and mux it with the sound produced by the Arm processor... (AHI interface?)

Amiga video could also be redirected to hdmi as the Arm can fetch video from multiple sources, quad spi being one. Make the spartan store Amiga video on a buffer and let the Arm fetch it from it via quad spi.

I'll start small and once the 86-pin connector arrives I'll try and get the bus from m68k via the bus arbitration control signals. Bring _br low (pulldown from the get go?) and wait _bg low and _as, _dtack and _bgack high. Should not be too difficult. By the way I think there is some error in Gary.v fpga implementation as it does not use _bgack signal which would mean when low that the Amiga can't use the bus. Lets see...
« Last Edit: December 07, 2021, 02:18:59 AM by dizzy »



AMIGASYSTEM

  • Global Moderator
  • Legendary Member
  • *****
    • Posts: 3740
    • Karma: +69/-2
  • AROS One
    • AROS One
Reply #1 on: December 07, 2021, 02:34:59 AM
I'd be curious to know the performance of PiStorm with AROS 68k even if I have doubts that it can be fast !


dizzy

  • Junior Member
  • **
    • Posts: 59
    • Karma: +60/-0
    • YouTube channel
Reply #2 on: December 07, 2021, 03:42:28 AM
It seems pretty fast...  :) I just don't like Pi's as they aren't that open source.

Yesterday I was converting some PC disk drives for Amiga and stumbled upon this http://amiga.robsmithdev.co.uk/instructions
Arduino Amiga Floppy Disk Reader/Writer aka DrawBridge.

I'd like to have that too but don't have suitable Arduino at hand and using serial port seems a bit outdated. I'll try to make one that uses small stm32 and bulk transfers and control endpoints as now I really don't have any good means to transfer data between my pc and Amiga.

Or maybe something like this?



How big a disk drive could be? Not sure if I could make two internal disk drives DF0: the normal size and then using mountlist from DF0: a second one DF1: but bigger...
Now I have a there a M25P32, 32Mbit (4Mb x 8) serial Flash memory.

My reasoning is that just drop a .ADF on the pc side to "hd" and the micro encodes it with MFM on the flash chip (or encodes it on the fly to save space) No real disks needed.
« Last Edit: December 07, 2021, 04:26:45 AM by dizzy »



Amiwell

  • Legendary Member
  • *****
    • Posts: 2616
    • Karma: +35/-4
  • Peace
Reply #3 on: December 07, 2021, 05:39:40 AM
there is emu68 for pistorm the performance are strabiliant :)



miker1264

  • Legendary Member
  • *****
    • Posts: 1827
    • Karma: +84/-6
Reply #4 on: December 07, 2021, 07:47:33 AM
there is emu68 for pistorm the performance are strabiliant :)

I read about a small floppy controller that fits inside the case of the black external usb floppy drives that can read Amiga disks on PC. With software on the Windows side to make ADF disks.

I think that would be very useful. I'd buy one or two.



Amiwell

  • Legendary Member
  • *****
    • Posts: 2616
    • Karma: +35/-4
  • Peace
Reply #5 on: December 07, 2021, 08:11:27 AM



dizzy

  • Junior Member
  • **
    • Posts: 59
    • Karma: +60/-0
    • YouTube channel
Reply #6 on: December 30, 2021, 01:28:10 PM
I got my connector for the left side of my Amiga 500, perfect fit. I have also ordered PLL clock chips from DigiKey and small smd xor gate. With those two I can generate some multiple frequency from the c1(3.5MHz) and c3(3.5Mhz 90 degrees out of phase) clocks (max 8x7.14Mhz?) (easy part). On my rev6 board I could tie a link and get the 7MHz clock on the expansion also, but I think that it is not possible with all A500 rev boards. I'm thinking synchronous timing with the motherboard... some clocks delayed or ahead...

The sound chips (PCM9211) also arrived, but maybe I won't try to use them (easy to solder tho)... as I'm planning on putting a FPGA or two on my board, so maybe just grap the digital signals?

I've yet again started to read all the m68k patents and looked into VHDL implementations that are freely available. FX68k seems most promising, but it's written in system verilog, I only barely know Xilinx (Spartan-6) VHDL and the chip.

I don't know if I should try to implement my own m68k on VHDL or not. I'm thinking about trying to make m68000 core with some m68010/20 designs in sight. For example with 32-bit wide bus always reading 32-bits if possible so if the first instruction is 16-bit the next one would be already fetched, considering alignment...

Spartan-6 what I've learned can use upto 800MHz on some parts but I've also read that max is around 275MHz, but the Spartan has also dedicated PLL and I can easily phase shift the clocks.

7MHz bus clock for the motherboard, 32-bit instruction word fetch from 32-bit wide bus (16 from motherboard) Quad SPI bus for the kickstart, execute in place (with 32 byte burst read or with larger cache read only, MB never sees them) (could pull the ROM out from the motherboard and read it in from there)... Or reuse the configuration interface and put it in with the FPGA config...

JTAG for the core could also be easily achieved or small stm32 (USB interface) acting as let's say BDM interface or something re-invented.

Phase shifting the let's say 275MHz clock on Spartan-6 could give much higher throughput overall. 7MHz from motherboard but full speed (80 -100 or so MHz) from 32-bit bus and quad spi. Interleaving the 275MHz clock gives better performance. Slower at the fetch but the micro and nano instruction programs (different phase shifted clocks) can be made a lot faster. More micro instructions per fetch clock. Also I think that it is not wise to use synthesizable VHDL code but to target the code for a specific FPGA chip.

For example, Spartan-6 has many 6-bit LUT logic slices, it's not wise to waste them on ALU. Spartan-6 has extremely fast DSP slices for that purpose. Use the LUTs for instruction decoding as in the die shots of real m68k. It has 16-bit instruction bus and negate of that and those are fed to a decoder that only looks for the instruction, e.g this instruction has to have bits sets in these places and on these places they must be zero. Every bit is not checked on that 16-bit instruction. I think the nano code takes care of them. Some instruction bits are directly used by the execution unit.

https://youtu.be/qk74Ghjkky8
https://youtu.be/DEalCnxEoww
« Last Edit: December 30, 2021, 02:24:07 PM by dizzy »



deadwood

  • AROS Developer
  • Legendary Member
  • *****
    • Posts: 1524
    • Karma: +118/-0
Reply #7 on: December 30, 2021, 02:41:29 PM
Good luck with your project. Electronics is something that seems fun, but somehow I never get around to start learning it ;)



dizzy

  • Junior Member
  • **
    • Posts: 59
    • Karma: +60/-0
    • YouTube channel
Reply #8 on: January 04, 2022, 06:56:57 AM
Thank you, although I think my project will never be finished  ;D Just something to occupy my time.

I've started some preliminary VHDL "coding" for my 68k core. I want the opcode decoder to be as thin as possible, so I want it to occupy only LUTx design elements.
I would like them not to be cascaded but to operate on "one stage", (asynchronous with one clk signal) I've not defined all the used opcodes but at the moment the logic to decode is on some parts two stage LUTx. Still pretty fast those LUTx elements, timings for them below. That 375.094MHz timing is because I've not defined where the output signals go so ISE assumes they go to IO pad but the logic really is internal. Two stage LUTx gives 535.906MHz:

I think I need to split the opcodes to only use one stage LUTx's.

My plan for decoding is that the decoder only outputs few microrom addresses (really dum and fast) and forward information directly from the IR "register"

I've set the decoder clock to 200MHz (5ns) and the LUTs are plenty fast for it, giving more than twice the overhead, should be faster with only one stage LUTs.
Need to handcraft the LUT tables i assume and not trust the synthesizer.

https://www.xilinx.com/support/documentation/sw_manuals/xilinx14_7/spartan6_hdl.pdf

EDIT:

Well this is fun... It seems that I need to take account the addressing modes while decoding the opcode otherwise I'd get a match for multiple opcodes.

For instance PEA would match on SWAP and BKPT too, only difference between them is the possible addressing mode:
Code: [Select]
FEDCBA98 76MMMRRR
01001000 01------ PEA
01001000 01000--- SWAP
01001000 01001--- BKPT

I still don't want to make a huge decoder that gives different signals for all possible opcode's addressing modes. (https://og.kervella.org/m68k/m68000.lst)
I think I need to tell the decoder when to use MMMRRR bits too for decoding also and add an offset to the microrom address based on that or something.

Anyway, I need to tell the decoder the current processor mode (user/supervisor)

I have chained 3 6-bit LUTs on one slice to decode 16-bit opcode (LUT0 gets bits0-5, LUT1 gets Q of LUT0 and bits 6-10 finally LUT2 gets Q of LUT1 and bits 11-15) I still have one 6-bit LUT left on the slice. Performance doesn't seem to be impacted as the routing for them is within the slice itself.

EDIT:

These are taken from the end of this listing (https://og.kervella.org/m68k/a1-decode.txt)
I think I will need to feed them together with the opcode to the decoder from the previous IR register.

I'm pretty sure it is used to decode the addressing modes possible for the instructions together with the decoder.

Code: [Select]
fedc ba9 876543210
0000 ... 1........ Dn M Xn        bxxx dn, <adr>
00.1 ... ......... S An/Xn M M Xn move.bw
0010 ... ......... S An/Xn M M Xn move.l
0101 ... .0....... Data S M Xn    addq.bw/subq.bw           
0101 ... ..1...... Data S M Xn    addq.w/subq.w
0100 ... 110...... Dn M Xn        chk.w
0100 ... 0.0......                negx/clr/neg/not.bl + ...
0100 0.. 0.1......                negx/clr/neg/not.w + ...
0100 0.. 010......                negx/clr/neg/not.l
0100 101 0.1......                tst.w tas
0100 101 010......                tst.l
0101 ... .10......                addq/subq.l
1.00 ... .0.......                (etc).b
1.00 ... ..1......                (etc).w
1..1 ... .0.......                (etc).b
1..1 ... 0.1......                sub/cmp/add.w
1.0. ... .10......                or/sub/and.l
1..1 ... .10......                sub/cmp/eor/add.l
1..1 ... 11.......                sub/eor/cmp/add.l
1110 0.. .11......                (as/ls/ro/rox)(r/l).b <adr>




 
« Last Edit: January 05, 2022, 06:56:46 AM by dizzy »



dizzy

  • Junior Member
  • **
    • Posts: 59
    • Karma: +60/-0
    • YouTube channel
Reply #9 on: January 05, 2022, 10:03:54 AM
My Amiga collection grew with one more A500. It's in mint condition and even has the original beige colour. Warranty seal is also unbroken.  :o

I will have to break the seal as trapdoor expansion board's battery has leaked and I'd like to know the boards revision.
Got myself at the same time Tac-2 joystick and external disk drive.

Meanwhile on the opcode decoding front...
Well this is fun (https://www.dropbox.com/scl/fi/gv00qud0xy0i9sdupx3zz/opcodes.ods?dl=0&rlkey=3y29eldhb5ax931ue6c4a56aa)

EDIT to the above, no chronological order here... It seems there is some sort of pattern for all of this after all, just need to tidy those cell borders a bit more... and put rest of the opcodes in the table...  :(
Seems there is a valid reason for invalid addressing modes...  ;D Based upon that I think I can reduce the decoding logic a lot and not use that second table (which I don't yet understand complitely). It would seem that I need a lot LESS LUTs for the decoding  8) LUT is just a 6-bit lookup table for the logic with one output bit but there are a lot of them in Spartan-6. 50% of all the elements are the simplest SLICEs with 4 6-bit LUTs. https://youtu.be/2p4ygfzxyWo?t=216

Below is a snippet of what I used for my testings. It just sets the output if match is found.
std_match takes care of the decoding part with don't care bits ("-") quite normal for VHDL implemented CPU.

I'll make my core such that the RTL schematic can be opened, those opensource cores that I've looked at are a bit rats nets...  :( My near 6GHz (5.9GHz overclocked i5-2550k) machine opens those schematics in about half a day...

The opcode decoder REALLY needs to look at the addressing mode, only difference between some instructions are what is a valid addressing mode for which instruction.

Code: [Select]
library ieee;
use ieee.std_logic_1164.all;

package opcodes is

subtype  opcode_word  is  std_logic_vector(15 downto 0);

constant OpORI     :  opcode_word := "00000000--------";   -- ORI
constant OpANDI    :  opcode_word := "00000010--------";   -- ANDI
constant OpSUBI    :  opcode_word := "00000100--------";   -- SUBI
constant OpADDI    :  opcode_word := "00000110--------";   -- ADDI
constant OpEORI    :  opcode_word := "00001010--------";   -- EORI
constant OpCMPI    :  opcode_word := "00001100--------";   -- CMPI

constant OpRTE     :  opcode_word := "0100111001110011";   -- RTE
constant OpRTS     :  opcode_word := "0100111001110101";   -- RTS

end package;
Code: [Select]
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;

use work.opcodes.all;

entity ADDI is
    Port ( ir_in : in  opcode_word;
           q : out  STD_LOGIC);
end ADDI;

architecture Behavioral of ADDI is

begin

ADDIprocess: process (ir_in)
begin
if std_match(ir_in, OpADDI)  then
q <= '1';
else
q <= '0';
end if;
end process;

end Behavioral;


EDIT:

For ORI, ANDI and EORI I can use one 6-bit LUT from SLICE to decode when M=111 and Xn=100 if set then it is not plain ORI, ANDI or EORI.
Size field is valid for all of them, how convenient.

« Last Edit: January 05, 2022, 03:25:23 PM by dizzy »



dizzy

  • Junior Member
  • **
    • Posts: 59
    • Karma: +60/-0
    • YouTube channel
Reply #10 on: January 15, 2022, 11:46:23 AM
This has been fun so far...

Been reading a lot on the subject, namely these two and some guy (nemesis?) on some board talking about microcode etc...

https://www.dropbox.com/s/5bjpjq3rgrsc98q/DavidLynch.pdf?dl=1
https://www.dropbox.com/s/bskpczjw58c5inp/How%20to%20Flowchart%20for%20Hardware.pdf?dl=1

I had a crack at how to implement data registers and as there is no internal architecture described at the moment and register operations should be fast I decided to implement easy parts of register operations directly on registers.

Easy parts are clr.b, clr.w and clr.l / not.b, not.w and not.l / swap.w (well... swap.w implementation at least simulates...)
Sign extension of data register output fall also in this category but not yet implemented also status flag changes are not taken care of.
Sign extension for the EA calculating unit (dsp48a1) I'm thinking it should have always 32-bit inputs.

Sign extension for the input data also when using moveq.
Something like this:
 - microcode (if any... then it would be the decoder) puts opcode bits 7-0 to data register input buss through mux (=sets dn-buss mux), sets quick flag (and size, well it is meaningless, quick flag takes care of that) and sets the register number (opcode bits 11-9)

I had some trouble while simulating the not with word size... only because I'm stupid...
I simulated first a byte not on register, then word and long... I could not figure out why word not did not work... Well it worked as it should...

d1 = 0x55555555 not.b -> 0x555555aa
d1 = 0x555555aa not.w -> 0x5555aa55
d1 = 0x5555aa55 not.l   -> 0xaaaa55aa

I was just comparing it with my clr function and didn't realize what sort of output I should be expecting... :)



This code takes 28 slices out of 1430 on Spartan-6 and is plenty fast if I read the timings right for 200MHz clock (a bit more than 300MHz)
( 52 slices after swap.w implemented...  >:( , 56 slices after moveq sign extension add on. Maximum clock fell to 244MHz, don't know if I'm reading that right)

Code: [Select]

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;

entity Dn_reg is
port( clk : in  std_logic;

Dn_bwl   : in  std_logic_vector( 1 downto 0);
Dn_set   : in  std_logic;
Dn_quick : in  std_logic;
Dn_op    : in  std_logic_vector( 1 downto 0);
Dn_num   : in  std_logic_vector( 2 downto 0);
Dn_in    : in  std_logic_vector(31 downto 0);
Dn_out   : out std_logic_vector(31 downto 0));
end Dn_reg;

architecture Behavioral of Dn_reg is

type REG_ARRAY is array (0 to 7) of std_logic_vector(31 downto 0);
signal Dn_registers : REG_ARRAY;

begin

DnRegisters: process (clk)

variable Dn_internal : std_logic_vector(31 downto 0);
variable Dn_temp     : std_logic_vector(15 downto 0);

   begin

if rising_edge(clk) then

-- Dn set
if (Dn_set = '1') then
Dn_internal := Dn_registers(to_integer(unsigned(Dn_num)));

if (Dn_quick = '0') then
-- bwl (00.b 01.w 10.l)
case Dn_bwl is
-- byte
when "00" =>
case Dn_op is
-- clr.b
when "11" =>
Dn_internal( 7 downto  0) := "00000000";
-- not.b
when "10" =>
Dn_internal( 7 downto  0) := not Dn_internal( 7 downto  0);
when "00" =>
Dn_internal( 7 downto  0) := Dn_in(7 downto 0);
when others =>
end case;
-- word
when "01" =>
case Dn_op is
-- clr.w
when "11" =>
Dn_internal(15 downto  0) := "0000000000000000";
-- not.w
when "10" =>
Dn_internal(15 downto  0) := not Dn_internal(15 downto  0);
-- swap.w
when "01" =>
Dn_temp := Dn_internal(31 downto 16);
Dn_internal(31 downto 16) := Dn_internal(15 downto  0);
Dn_internal(15 downto  0) := Dn_temp;
when "00" =>
Dn_internal(15 downto  0) := Dn_in(15 downto 0);
when others =>
end case;
-- long
when "10" =>
case Dn_op is
-- clr.l
when "11" =>
Dn_internal(31 downto  0) := "00000000000000000000000000000000";
-- not.l
when "10" =>
Dn_internal(31 downto  0) := not Dn_internal(31 downto  0);
when "00" =>
Dn_internal(31 downto  0) := Dn_in(31 downto  0);
when others =>
end case;
when others =>
end case;
-- moveq (Dn_quick) sign extend 8-bit input data to full 32-bits
-- does not care for the Dn_bwl size (would be redundant)
else
Dn_internal( 7 downto  0) := Dn_in( 7 downto  0);
Dn_internal(31 downto  8) := (others => Dn_in(7));
end if;
Dn_registers(to_integer(unsigned(Dn_num))) <= Dn_internal;
else
Dn_out <= Dn_registers(to_integer(unsigned(Dn_num)));
end if;

end if;
end process;

end Behavioral;



« Last Edit: January 15, 2022, 03:18:31 PM by dizzy »



Samurai_Crow

  • Junior Member
  • **
    • Posts: 88
    • Karma: +32/-0
  • Hobby coder
Reply #11 on: January 15, 2022, 03:14:41 PM
How serious do you want to get into this?  There's a VHDL 68020/030 core at https://github.com/AmicableComputers/wf68k30L if interested.  It only lacks caches and a barrel shifter in the stage 1 pipeline decoder.  It's not very simple for a beginner though.

Also, I've heard shifts are expensive in FPGA implementations.



dizzy

  • Junior Member
  • **
    • Posts: 59
    • Karma: +60/-0
    • YouTube channel
Reply #12 on: January 15, 2022, 03:23:43 PM
Thanks! That one I had not noticed

For the shifter on Spartan-6 one could use two dsp48a1 cores to make 18-bit barrel shifter, page 35

https://www.xilinx.com/support/documentation/user_guides/ug389.pdf

Had a look at that 030-core, there's no way to fit that on xc6slx9 144-pin Spartan. Managed to fit it to xc6slx45 bga Spartan. It used 5,119 out of 6,822 slices (75%)

EDIT:

What I'd like to have is basic 68000 with some things taken from 68010, CPU32 and 68020.
From 68010 of course that loop thing + VBR.
From CPU32 a short pipeline.
From 68020 fetching 32-bit opcode when possible.
 (4. If the instruction is a single-word instruction causing a branch, the second word is not used.
 But because this word is fetched by the preceding instruction, it is impossible to avoid this
 superfluous fetch.) Except when the second word is fetched at the same time as the word being executed when read through 32-bit bus then there is no time penalty.

Plus I would not mind if it ran with clock speeds above 100MHz or so.

Bus negotiating would also be mirrored, no one could ask the bus but my Spartan would ask for it... for Amiga use of course.

Also a Quad SPI eeprom housing kickstart, so a dual/triple bus. Quad SPI (with ICache), 16-bit parallel motherboard bus and or combined to 32-bit parallel bus.

That 030-core was wider than taller, I want massively parallel units, e.g the design should be taller than what it is wide.

EDIT:

What I also think I've learned is that reset signal as mostly used on VHDL codes is really not a reset at all. FPGA comes out of reset when it has loaded the configuration bitstream, if one truly wants to reset the FPGA then it needs to be reprogrammed. STARTUP_SPARTAN6 primitive should provide that from fabric logic. Signals etc. should have default state stated and they are programmed to that state at the same time as the logic is programmed.

EDIT: With a quick test this seems to work just nicely, also GTS sets pins to high impedance.

EDIT: In order to have any change to fit any 68000 core on to this Spartan-6 (xc6slx9 144-pin package) I need to target it specifically, e.g use what is already in silicon and not use for those things the logic fabric.

Why this part? It is easily soldered smd component, not a bga part.

Code: [Select]

CFGCLK Output 1 Configuration logic main clock output.
CFGMCLK Output 1 Configuration internal oscillator clock output.
CLK Input 1 User startup-clock input
EOS Output 1 Active high output signal indicates the End Of Configuration.
GSR Input 1 Global Set/Reset (GSR) input (GSR cannot be used for the port name).
GTS Input 1 Global Tristate (GTS) input (GTS cannot be used for the port name).
KEYCLEARB Input 1 Clear AES Decrypter Key input from Battery-Backed RAM (BBRAM).

STARTUP_SPARTAN6_inst : STARTUP_SPARTAN6
   port map (
      CFGCLK    => open,
      CFGMCLK   => open,
      EOS       => open,
      CLK       => '0',
      GSR       => not nRESET,
      GTS       => not nRESET,
      KEYCLEARB => '0'
);

EDIT: For the e-clock generating I plan on using the PLL_ADV primitive, when fed with 7MHz from the motherboard I can set a divider for it to produce 0.7MHz clock with correct duty cycle as that is also programmable. Synchronization would then be automatic as the 0.7MHz clock would be used to trigger and a signal set accordingly.

Code: [Select]
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
library UNISIM;
use UNISIM.VComponents.all;

entity pll_clocks is
    Port ( CLK_50M     : in  STD_LOGIC;
           RESET       : in  STD_LOGIC;
   CLK_E       : out  STD_LOGIC;
           CLK_7M      : out  STD_LOGIC;
   CLK_200M_p1 : out  STD_LOGIC;
   CLK_200M_p2 : out  STD_LOGIC;
           LOCKED      : out  STD_LOGIC);
end pll_clocks;

architecture Behavioral of pll_clocks is

signal CLKFB           : std_logic;

begin

-- Using MojoV3 we have 50MHz input clock
-- On Amiga we can get 3.54MHz 7.09MHz or multiples
-- PLL takes as low as 5MHz
-- Use PLL to generate e_clock

-- these are just some values used for testing, I have 100MHz scope with 20MHz sampling frequency... :)
-- 50MHz * 8 / DIVIDE

   PLL_BASE_inst : PLL_ADV
   generic map (
      CLKFBOUT_MULT => 8,                 
      CLKOUT0_DIVIDE => 50, CLKOUT0_PHASE =>  0.0,
      CLKOUT1_DIVIDE => 100, CLKOUT1_PHASE =>  0.0,
      CLKOUT2_DIVIDE => 100, CLKOUT2_PHASE => 90.0,
      CLKOUT3_DIVIDE => 50, CLKOUT3_PHASE =>  0.0, CLKOUT3_DUTY_CYCLE => 0.4,
      CLK_FEEDBACK => "CLKFBOUT",
      CLKIN1_PERIOD => 20.0,
      DIVCLK_DIVIDE => 1
   )
      port map (
      CLKFBOUT => CLKFB,
      CLKOUT0  => CLK_7M,
      CLKOUT1  => CLK_200M_p1,
      CLKOUT2  => CLK_200M_p2,
      CLKOUT3  => CLK_E,
      CLKOUT4  => open,
      CLKOUT5  => open,
      LOCKED   => LOCKED,     
      CLKFBIN  => CLKFB,   
      CLKIN1    => CLK_50M,
CLKIN2    => '0',
CLKINSEL => '1',
DADDR => "00000",
DCLK => '0',
DEN => '0',
DI => "0000000000000000",
DWE => '0',
REL => '0',
      RST      => RESET --'0'
   );
end Behavioral;

« Last Edit: January 15, 2022, 08:04:45 PM by dizzy »



Samurai_Crow

  • Junior Member
  • **
    • Posts: 88
    • Karma: +32/-0
  • Hobby coder
Reply #13 on: January 16, 2022, 09:10:26 PM
http://eab.abime.net/showpost.php?p=1527380&postcount=516 shows how to reimplement the core's registers using block memory to save on its size.



dizzy

  • Junior Member
  • **
    • Posts: 59
    • Karma: +60/-0
    • YouTube channel
Reply #14 on: January 17, 2022, 04:50:52 AM
Hi, and thanks again.

Would take too much out of the fun if I copied someone else's work... but thank you nevertheless.

I sort of a plan to use blockram for other purposes (that is if I have a plan...  ;D)
Microcode and caches would occupy some of them. I managed to reduce the slice count for my register implementation to 50 slices and the speed increased also.

I'm not getting anywhere as I need something to show me whats going on inside the FPGA and therefore I'm now doing a debugger (BDM) with Qt-creator.
I need to make some sort of PCB housing the Spartan and stm32f103 micro. Debugger would communicate via usb to the micro and it would be in charge of the bdm.

stm32f103 would also program the Spartan spi configuration eeprom chip and the one housing kickstart via usb. It's a bit faster that way than to use the Xilinx cable and create configuration files etc...