Bringing up a 65org16 core
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Bringing up a 65org16 core
Maybe the Spartan 6 would be a better choice for the 32-bit version, regarding the ripple carry issue?
Re: Bringing up a 65org16 core
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...
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
Re: Bringing up a 65org16 core
State machine is usually one-hot encoded, that means there's one flip flop for each state.
Re: Bringing up a 65org16 core
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.
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Bringing up a 65org16 core
enso wrote:
...Not to mention that in real life SRAM is slowing us down anyway.
Re: Bringing up a 65org16 core
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.
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.
Last edited by MichaelM on Wed Nov 27, 2013 12:39 am, edited 1 time in total.
Michael A.
-
ElEctric_EyE
- Posts: 3260
- Joined: 02 Mar 2009
- Location: OH, USA
Re: Bringing up a 65org16 core
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...
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.
MichaelM wrote:
... I posted a description of that process here...
I'll post future questions in there. Thanks!
Re: Bringing up a 65org16 core
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!
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
Re: Bringing up a 65org16 core
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.
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.
Re: Bringing up a 65org16 core
Ah, of course! Here is my .bmm file (although the location is bound to be different)
Code: Select all
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
Re: Bringing up a 65org16 core
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.
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.
Re: Bringing up a 65org16 core
Here is the 1K x 16 BRAM module:
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.
Code: Select all
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)
);
endmoduleOn 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
Re: Bringing up a 65org16 core
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:
You may have already tried something like this. If so, let me know. I've got a couple of other ideas to try.
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: Select all
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: Select all
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;
Michael A.
Re: Bringing up a 65org16 core
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)
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...
Code: Select all
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;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