cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Adventurer
Adventurer
1,533 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

I can see my memory contents..now..!did a mistake ..you can see 0a3d70a3,and 0e560618,values..in the middleyou can see 0a3d70a3,and 0e560618,values..in the middle

0 Kudos
Highlighted
Adventurer
Adventurer
1,529 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

ok...i got ..it Poll means ..reading the address of the AXI GPIO...in Which the DONE signal is provided.and reading that Address through.. SDK..am i right?....if thats the case..can you give one example on how to write 'C' code for AXI gpio...initiazation,control..of signals and so on...

THANKS in advance @ronnywebers 

0 Kudos
Highlighted
Advisor
Advisor
1,522 Views
Registered: ‎10-10-2014

Re: BRAM Acces to write it from PL and read from PS and compute that data

there's a few tutorials that you could go through :

1) Creating a custom IP block in Vivado

this one will learn you a lot, also the SDK side on how to talk to AXI registers (AXI GPIO is just a bunch of registers too). 

this one I just searched on youtube with 'Vivado AXI GPIO', there's probably more of them :

2) Zedboard getting started with VIVADO and SDK Switch Buttons and Led Interfacing with AXI GPIO IP

3) This is a very good tutorial on the Zedboard, but a bit more complicated : https://github.com/Architech-Silica/Zynq-Zedboard-Vivado-Workshop

 

** kudo if the answer was helpful. Accept as solution if your question is answered **
0 Kudos
Highlighted
Adventurer
Adventurer
1,511 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

Thanks for the quick reply...can u please follow me up on PL part ...which u mentioned to share FSM,TB and RAM.

THANKS @ronnywebers

0 Kudos
Highlighted
Adventurer
Adventurer
1,503 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

here DIN and address..are seen is whereas..dout is 0here DIN and address..are seen is whereas..dout is 0

0 Kudos
Highlighted
Advisor
Advisor
1,500 Views
Registered: ‎10-10-2014

Re: BRAM Acces to write it from PL and read from PS and compute that data

try to put all signals of the bram on the ILA (we, en, ...), and make sure to inspect the write and read cycles. Is your WE toggling at the right moment, is your EN = '1', is the reset low, ... -> check every signal

** kudo if the answer was helpful. Accept as solution if your question is answered **
0 Kudos
Adventurer
Adventurer
1,482 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

hi,couldnt see the dout signal...we= 0 and en = 1...but dout is showing as zero...sir ..i knwo the gpio way u justed...is easy..but iam not getting..it..that is the part where i have to implement c code...its showing 32 bit 0 as out...can u suggest me a normal way ..in which i can configure via PL itself.that is use GO,rest as switches..and done as an led ..without use of axi GPIO..please help..the GPIO way..has given me a headache...please help..also..please verify this simulation,ggg.png thanks @ronny webers

0 Kudos
Highlighted
Advisor
Advisor
1,474 Views
Registered: ‎10-10-2014

Re: BRAM Acces to write it from PL and read from PS and compute that data

@sam007 , I think you try to go to fast ... did you go through the tutorials I gave you? Did you do these step by step? I think you first should go through some written out tutorials, that you know will work, try to understand these first, before you try to build something yourself.

the 3 tutorials I gave you are really helpfull, I learned from these before I tried something myself.

I searched on youtube for 'vivado bram simulation', and found for example these:

https://www.youtube.com/watch?v=pDw3MEoQF9Y

https://www.youtube.com/watch?v=SGvYkA87W20

https://www.youtube.com/watch?v=gfpE81yMBwQ

these will help you understand how a BRAM works, how to instantiate it, how to simulate it. With Vivado and Verilog, you must start simple, and understand every step. You might think you're going slow then, but it's the only way to learn it. And go for the Verilog book I gave you (Pong P. Chu).

 

 

** kudo if the answer was helpful. Accept as solution if your question is answered **
An example of how accesses to an FPGA block RAM (BRAM) configured with different width ports works in both write first and read first mode.
In the last lecture tutorial we had a look at how to create a Block RAM memory interface in Vivado. * Full Vivado Course : http://augmentedstartups.info/xili...
0 Kudos
Highlighted
Adventurer
Adventurer
1,466 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

hi,should the done,go,and reset..be 32 bit..and should i take create ports for go,reset...fig.png

0 Kudos
Highlighted
Adventurer
Adventurer
1,466 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

iam sorry ..should i create ports like this!go signal is given to gpio..in which port is taken out and another gpio for resetgo signal is given to gpio..in which port is taken out and another gpio for reset

0 Kudos
Highlighted
Adventurer
Adventurer
1,461 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

or just keep it like this..thanks @ronnywebers po.png

0 Kudos
Highlighted
Adventurer
Adventurer
1,453 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

sir,a favour can you re assess..my FSM code!i want to test it on true dual port block ram...just tell me ..the write and enable in my code...which i have wriiten....is it triggered at the right time? THANKS @ronnywebers 

module FSM_DATA_ADDR_GENERATOR(
input wire SYSCLK,
input wire RESET,
input wire GO,
input wire RESET_SIGNAL,
output wire WE,
output wire EN,
output wire DONE,
output wire [9:0]ADDRESS,
output wire[31:0]DATA_IN
);
////////////////////////////////////////////////////////////////////
reg WE_SIG            = 1'b0;
reg EN_SIG            = 1'b0;
reg DONE_SIG          = 1'b0;
reg [9:0]ADDRESS_SIG  = {3'b100,7'b0000000};
reg [31:0]DATA_IN_SIG = 32'h00000000;
reg [1:0]STATE        = 2'b00;
/////////////////////////////////////////////////////////////////////////
parameter IDLE        = 2'b00;
parameter INCREMENT   = 2'b01;
parameter STOP_STATE  = 2'b10;
////////////////////////////////////////////////////////////////////////
assign WE             = WE_SIG;
assign EN             = EN_SIG;
assign ADDRESS        = ADDRESS_SIG;
assign DONE           = DONE_SIG;
assign DATA_IN        = DATA_IN_SIG;
/////////////////////////////////////////////////////////////////////////
always@(posedge SYSCLK)
 begin
  if(RESET)
   begin
    STATE    <= IDLE;
   end
 else     
  begin
   case(STATE)

IDLE: 
 begin
  if(RESET_SIGNAL == 0)
    STATE    <= INCREMENT;
   else
    begin  
     WE_SIG     <= 1'b1;
    DONE_SIG   <= 1'b0;
    EN_SIG     <= 1'b1;
   ADDRESS_SIG <= {3'b100,7'b0000000};
   DATA_IN_SIG <= 32'h00000000;
        STATE  <= IDLE;
   end 
   end 
       
      
INCREMENT:
begin
 begin
   WE_SIG    <= 1'b0;
  EN_SIG     <= 1'b0;
  DONE_SIG   <= 1'b0;
 ADDRESS_SIG <= ADDRESS_SIG + {7'b0000000,3'b100};
 DATA_IN_SIG <= DATA_IN_SIG + 32'h04040404;
      STATE  <= INCREMENT;
      end     
    if(GO == 1)
     STATE   <= STOP_STATE;
    end

STOP_STATE:
 begin
  begin
   WE_SIG    <= 1'b1;
   EN_SIG    <= 1'b1;
   DONE_SIG  <= 1'b1;
  DATA_IN_SIG <= 32'h0a3d70a3;
  ADDRESS_SIG <= {7'b0000000,3'b101};   
   STATE     <= STOP_STATE;  
    end
  if(RESET_SIGNAL == 1)
  
   STATE     <= IDLE;  
  end
  
  
default:
 begin  
   WE_SIG    <= 1'b0;
  EN_SIG     <= 1'b0;
 ADDRESS_SIG <= {3'b100,7'b0000000};
 DATA_IN_SIG <= 32'h00000000;
      STATE  <= IDLE;
 end

 endcase
 end
end 
endmodule

0 Kudos
Highlighted
Advisor
Advisor
1,447 Views
Registered: ‎10-10-2014

Re: BRAM Acces to write it from PL and read from PS and compute that data

@sam007  it's probably cleaner to use the 'slice' IP in the block diagram to split the 32-bit port of the GPIO into a few separate signals. Note that the 'concat' IP does the inverse of 'slice'. 

about your FSM : please check UG901 - Synthesis first for the recommended coding of an FSM in Verilog. you can find a simple example in chapter 4, under FSM -> fsm_1.vhd

Notice how they don't use 'begin' and 'end' in UG901 ... -> get rid of this first, as IMHO it only pollutes your code and makes it less readable. Also try to use proper indentation, it's important to avoid mistakes. Use either all spaces or all tabs to indent, that probably helps alignment in a code snippet in a forum post.

Also notice in the fsm example that there is no 'default' section in that example template, they define all the output signals in every state. I guess a default state is legal in Verilog, but as they don't use it in the example template, I would start without one.. try to stay close to the UG901 recommended way of coding. 

Also notice that you don't define your output signals during a reset -> again, take a look at UG901 ... 

 

always@(posedge SYSCLK)
 begin
  if(RESET)
   begin
    STATE    <= IDLE;
------------------> define all your outputs here too !!! <------------------------
   end
 else     
  begin
   case(STATE)

 

 

also try to use easy readable 'data' and 'address values' during test / simulation, like for example somewhere you use 'h0a3d70a3' -> I'd use 'h11223344' or 'h12345678' or something more readable in the simulator.

** kudo if the answer was helpful. Accept as solution if your question is answered **
0 Kudos
Highlighted
Adventurer
Adventurer
1,437 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

everything is fine apart from the fact that at start of dout ..i get x...what is that ..iam not able to figure..out..maybe memory should be initialized to some value!!!!but through text file i tried...it is showing as unknown..only in the first read...iam getting that issue...after that data in dout is valid...attched the waveform

 THANKS @ronnywebers beq.png

0 Kudos
Highlighted
Adventurer
Adventurer
1,430 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

mem.png


@ronnywebers wrote:

@sam007  it's probably cleaner to use the 'slice' IP in the block diagram to split the 32-bit port of the GPIO into a few separate signals. Note that the 'concat' IP does the inverse of 'slice'. 

about your FSM : please check UG901 - Synthesis first for the recommended coding of an FSM in Verilog. you can find a simple example in chapter 4, under FSM -> fsm_1.vhd

Notice how they don't use 'begin' and 'end' in UG901 ... -> get rid of this first, as IMHO it only pollutes your code and makes it less readable. Also try to use proper indentation, it's important to avoid mistakes. Use either all spaces or all tabs to indent, that probably helps alignment in a code snippet in a forum post.

Also notice in the fsm example that there is no 'default' section in that example template, they define all the output signals in every state. I guess a default state is legal in Verilog, but as they don't use it in the example template, I would start without one.. try to stay close to the UG901 recommended way of coding. 

Also notice that you don't define your output signals during a reset -> again, take a look at UG901 ... 

 

always@(posedge SYSCLK)
 begin
  if(RESET)
   begin
    STATE    <= IDLE;
------------------> define all your outputs here too !!! <------------------------
   end
 else     
  begin
   case(STATE)

 

 

also try to use easy readable 'data' and 'address values' during test / simulation, like for example somewhere you use 'h0a3d70a3' -> I'd use 'h11223344' or 'h12345678' or something more readable in the simulator.


here...i saw in a forum ..that we can assign values to memory..which prevents the dout going to x....thats good..but i want to assign for 1024 values!..how to do that? Sir i have extended this thread iam sorry for that...but here in my company..they have also put their hands up in terms of support...and this forum and your helps keeps me going..so THANKS @ronnywebers  
mem_val.png

0 Kudos
Highlighted
Advisor
Advisor
1,424 Views
Registered: ‎10-10-2014

Re: BRAM Acces to write it from PL and read from PS and compute that data

I can see the 0x12345678 in your memory, 'something' is happening, but it's zoomed out where your simulation is actually writing, so I can't see the detals (where go goes to '1')

the easiest way to initialize them would be through a file I think, you should find that using google. Apparently it's also possible using code, see here 

did you cleanup your FSM? did you correct the unasigned signals when you are resetting? did you compare your code with UG901?

you could make your memory much smaller to start with, like 16 entries, that way you can put 16 values in a file and read these in, instead of 1024. Once your whole system works, you can expand. Start simple.

I'd cleanup your fsm first. Clean code is the start of everything. Then post it here again.

in the testbench I can see you generate 2 resets : keep it simple, generate 1 clean reset, get rid of that second one. Also try and make the 'EN' line permanently '1', I don't think you should be toggling it anyway, not sure on what hardware you are, but in general EN works as follows:

'EN'  : when inactive (= zero), no data is written to the block RAM and the output bus remains in its previous state.

 

** kudo if the answer was helpful. Accept as solution if your question is answered **
0 Kudos
Highlighted
Adventurer
Adventurer
1,409 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

hello sir,my spec has changed a little bit,it is as follows

1).In a Dual Port Ram for PORTB ....Generate an Address in this case at Address Location 0,assert "Read operation" and Collect Data_out at Port B.

2.)  Then Generate an Address in this case, Address location 1,Put data inside the Data_in,and Assert "Write operation".

Thanks @ronnywebers 

0 Kudos
Highlighted
Adventurer
Adventurer
1,399 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

Accept as Solution....

0 Kudos
Highlighted
Advisor
Advisor
1,391 Views
Registered: ‎10-10-2014

Re: BRAM Acces to write it from PL and read from PS and compute that data

@sam007  do you mean everything works fine now? 

** kudo if the answer was helpful. Accept as solution if your question is answered **
0 Kudos
Highlighted
Adventurer
Adventurer
1,381 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

yeah it does..actually..got some change in spec..and some help...and the objective was to copy the memory ...That is write from PS and read from PL.

0 Kudos
Highlighted
Adventurer
Adventurer
1,375 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

I have a question please need some help with this!!!....I have an SPI Module...in which i use to Run via FPGA Switches...First switch 1 would have loaded an inital frequency of 100mhz... and switch 2 would commence Frequency Hopping..from 100 mhz to 140mhz to 200 mhz to 330mhz...and then when in switch 3 it would go back to init 100mhz frequency again......

 

Now the spec given to me is as follows use a 32 bit internal register instead of these "SWITCHES" .......and when this 32 bit register....the Bit[0] -> 0(Falling Edge),the it should perform the operation of Switch 1

Next the 32 bit register..when Bit[1] -> 1(Rising Edge) then it should perform the Switch 2 operation ie; Frequency Hopping...

next the 32 bit Register ..when bit[2] -> 0 (Falling Edge),then it should perform the switch 3 operation..that is init DDS...same as switch 1 

Here instead of using Switches...the PS will write the values to Port A(PS) and Port B(PL) will read those values

I TRIED TO USE reg[0] == 0

{Edge_det_sig[0]} == 1'b0,{Edge_det_sig[1]} == 1'b1..in PL..design...no effect..what should i do...for this kind of spec? i have attached the code please..

module Spi_Mod(
input wire sysclk,
output wire sclk,
output wire sig1ms_sig,
output wire cs,
output wire[3:0]functional_pins,
output wire master_reset,
output wire io_update,
output wire [2:0]ps,
output wire[31:0] Edge_det,
output mosi
);

////////////////////////////////////////////////////////////////////////////////////// 
    
parameter [2:0]idle_state          =  3'b000; 
parameter [2:0]master_reset_state  =  3'b001;
parameter [2:0]wait_state          =  3'b010;
parameter [2:0]data_state          =  3'b011;
parameter [2:0]repeat_state        =  3'b100;
parameter [2:0]update_state        =  3'b101;
parameter [2:0]stop_state          =  3'b110;  
/////////////////////////////////////////////////////////////////////////////////////////////       

//////////////////////////////////////////////////////////////////////////////////////////
reg sclk_reg         =  1'b0;    
reg cs_reg           =  1'b1;
reg [3:0]func_pins   =  4'b0001;                                                        
reg master_reset_reg =  1'b0;
reg io_update_reg    =  1'b0;
reg [2:0]ps_reg      =  3'b000;
reg  mosi_reg        =  1'b0;
reg [2:0]state       =  3'b000;
reg [2:0]update_cntr =  3'b000;        
reg [39:0]data       =  40'd0;
reg [5:0]cnt         =  6'd0;   
reg [2:0]freq_cnt    =  3'b000;
reg [39:0]freq_ch    =  40'd0;
reg  sig1ms          =  1'b0;
reg [31:0]Edge_det_sig = 32'h00000000;///for edge detect Ps logic.
reg [31:0]cnt_1ms    =  32'd0;



///////////////////////////////////////////////////////////////////////////////////////////    
   
/////////////////////////////////////////////////////////////////////////////////////////////       
    
assign sclk             =  sclk_reg;
assign cs               =  cs_reg;
assign functional_pins  =  func_pins;
assign master_reset     =  master_reset_reg;
assign io_update        =  io_update_reg;
assign ps               =  ps_reg;
assign sig1ms_sig       =  sig1ms;
assign Edge_det         =  Edge_det_sig;
assign mosi             =  mosi_reg;

 
////////////////////////////////////////// //////////////////////////////////////////////////
    
