6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Tue Nov 12, 2024 6:23 pm

All times are UTC




Post new topic Reply to topic  [ 30 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Tue Nov 26, 2013 7:28 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
Maybe the Spartan 6 would be a better choice for the 32-bit version, regarding the ripple carry issue?

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 26, 2013 7:30 pm 
Offline
User avatar

Joined: Sat Sep 29, 2012 10:15 pm
Posts: 904
Probably overall a better choice, although I can't imagine the carry chain being that much faster.

I would still like to squeeze the most out of my Spartan 3 chips for a while more. The prices will come down by then...

_________________
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 26, 2013 7:32 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
State machine is usually one-hot encoded, that means there's one flip flop for each state.


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 26, 2013 7:34 pm 
Offline
User avatar

Joined: Tue Nov 16, 2010 8:00 am
Posts: 2353
Location: Gouda, The Netherlands
As far as I know Spartan 6 carry chain is comparable in design as the Spartan 3 (but I could be mistaken, I haven't looked at the specifics in a while). Spartan 6 is a more modern chip, so it's probably going to be a bit faster overall, due to process technology improvements.


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 26, 2013 11:53 pm 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
enso wrote:
...Not to mention that in real life SRAM is slowing us down anyway.

You've done experiments with data2mem... Is there anyway to load the FPGA blockRAM with external hardware without resetting the machine?

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 27, 2013 12:21 am 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
I am sure that you are aware that all block RAM in the FPGA is dual ported. If you are not using one of the ports, then you may use it to load the block RAM from external HW without resetting the FPGA.

That said, you appear to be under the impression that data2mem will load the block RAMs. It does not do that. Instead it prepares a data file that bitgen uses to modify the configuration bitstream bits corresponding to the selected block RAMs. In this manner, the block RAMs can be loaded from by reconfiguring the FPGA. In essence, the FPGA is reset during reprogramming of the configuration image.

The benefit of data2mem is that synthesis and PAR are not required to modify the contents of the block RAM in which your program is stored. The time savings is exceptional.

When working to prove out my M65C02 development board with my M16C5x soft-microcontroller, I figured out how the block RAMs were organized and created the necessary .bmm and .mem files, and enabled BMM processing in the mapper and bitgen tools. I posted a description of that process here.

If you are interested in working out whether you can use data2mem for your 65Org16, I can help with that next week. Just let me know.

_________________
Michael A.


Last edited by MichaelM on Wed Nov 27, 2013 12:39 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 27, 2013 12:36 am 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
MichaelM wrote:
I am sure that you are aware that all block RAM in the FPGA is dual ported. If you are not using one of the ports, then you may use to load the block RAM from external HW without resetting the FPGA...

This needs to be explored!!!
MichaelM wrote:
...If you are interested in working out whether you can use data2mem for your 65Org16, I can help with that next week. Just let me know.

I would appreciate that! I have been re-synthesizing the entire project after making even a simple variable change in the 65Org16.b software
MichaelM wrote:
... I posted a description of that process here...

Yes, I tried to follow the details in that thread, but I got lost.
I'll post future questions in there. Thanks!

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 27, 2013 1:24 am 
Offline
User avatar

Joined: Sat Sep 29, 2012 10:15 pm
Posts: 904
Michael, you are of course correct. My language was sloppy.

Since the bootcode is a serial loader, it needs to be dealt with extremely rarely. Hardly worth creating an external BRAM loader just for the bootloader which takes about 3 seconds to recompile and reconfigure the FPGA.

I am already using data2mem for 65Org16 (and in CHOCHI workflows). I wrote a variation on bin2mem (I think you wrote the original if I am not mistaken) called bin2mem16, which generates a 16-bit .mem file suitable for 65Org16.

Thank you for your offer!

_________________
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 27, 2013 2:00 am 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
enso:

I should have directed my last post to EEyE. He and I have agreed to work this issue for his projects after Thanksgiving. At that time, perhaps you could also share your BMM file for your 65Org16 project. It will likely require some mods for his specific configuration, but I think any changes required should be fairly straightforward since it's a common code base.

Have a happy Thanksgiving and safe travels.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 27, 2013 2:23 am 
Offline
User avatar

Joined: Sat Sep 29, 2012 10:15 pm
Posts: 904
Ah, of course! Here is my .bmm file (although the location is bound to be different)
Code:
ADDRESS_SPACE top_picoblaze_rom RAMB16 INDEX_ADDRESSING [0x00000000:0x000003FF]
  BUS_BLOCK
    bram/bram0 [15:0] PLACED = X0Y0;
  END_BUS_BLOCK;
END_ADDRESS_SPACE;

_________________
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 27, 2013 2:49 am 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
Thanks very much.

Just curious about your method for instantiating your block RAMs. From your posts in this thread it is clear that you prefer instantiation instead of inference, but you don't mention the methodology you use for instantiation. Do you instantiate your block RAMs using HDL library elements or coregen macros? Further, have you had any success in using data2mem to patch block RAMs when multiple RAMs are used?

The BMM for your 65Org16 identifies a single RAMB16 in a x16 configuration. I had a thought that the multiple block RAM issue you mentioned in that other may have to do with naming your memory as pertaining to a PicoBlaze. My original BMM named a PPC440 as its target, but I looked back in that thread and saw that my M16C5x BMM file named the target a generic name, PROM.

I will investigate this subject further this weekend when working with EEyE. This is a good time as any to get the XC3S200A-4VQ100I version of my development board running my M65C02 soft-microprocessor, and put Klaus' complete test program in the extra internal block RAM of that FPGA. Data2Mem would be a great help in running all of his test suite on the target. So far, I've had to partition the test suite in the simulator because of its run time. ISim can not run his test suite and capture all of the signals I like to view. When it runs out of memory, physical and virtual, it simply crashes.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 27, 2013 5:25 am 
Offline
User avatar

Joined: Sat Sep 29, 2012 10:15 pm
Posts: 904
Here is the 1K x 16 BRAM module:
Code:
module BRAM1KX16 (
  input CLK
, input [9:0] A
, output [15:0] DO
, input  [15:0] DI
, input EN
, input WR
);
(*LOC="RAMB16_X0Y0"*)
RAMB16_S18
#(  .INIT(18'h00000),.SRVAL(18'h00000))
bram0(
  .CLK(CLK), .ADDR(A[9:0]), .DO(DO[15:0]), .DI(DI[15:0]),  .WE(WR&EN),
  .EN(1), .SSR(~EN), //on deselect, output 00
  .DIP(0)
);
endmodule


Note that the LOC directive matches the .bmm file's x-y coordinates. Also, I instantiate this module as 'bram', therefore the name in the .bmm file is 'bram/bram0'

On the topic of .bmm naming conventions - I assumed that the picoblaze name is just a symbol and does not affect anything.

_________________
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 27, 2013 3:53 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
Yes, the name given in the BMM file for the block RAM is just a name. Any relation to the Xilinx soft-core processors is just a coincidence. It appears that Data2MEM does not place any restrictions on the reference provided for the block RAM array specified in the BMM file.

The examples given in the Data2MEM user's guide do give the impression that the tool was designed specifically to patch program and data memory for Xilinx soft-core processors. It is a good thing that is not the case, and that it can be used for the purpose of patching the block RAM initialization data of any configuration bit stream.

Your module is instantiating an HDL library element for the Spartan-3 family. In regards to your question of how to use Data2MEM with multiple block RAMs, I will try the following:

Code:
module BRAM4KX16 (
  input  CLK
, input  [11:0] A
, output [15:0] DO
, input  [15:0] DI
, input  EN
, input  WR
);

//  MAM, 13K27, Increase memory array from 1024 x 16 to 4096 x 16.

assign RAM_EN0 = EN & (A[11:10] == 2'b00);

(*LOC="RAMB16_X0Y0"*)
RAMB16_S18
#(  .INIT(18'h00000),.SRVAL(18'h00000))
bram0(
  .CLK(CLK), .ADDR(A[9:0]), .DO(DO[15:0]), .DI(DI[15:0]),  .WE(WR&RAM_EN0),
  .EN(1), .SSR(~RAM_EN0), //on deselect, output 00
  .DIP(0)
);

assign RAM_EN1 = EN & (A[11:10] == 2'b01);

(*LOC="RAMB16_X0Y1"*)
RAMB16_S18
#(  .INIT(18'h00000),.SRVAL(18'h00000))
bram1(
  .CLK(CLK), .ADDR(A[9:0]), .DO(DO[15:0]), .DI(DI[15:0]),  .WE(WR&RAM_EN1),
  .EN(1), .SSR(~RAM_EN1), //on deselect, output 00
  .DIP(0)
);

assign RAM_EN2 = EN & (A[11:10] == 2'b10);

(*LOC="RAMB16_X0Y3"*)
RAMB16_S18
#(  .INIT(18'h00000),.SRVAL(18'h00000))
bram2(
  .CLK(CLK), .ADDR(A[9:0]), .DO(DO[15:0]), .DI(DI[15:0]),  .WE(WR&RAM_EN2),
  .EN(1), .SSR(~RAM_EN2), //on deselect, output 00
  .DIP(0)
);

assign RAM_EN3 = EN & (A[11:10] == 2'b11);

(*LOC="RAMB16_X0Y3"*)
RAMB16_S18
#(  .INIT(18'h00000),.SRVAL(18'h00000))
bram3(
  .CLK(CLK), .ADDR(A[9:0]), .DO(DO[15:0]), .DI(DI[15:0]),  .WE(WR&RAM_EN3),
  .EN(1), .SSR(~RAM_EN3), //on deselect, output 00
  .DIP(0)
);

endmodule


Code:
ADDRESS_SPACE bram RAMB16 INDEX_ADDRESSING [0x00000000:0x00001FFF]
 
  // Address Range: 0x0000:0x07FF -- Each Block RAM is 2kB in size.

  BUS_BLOCK
    bram/bram0 [15:0] PLACED = X0Y0;
  END_BUS_BLOCK;
 
  // Address Range: 0x0800:0x0FFF -- Each Block RAM is 2kB in size.
 
  BUS_BLOCK
    bram/bram1 [15:0] PLACED = X0Y1;
  END_BUS_BLOCK;
 
  // Address Range: 0x1000:0x17FF -- Each Block RAM is 2kB in size.
 
  BUS_BLOCK
    bram/bram2 [15:0] PLACED = X0Y2;
  END_BUS_BLOCK;
 
  // Address Range: 0x1800:0x1FFF -- Each Block RAM is 2kB in size.
 
  BUS_BLOCK
    bram/bram3 [15:0] PLACED = X0Y3;
  END_BUS_BLOCK;

END_ADDRESS_SPACE;


You may have already tried something like this. If so, let me know. I've got a couple of other ideas to try.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 27, 2013 5:48 pm 
Offline
User avatar

Joined: Sat Sep 29, 2012 10:15 pm
Posts: 904
In this situation, it would make more sense to wire the BRAMs as 4 4-bit BRAMS, each responsible for 4 bits out of 16. This way they can all share the address lines, avoiding address decoding logic as well as the 4-1 mux at the end. The .bmm file is then (I think)
Code:
ADDRESS_SPACE bram RAMB16 INDEX_ADDRESSING [0x00000000:0x00001FFF]
  BUS_BLOCK
    bram/bram0 [3:0] PLACED = X0Y0;
    bram/bram1 [7:4] PLACED = X0Y1;
    bram/bram2 [11:8] PLACED = X0Y2;
    bram/bram3 [15:12] PLACED = X0Y3;
  END_BUS_BLOCK;
END_ADDRESS_SPACE;


The instantiation code is trivial, just wire up the right bits to the right BRAM data bus.

Confusing points: Which bits go where? I never got this to work, but mostly because I was still debugging the 65Org16 circuit and nothing really worked. There are a few opportunities to place the bits backwards, wire the BRAMS backwards, etc.

In my case I am happy with just a single BRAM (1K) bootloader, so it's an academic point.

Michael, your instantiation code above has a typo - the LOC directive for "RAMB16_X0Y3" is repeated twice and X0Y2 is never used...

_________________
In theory, there is no difference between theory and practice. In practice, there is. ...Jan van de Snepscheut


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 27, 2013 8:29 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
Thanks, typo from copying and pasting blocks of code.

_________________
Michael A.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 30 posts ]  Go to page Previous  1, 2

All times are UTC


Who is online

Users browsing this forum: No registered users and 11 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: