Closed FlyingxDutch closed 5 years ago
Here is ziped full project - ISE 14,7 : BrieySoCNext06.zip
And here is diagram of new top module BrieySoC.v
And here internal organisation of Mimas V.2 DDR memory chip (MT46H32M16LF)
@FlyingxDutch You might want to look at using LiteX with VexRISC-V we already have support for DDR on the MimasV2 board.
There is a tutorial for getting micropython running on MimasV2 here -> https://fupy.github.io/MimasV2.html
@FlyingxDutch Briey is only support SDRAM-SDR. Sorry :)
Hello, now that i am aware, how it is implemented I think it is time to close that issue. I will look at LiteX VexRISC-V implementation as @mithro adviced me.
Thanks all for quick answers and Regards
Hello,
for some time I am trying to run "Briey SoC" (generated from SpinalHDL according to given instruction) on Spartan6 based FPGA board "Mimas V.2" from "Numat Lab". Here is link to this board description (on Numato website): https://numato.com/product/mimas-v2-spartan-6-fpga-development-board-with-ddr-sdram
In order to launch Briey.v project on real FPGA board (Mimas V.2) I altered the original design. The major changes are: 1) Added (PLL) instance CLKGEN (Xilinx IP core) for generating clocks: AXI bus clock, VGA clock, DDR memory clock
2) Added input buffer (IBUFG) for input JTAG clock (signal: io_jtag_tck)
3) Generation of differential clock (two lines) for DRR memory from single clock (100 MHz PLL). Added primitive OBUFDS.
4) Two directional buffer (instance DDRDataBuffer - "SelectI/O Wizard IP core") added to Briey bus and DDR memory data bus (16 bit wide)
5) In "User constraints file" (BrieySOC.ucf) maped properly most of ports of top module (BrieySOC). There is lack of few important signals - I will write about this later.
The main issue I had encountered is related to internal Briey DDR memory controller. My FPGA board Mimas v.2 has on-board SDRAM (DDR1 RAM memory) chip: MT46H32M16LF. This chip requires diferential clock (two lines) and also two-directional 16-bit wide data bus.
In the Briey design thera are two one-directional 16-bit buses (one for write and second for read). To solve that issue I added Xilinx IPcore named "Select I/O Wizard"
I reconstructed the original design Briey.v with new top module named "BrieySOC", here is it's code (Verilog): `/ Top module: Briey SOC /
module BrieySOC( input io_asyncReset, input Clk100Mhz, input io_jtag_tms, input io_jtag_tdi, output io_jtag_tdo, input io_jtag_tck, output [12:0] io_sdram_ADDR, output [1:0] io_sdram_BA, //input [15:0] io_sdram_DQ_read, //output [15:0] io_sdram_DQ_write, inout [15:0] io_sdram_DATA, output io_sdram_DQ_writeEnable, output [1:0] io_sdram_DQM, output io_sdram_CASn, output io_sdram_CKE, output io_sdram_CSn, output io_sdram_RASn, output io_sdram_WEn, output io_sdram_clk, output io_sdram_clk_n, input [3:0] io_gpioA_read, output [3:0] io_gpioA_write, output [3:0] io_gpioA_writeEnable, output io_uart_txd, input io_uart_rxd, output io_vga_vSync, output io_vga_hSync, output io_vga_colorEn, output [4:0] io_vga_color_r, output [5:0] io_vga_color_g, output [4:0] io_vga_color_b, input io_timerExternal_clear, input io_timerExternal_tick, input io_coreInterrupt ); //----------------------------------------------------
//-- Connecting wires wire clkAXIOut; wire clkLOCKED; wire clkVGAOut; wire clkBuf100MHz; wire clkDDR100MHz; wire clkJTAGBuf; wire CLK_TO_PINS; wire TRISTATE_OUTPUT; wire CLK_RESET; wire [15:0] io_sdram_DQ_read; wire [15:0] io_sdram_DQ_write;
CLKWizard CLKGEN (// Clock in ports .CLK_IN1(Clk100Mhz),
// Clock out ports .CLK_OUT1(clkAXIOut), //50 MHz AXI clock .CLK_OUT2(clkVGAOut), //25.175 MHz VGA clock .CLK_OUT3(clkBuf100MHz), //100 MHz DDR memory clock // Status and control signals .RESET(io_asyncReset), .LOCKED(clkLOCKED));
( .O(clkJTAGBuf), .I(io_jtag_tck) );
//Output buffer for DDR diff clock (out) OBUFDS #( .IOSTANDARD("DIFF_MOBILE_DDR") ) OBUFDS_01 ( .O(io_sdram_clk), .OB(io_sdram_clk_n), .I(clkBuf100MHz) );
//---- DDR memory bufer bi-directional ---------
BiDirBuffer DDRDataBuffer ( .DATA_TO_AND_FROM_PINS(io_sdram_DATA), //Bi-Directional pins .DATA_IN_TO_DEVICE(io_sdram_DQ_read), //Output pins // From the device out to the system .DATA_OUT_FROM_DEVICE(io_sdram_DQ_write), //Input pins .CLK_TO_PINS(CLK_TO_PINS), //Output pins
);
//---- CPU instance ---------
Briey SoC( .io_asyncReset(io_asyncReset), .io_axiClk(clkAXIOut), .io_vgaClk(clkVGAOut), .io_jtag_tms(io_jtag_tms), .io_jtag_tdi(io_jtag_tdi), .io_jtag_tdo(io_jtag_tdo), .io_jtag_tck(clkJTAGBuf), .io_sdram_ADDR(io_sdram_ADDR), .io_sdram_BA(io_sdram_BA), .io_sdram_DQ_read(io_sdram_DQ_read), .io_sdram_DQ_write(io_sdram_DQ_write), .io_sdram_DQ_writeEnable(io_sdram_DQ_writeEnable), .io_sdram_DQM(io_sdram_DQM), .io_sdram_CASn(io_sdram_CASn), .io_sdram_CKE(io_sdram_CKE), .io_sdram_CSn(io_sdram_CSn), .io_sdram_RASn(io_sdram_RASn), .io_sdram_WEn(io_sdram_WEn), .io_gpioA_read(io_gpioA_read), .io_gpioA_write(io_gpioA_write), .io_gpioA_writeEnable(io_gpioA_writeEnable), .io_uart_txd(io_uart_txd), .io_uart_rxd(io_uart_rxd), .io_vga_vSync(io_vga_vSync), .io_vga_hSync(io_vga_hSync), .io_vga_colorEn(io_vga_colorEn), .io_vga_color_r(io_vga_color_r), .io_vga_color_g(io_vga_color_g), .io_vga_color_b(io_vga_color_b), .io_timerExternal_clear(io_timerExternal_clear), .io_timerExternal_tick(io_timerExternal_tick), .io_coreInterrupt(io_coreInterrupt)
);
endmodule
I mapped most of Briey ports in user constraint file, here is it's current code:
#--------------------------------------------------- NET "Clk100Mhz" LOC = V10 | IOSTANDARD = LVCMOS33 | PERIOD = 100MHz ;NET "io_asyncReset" LOC = M18 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST | PULLUP; #SW1
###################################################################################################################################################
HEADER P6
################################################################################################################################################### NET "io_jtag_tms" LOC = U7 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 1 Header P6 NET "io_jtag_tdi" LOC = V7 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 2 NET "io_jtag_tdo" LOC = T4 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 3 NET "io_jtag_tck" LOC = V4 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 4 - issue
-------------------------- LPDDR RAM START--------------------------------------------------------------------
NET "calib_done" LOC = P15 | IOSTANDARD = LVCMOS33;
NET "error" LOC = P16 | IOSTANDARD = LVCMOS33;
NET "c3_sys_rst_n" LOC = L15 | IOSTANDARD = LVCMOS33 | PULLDOWN; # Pin 7 of Header P9
NET "io_sdram_ADDR[0]" LOC = J7 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_ADDR[10]" LOC = F4 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_ADDR[11]" LOC = D3 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_ADDR[12]" LOC = G6 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_ADDR[1]" LOC = J6 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_ADDR[2]" LOC = H5 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_ADDR[3]" LOC = L7 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_ADDR[4]" LOC = F3 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_ADDR[5]" LOC = H4 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_ADDR[6]" LOC = H3 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_ADDR[7]" LOC = H6 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_ADDR[8]" LOC = D2 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_ADDR[9]" LOC = D1 | IOSTANDARD = MOBILE_DDR;
NET "io_sdram_BA[0]" LOC = F2 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_BA[1]" LOC = F1 | IOSTANDARD = MOBILE_DDR;
NET "io_sdram_clk" LOC = G3 | IOSTANDARD = DIFF_MOBILE_DDR; NET "io_sdram_clk_n" LOC = G1 | IOSTANDARD = DIFF_MOBILE_DDR;
NET "io_sdram_DATA[0]" LOC = L2 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_DATA[10]" LOC = N2 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_DATA[11]" LOC = N1 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_DATA[12]" LOC = T2 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_DATA[13]" LOC = T1 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_DATA[14]" LOC = U2 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_DATA[15]" LOC = U1 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_DATA[1]" LOC = L1 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_DATA[2]" LOC = K2 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_DATA[3]" LOC = K1 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_DATA[4]" LOC = H2 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_DATA[5]" LOC = H1 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_DATA[6]" LOC = J3 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_DATA[7]" LOC = J1 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_DATA[8]" LOC = M3 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_DATA[9]" LOC = M1 | IOSTANDARD = MOBILE_DDR;
NET "io_sdram_CASn" LOC = K5 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_CKE" LOC = H7 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_RASn" LOC = L5 | IOSTANDARD = MOBILE_DDR; NET "io_sdram_WEn" LOC = E3 | IOSTANDARD = MOBILE_DDR;
-------------------------- LPDDR RAM END --------------------------------------------------------------------
##################################################################################################################################################
HEADER P7
###################################################################################################################################################
NET "io_gpioA_read[0]" LOC = U8 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 1 NET "io_gpioA_read[1]" LOC = V8 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 2 NET "io_gpioA_read[2]" LOC = R8 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 3 NET "io_gpioA_read[3]" LOC = T8 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 4 NET "io_gpioA_write[0]" LOC = R5 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 5 NET "io_gpioA_write[1]" LOC = T5 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 6 NET "io_gpioA_write[2]" LOC = T9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 7 NET "io_gpioA_write[3]" LOC = V9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 8
###################################################################################################################################################
HEADER P8
################################################################################################################################################### NET "io_gpioA_writeEnable[0]" LOC = R11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 1 NET "io_gpioA_writeEnable[1]" LOC = T11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 2 NET "io_gpioA_writeEnable[2]" LOC = R10 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 3 NET "io_gpioA_writeEnable[3]" LOC = T10 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 4 NET "io_vga_colorEn" LOC = U13 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 5 : VGA output NET "io_timerExternal_clear" LOC = V13 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 6 : Ext. timer NET "io_timerExternal_tick" LOC = U11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 7 : Ext. timer NET "io_coreInterrupt" LOC = V11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; #Pin 8 : Ext. interrupt
###################################################################################################################################################
UART Interface
################################################################################################################################################### NET "io_uart_txd" LOC = A8 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; NET "io_uart_rxd" LOC = B8 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
###################################################################################################################################################
VGA - less color resolution than in Briey
################################################################################################################################################### NET "io_vga_hSync" LOC = B12 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; NET "io_vga_vSync" LOC = A12 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "io_vga_color_r[4]" LOC = C9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; NET "io_vga_color_r[3]" LOC = B9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; NET "io_vga_color_r[2]" LOC = A9 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "io_vga_color_g[5]" LOC = C11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; NET "io_vga_color_g[4]" LOC = A10 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; NET "io_vga_color_g[3]" LOC = C10 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
NET "io_vga_color_b[4]" LOC = A11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ; NET "io_vga_color_b[3]" LOC = B11 | IOSTANDARD = LVCMOS33 | DRIVE = 8 | SLEW = FAST ;
But I still don't known how to map few important DDR memory signals. The problem is that DDR chip on Mimas V2 has different internal arrangment. I don't know how to map/generate in Verilog code these signals for MT46H32M16LF memory chip:
#NET "mcb3_dram_dm" LOC = K3 | IOSTANDARD = MOBILE_DDR;NET "mcb3_dram_dqs" LOC = L4 | IOSTANDARD = MOBILE_DDR;
But I don't know how to generate these signals from original signals of Briey DDR controler. I am aware that these signals are important for proper timing of DDR memory.
The last issue is that I am not sure if added two-directional buffer for busses between original Briey design and on-board DDR memory is proper (I am not sue if it lack of control direction of data-flow in it, but there isn't any otion for that in Xilinx "IP core" named "Select I/O Wizard).
I had posted and detailed describe my attempts to launch Briey SOC on Mimas V.2 Board on edaboard.com forum, but I didn't get answer solving my issues. Here is link to my post related to this topic:
https://www.edaboard.com/showthread.php?383756-Briey-SoC-(RISCV)-and-Mimas-V-2-Numato-FPGA-board
I hope that5 someone will be able to help me with these problems.
Thanks and regards