always @(posedge sysclk)  
begin  

   
if(cnt_1ms == 32'd100000)//1ms logic
 begin
  cnt_1ms        <=  0;
  sig1ms         <=  1;
 end 
else
 begin
  cnt_1ms        <= cnt_1ms + 1;
  sig1ms         <= 0;
 end



   

  
case(state)
idle_state:
begin
if({Edge_det_sig[0]} == 1'b0)
 begin    
  state          <=   master_reset_state;
  data           <=  {8'h00,32'h0001010a};
 end
else if({Edge_det_sig[0]} == 1'b1)
 begin

  func_pins      <=   4'b0001;//Serial_state
  io_update_reg  <=   1'b0;
master_reset_reg <=   1'b0;
  ps_reg         <=   3'b000;
  sclk_reg       <=   1'b0;
  cs_reg         <=   1'b1;
  state          <=   idle_state;
 end
end 
    
    
    
master_reset_state:
 begin
  func_pins      <=   4'b0001;//Serial_state
  io_update_reg  <=   1'b0;
master_reset_reg <=   1'b1;
  ps_reg         <=   3'b000;
  sclk_reg       <=   1'b0;
  cs_reg         <=   1'b1;
  state          <=  wait_state;
 end
    
    
    
wait_state:
 begin
  func_pins      <=   4'b0001;
  io_update_reg  <=   1'b0;
master_reset_reg <=   1'b0;
  ps_reg         <=   3'b000;
  sclk_reg       <=   1'b0;
  cs_reg         <=   1'b0;
  state          <=   data_state;
 end
    
    
    
data_state:
 begin
  func_pins      <=   4'b0001;
  io_update_reg  <=   1'b0;
master_reset_reg <=   1'b0; 
  ps_reg         <=   3'b000;
  sclk_reg       <=   1'b0;
  cs_reg         <=   1'b0;
  mosi_reg       <=  {data[39]};//msb sent 1st to MOSI output.      
  state          <=  repeat_state; 
 end
    
    
repeat_state:
 begin
  func_pins      <=  4'b0001;
  io_update_reg  <=   1'b0;
master_reset_reg <=   1'b0;
  ps_reg         <=   3'b000;
  sclk_reg       <=   1'b1;
  cs_reg         <=   1'b0;  
  data           <=  {data[38:0],1'b0};

if(cnt > 6'd38) 
  state          <=  update_state;
else 
 begin
  cnt            <=  cnt + 1;
  state          <=  data_state;

 end
end
    
update_state:
 begin
  func_pins     <=  4'b0001;
  ps_reg        <=   3'b000;
  cs_reg        <=   1'b0; 
master_reset_reg<=   1'b0; 
  io_update_reg <=   1'b1;
  sclk_reg      <=   1'b0;
  cnt           <=   6'd0;
  update_cntr   <=  update_cntr  + 1;
  data          <=  freq_ch;
        
if(update_cntr == 3'b000)
 begin
    
  data          <= {8'h03,32'h01052120};
  state         <=  wait_state;
 
 end
    
if(update_cntr == 3'b001)
 begin
    
 data           <= {8'h03,32'h00052120};
 state          <=  wait_state;
    
 end
else if(update_cntr == 3'b010)
 begin
        
  data         <=  {8'h01,32'h00800900}; 
  state        <=   wait_state;
    
 end
    
else if(update_cntr == 3'b011)
 begin    
  
  data        <=  {8'h0c,32'h0fd70000};        
  state       <=   wait_state;
 
 end
    
else if(update_cntr == 3'b100)
 begin
 
  data         <=  {8'h0b,32'h0a3d70a3};//amplitude with init freq,ie 100mhz       
  state        <=   wait_state;
  update_cntr  <=   3'b110;
 
 end 
    
else if(update_cntr == 3'b101)
 begin
    
 io_update_reg <=   1'b0;
 data          <=   freq_ch;        
 state         <=   wait_state;
 end

else if(update_cntr == 3'b110)
 begin
      
  mosi_reg    <=   1'b0;
  state       <=  stop_state;
  end
end

stop_state:
 begin
state         <=   stop_state;
update_cntr   <=   3'b000;
io_update_reg <=   1'b0;
master_reset_reg <=   1'b0;
ps_reg        <=   3'b000;
sclk_reg      <=   1'b0;
cs_reg        <=   1'b1;
mosi_reg      <=   1'b0;
func_pins     <=   4'b0001;//serial_state  

    
if({Edge_det_sig[0]} == 1'b0)
 begin
    
state        <=   master_reset_state;
data         <=  {8'h00,32'h0001010a};//amplitude phase
update_cntr  <=   3'b100;
    
 end
    
 else if({Edge_det_sig[0]} == 1'b0)
 begin  
 freq_ch    <=  40'h0;
 state      <=   stop_state;
 end
    

   
if({Edge_det_sig[1]} == 1'b1 )
 begin
if(sig1ms == 1) 
begin
freq_cnt  <= freq_cnt + 1;   
if(freq_cnt == 3'b000)
 begin
update_cntr <=  3'b101;
freq_ch     <= {8'h0b,32'h0e560418};// 140 mhz 
state       <=  update_state;
 end 
  
  
if(freq_cnt == 3'b001)
 begin
update_cntr <=  3'b101;
 freq_ch    <= {8'h0b,32'h147ae147}; //200 mhz
 state      <=  update_state;
 end 
    
   
if(freq_cnt == 3'b010)
 begin
update_cntr <=  3'b101;
freq_ch     <= {8'h0b,32'h20c49ba5};//320 mhz 
state       <=  update_state;
end 
  
if(freq_cnt == 3'b011) 
 begin
update_cntr <=  3'b101;
freq_ch     <= {8'h0b,32'h2219652b};//333 mhz
state       <=  update_state;
freq_cnt    <=  3'b000; 
 end
 
else if({Edge_det_sig[1]} == 1'b0)

 begin
update_cntr  <=  3'b101;
freq_ch      <=  {8'h0b,32'h0e560418};// init freq in hopping that is 140 mhz 
state        <=  update_state;
freq_cnt     <=  3'b000;

 end
end
end
 

 
if({Edge_det_sig[0]} == 1'b0)
 begin

update_cntr <=  3'b101;
freq_ch     <= {8'h0b,32'h0e560418};
state       <=  update_state;
freq_cnt    <=  3'b000; 

   
 end

    
else if({Edge_det_sig[0]} == 1'b1)
 begin
update_cntr <=  3'b101;
freq_ch     <=  40'h0;//140mhz
state       <=  update_state;
     
 end
end
     
default:
 begin
io_update_reg <=   1'b0;
master_reset_reg<=   1'b0;
ps_reg            <=   3'b000;
sclk_reg          <=   1'b0;
cs_reg            <=   1'b1;
func_pins         <=   4'b0001;//serial_state
 end    
endcase    
end
endmodule

THANKS @ronnywebers 

0 Kudos
Highlighted
Adventurer
Adventurer
1,334 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

sir please help @ronnywebers 

0 Kudos
Highlighted
Advisor
Advisor
1,325 Views
Registered: ‎10-10-2014

Re: BRAM Acces to write it from PL and read from PS and compute that data

@sam007 

As this is a completely different question, you should create a new question on the forum. Each thread should limit itself to the question asked, otherwise the forum becomes useless. 

Actually this post became too long anyway. Also it would be nice if you could post your final solution of your FSM and C-code here, or at least a stripped-down but working verison, that is the purpose of the forum : you can ask questions and people may try to help you, but you should also give back to other people.

** kudo if the answer was helpful. Accept as solution if your question is answered **
0 Kudos
Highlighted
Adventurer
Adventurer
1,320 Views
Registered: ‎07-30-2018

Re: BRAM Acces to write it from PL and read from PS and compute that data

will do  so sir! @ronnywebers  Thank you for your Assistance!

//DUT//
module mem_new(
input wire CLK,
input wire RST,
input wire [31:0]DOUTB,
output wire ENB,
output wire [31:0]DINB,
output wire [31:0]ADDRB,
output wire [3:0]WEB
);
////////////////////////////////////////////////////////////////////////////////////////
reg [31:0]DATA_READ   = 32'h00000000;
reg ENB_SIG           = 1'b0;
reg [31:0]DINB_SIG    = 32'h00000000;
reg [31:0]ADDRB_SIG   = 32'h00000000;
reg [3:0]WEB_SIG      = 4'b0000;
reg [2:0]STATE        = 3'b000;
reg [2:0]WAIT_CYCLES  = 3'b000;
///////////////////////////////////////////////////////////////////////////////////////////
parameter IDLE_STATE   = 3'b000;
parameter ADDRESS_ZERO = 3'b001;
parameter READ_ADDRESS = 3'b010;
parameter ADDRESS_ONE  = 3'b011;
parameter SEND_DATA    = 3'b100;
parameter DONE_STATE   = 3'b101;
///////////////////////////////////////////////////////////////////////////////////////////////
parameter MAX_WAIT_CYCLES = 2'd2;
///////////////////////////////////////////////////////////////////////////////////////////////
assign    ENB          = ENB_SIG;
assign    DINB         = DINB_SIG;
assign    ADDRB        = ADDRB_SIG;
assign    WEB          = WEB_SIG;
////////////////////////////////////////////////////////////////////////////////////////////////
always@(posedge CLK)
 begin
case(STATE)
IDLE_STATE:
 begin
  if(RST) 
   begin
  STATE               <= IDLE_STATE;
  ENB_SIG             <= 1'b0;
  DINB_SIG            <= 32'h00000000;       
  ADDRB_SIG           <= 32'h00000000;
  WEB_SIG             <= 4'b0000;
    end 
  else
   STATE              <= ADDRESS_ZERO;
  end
      
      
ADDRESS_ZERO:
  begin
   ENB_SIG             <= 1'b1;//Enable BRAM port.
   ADDRB_SIG           <= 32'h40000000;//First Address is Generated
   WAIT_CYCLES         <= WAIT_CYCLES + 1;
    if(WAIT_CYCLES == MAX_WAIT_CYCLES)///wait for Max cycles ie;2 for Read cycles 
     begin
      STATE            <= READ_ADDRESS;
      WAIT_CYCLES      <= 3'b000;
     end
   end 
   

READ_ADDRESS:
   begin
    DATA_READ          <= DOUTB;//data at previous address is collected and Read.
    WAIT_CYCLES        <= WAIT_CYCLES + 1;
    if(WAIT_CYCLES == MAX_WAIT_CYCLES)///wait for Max cycles ie;2 for Read cycles 
     begin
      STATE            <= ADDRESS_ONE;
      WAIT_CYCLES      <= 3'b000;
     end
   end
    
ADDRESS_ONE:
  begin
   ADDRB_SIG           <= 32'h40000004;//Second Address is generated
   WAIT_CYCLES         <= WAIT_CYCLES + 1;
   if(WAIT_CYCLES == MAX_WAIT_CYCLES) //wait for Max cycles ie;2 for Read cycles
    begin
     STATE             <= SEND_DATA;
     WAIT_CYCLES       <= 3'b000;
        end
      end
 
SEND_DATA:
 begin
   DINB_SIG            <= DATA_READ;//data is put in dinb
   WEB_SIG             <= 4'b1111;///This Data is then Written into the Bram.
   WAIT_CYCLES         <= WAIT_CYCLES + 1;
   if(WAIT_CYCLES == MAX_WAIT_CYCLES) //wait for Max cycles ie;2 for Read cycles
       begin
        STATE          <= DONE_STATE;
        WAIT_CYCLES    <= 3'b000;
        end
  end       

DONE_STATE:
 begin
   WEB_SIG             <= 4'b0000;//Write disabled
   ENB_SIG             <= 1'b0;//Bram disabled
   WAIT_CYCLES         <= WAIT_CYCLES + 1;
   if(WAIT_CYCLES == MAX_WAIT_CYCLES)//wait for Max cycles ie;2 for Read cycles
    begin
     STATE             <= IDLE_STATE;
     WAIT_CYCLES       <= 3'b000;
    end
 end        
 
default:
 begin  
  STATE               <= IDLE_STATE;
  ENB_SIG             <= 1'b0;
  DINB_SIG            <= 32'h00000000;       
  ADDRB_SIG           <= 32'h00000000;
  WEB_SIG             <= 4'b0000;
 end

 endcase
 end
endmodule 


//TB//
module test_mem_new();
reg CLK;
reg RST;
reg [31:0]DOUTB;
wire ENB;
wire [31:0]DINB;
wire [31:0]ADDRB;
wire [3:0]WEB;


mem_new m1 (.CLK(CLK),.RST(RST),.DOUTB(DOUTB),.ENB(ENB),.DINB(DINB),.ADDRB(ADDRB),.WEB(WEB));

initial
begin
CLK = 1'b0;
end
always
#5 CLK = ~CLK;

initial
 begin
  RST  = 1'b0;
 #10;
  RST  = 1'b1;
  #30;
  RST  = 1'b0; 
end

initial
 begin
  DOUTB = 32'h00000000;
 #100;
  DOUTB = 32'h12345678;
 #100;
  DOUTB = 32'h0a3d70a3;
 #100;
  DOUTB = 32'h23456789;
 end  

endmodule

//C code//
#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xil_io.h"

#define BRAM_ADDR_0		0x40000000
#define BRAM_ADDR_1		0x40000004

uint32_t mem_data;

int main()
{
    init_platform();


    print("Hello World\n\r");
    Xil_Out32(BRAM_ADDR_0,55);
    mem_data = Xil_In32(BRAM_ADDR_1);
	xil_printf("Read Data = %d\n",mem_data);


    cleanup_platform();
    return 0;
}

Highlighted
Observer
Observer
648 Views
Registered: ‎12-10-2019

Re: BRAM Acces to write it from PL and read from PS and compute that data

@Anonymous Hi, I hope you could help me, I am trying to write the BRAM from PL and read from PS (see block diagram)

 

code explanation:

I am writing three times in the ram, always from address 0 to 9 but from values from 0 to 29 (see signals file), after the three writes I put all the signals to 0, I am not writing anything and disable the port b of the ram, in the arm (see helloworld file) I make a 5 seconds pause and I use a signal from the PL to know when the ram is full ("ram full" signal - see the block diagram), and I read the ram one time from addresses 0 to 9 and print in the uart the results

what do I expect:

I have written the ram and I have wait enough time to could read it, so I expect to see in the terminal the last values written, I mean, addresses 0 to 9 with values from 20 to 29

what do I get?

random values (see the output file) (I pressed the board reset three times that is why I have three lectures)

 

note:

- if I always write the same values in the ram, when I read it works ok

- common clock enable in bram

- I read in your post that the bram reset signal must be low when you are writing because the ram reset is active high, I had an error here because I had the port b reset always in high when I was writing, now is fixed and always is low but it does not change anything, it does not work

 

thanks

0 Kudos
Highlighted
Observer
Observer
568 Views
Registered: ‎12-10-2019

Re: BRAM Acces to write it from PL and read from PS and compute that data

@ronnywebersHi, could you explain to me this, please?

"your fsm will probably be finished by the time your PS code runs through it's main loop"

why?, in theory the ARM is running faster than the FPGA, for example in my block diagram I can see the clock frequency of the FPGA in 100MHz (fclk_clk0 pin) but inside SDK in the xparameters.h file I see:

XPAR_PS7_CORTEXA9_0_CPU_CLK_FREQ_HZ 500000000

thanks

 

0 Kudos
Highlighted
Advisor
Advisor
551 Views
Registered: ‎10-10-2014

Re: BRAM Acces to write it from PL and read from PS and compute that data

@jg_spitfire what I meant is that PL code will start to run earlier than you think ... if you don't take any measures. In some applications that's ok, in some other you want to have control over this.

For example take a custom IP with a simple counter in it, that just receives a PL clock (let's say 100MHz) from the Zynq IP, and a PL reset from the Processing System Reset IP. The IP also contains an AXI register that allows you to read the value of the counter from the PS.

As soon as the clock is there, and reset goes inactive, the counter starts counting. Immediately. At that time, I'm pretty sure your C application is still starting up (if I'm correct, FSBL will release the reset and enable the clock, even before it loads the actual application.elf file, but I should check this in more detail - maybe that is part of the application init, not sure of that). But anyway, details aside, by the time you read the AXI register with the counter value, it will not be zero anymore ... you can try that out if you want (but make the counter big enough, like 32-bit, so it does not wrap around too quickly). I'm pretty sure the counter value that you read right after the PS application starts will also vary slightly between successive resets / tests. 

If you add an ILA, the above will even become more interesting, as you'll actually see what's happening at startup, and how many cycles everything takes ...

It's correct that (depending on the settings of course) PS runs in most cases at a higher clock speed (i.e. 500MHz) than the PL (i.e. 100MHz). However AXI transactions are also limited by the 100MHz PL clock, and take a few clock cycles to complete. So .. you'll never read '0' from the counter. Also keep in mind that the PS has startup code to run (init irq tables, C environment, ... before it enters the main() loop. 

Unless ... unless you also add an enable to the counter, and connect it to an AXI register, so you can determine from the PS when it's ok for the counter to run.

In the forementioned case of an FSM and BRAM, this is just the same as the counter. Without enable, the FSM will be writing somewhere in the BRAM by the time PS is ready to read from it, or might even have finished, all depending of course on the number of addresses it should write. 

So bottom line: never rely on startup times on either side (PS/PL), but make sure you are in control if needed.

** kudo if the answer was helpful. Accept as solution if your question is answered **
Highlighted
Observer
Observer
527 Views
Registered: ‎12-10-2019

Re: BRAM Acces to write it from PL and read from PS and compute that data

Thanks, @ronnywebers  now I understand the problem better, where did you learn those things about the axi and the speeds of fpga and the arm?, could you share some link, pdf, or book about it please?, I would like to know more about this, for example, you said:

"Unless ... unless you also add an enable to the counter, and connect it to an AXI register, so you can determine from the PS when it's ok for the counter to run."

I tried that when I was trying to read the ram I was writing from PL( see the photo), In my PS side I create a signal to fire the FSM of my PL code, so once the PS is inside the main function the FSM starts writing the ram and when the ram is full I send the signal "ram_full" to the PS to start reading it, the problem is that even if I control the start of the FSM I can't read correctly the values written, for example I am writing 3 times the ram (in port b)

#1: from addresses 0 to 9 , values 0 to 9

#2: from addresses 0 to 9 , values 10 to 19

#3: from addresses 0 to 9 , values 20 to 29

but I am only able to read the third value written (20 to 29), that means that even if I can detect the "ram_full" signal the arm is too slow to read the first write in the ram and when starts reading it the ram already has been written three times, is that correct or I am wrong?


ram_writter.jpg
0 Kudos
Highlighted
Advisor
Advisor
505 Views
Registered: ‎10-10-2014

Re: BRAM Acces to write it from PL and read from PS and compute that data

@jg_spitfire not sure what your exact goal is with the FSM or writing multiple times to the same memory location.

There's quiet some things to learn, so know beforehand that it will take some time ... There aren't many hands-on books or tutorials, especially not from Xilinx (besides a few tutorials, which you should checkout of course, but will leave a lot of your questions unanswered).

However, the following are usefull documents/links to check:

  • The best book (ebook version is free!) to read on Zynq or Zynq UltraScale+
    • these books are a synthesis of the Xilinx documentation. Should you read these from front to back? If you have the time - yes, definitely, you won't regret it - if not - skim through the books and pick out the chapters that you think are relevant to your needs.
    • The documents from Xilinx that you will need to refer to the most are the 'Technical Reference Manuals' and the 'Methodology guides', checkout the great DocNav tool and the 'Design hub tab' in docnav to find your way in the mountain of pdfs ... 
  • The best hands-on tutorial of all to learn the basics about Vivado and SDK (including interrupt handling) : Zynq Zedboard Vivado Workshop

If you are working with Zynq, the Zedboard is one of the best boards you can buy, you'll find a lot of examples on the web, and it's very complete. A similar but cheaper board is the Zybo board by Digilent. A microzed board is even cheaper I believe (but has limited interfacing), and might get you started also 

After this, you should be able to develop many things. Make sure to get a good HDL book too, if you search on books on the forum, you'll probably find some good tips ...

 

** kudo if the answer was helpful. Accept as solution if your question is answered **