UPGRADE YOUR BROWSER
We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!
03-20-2018 01:11 AM
One more confusion I have regarding BRAM read and write / access operation on linux based platform..
I have done the DDR access from PS using "mmap" function call and using "/dev/mem/" access on linux platform.. But when I will need linux platform based BRAM access will this library "xil_io.h" will be valid method for this or any other way to access BRAM on linux platform.
Thanks,
Dhara
03-20-2018 01:30 AM
@dpandya9488, I'm not a linux sofware expert, but I googled 'zynq access bram from linux user space', and it gives me this wiki page, think that contains all you need.
02-01-2019 04:09 AM
Hello,
I have done something similar to you. Can u plz chk it what is the issue in my design or SDK code ?
In SDK, if i write j=j+1,i get only one value.
I am sending data from PL which is increamented by 1 but not getting the same data when i read it from PS. Instead i am getting values as 00,04,08,0C......
I should get 00,01,02,03,04,05,06......Am i right ?
What is the problem ?
02-12-2019 01:49 AM
sir can give me the pl code,for that fsm which u mentioned,i have nobody to guide me at my current place,as iam still learning,but this is a part of my project which i should submit,please attach me this pl code,as i can learn how to infer it..please sir send it as soon as possible
02-12-2019 01:51 AM
02-12-2019 02:04 AM
02-12-2019 02:26 AM
02-12-2019 02:28 AM
02-12-2019 03:12 AM
which code do u want ?
02-12-2019 03:18 AM
02-12-2019 03:19 AM
02-12-2019 03:21 AM
02-12-2019 03:36 AM
02-12-2019 04:20 AM
@sam007, I don't have the time at the moment to write you a FSM, but in the past I did put a good FSM example on the forum, after getting great input from other people.
The FSM uses a 'single process' approach (vs. the classical 2 or 3 process aproach found in books), which makes it very simple to read and understand. This 'single process' approach is also shown in UG901 (Synthesis, chapter 4, HDL coding techniques). Please checkthe code in this answer of the threadt, it should get you going with FSM's. Also read the entire thread from the start, so you can understand it better, there's some great explanation by other forum users on my questions.
02-12-2019 04:46 AM
02-12-2019 04:52 AM
02-12-2019 05:18 AM
02-13-2019 01:57 AM - edited 02-13-2019 01:57 AM
@sam007, I don't have any code ready at this moment, especially not Verilog as I use VHDL
Did you try to write to the BRAM from the PS and read back from the PS first? Just to see that the PS code is working fine.
Also can you share a screenshot of your entire block diagram here and your entire verilog file? (please use the 'insert code' function for this, it's the </> icon above this editor.
Did you add an 'ILA' on the interfaces to see what's happening?
02-13-2019 04:28 AM
Iam having a problem in implementing the functionality of The "FSM" you suggested please help me out,with the logic part.
BLOCK diagram for PS READ AND WRITE THROUGH PORT A
PS READ AND WRITE OUTPUT IN TERATERM...AS YOU ASKED.
PS_PROGRAM FOR READ AND WRITE ..HERE IAM READING THE PL ADDRESS OF AXI BRAM CONTROLLER,AND THUS RESULT IS SHOWN
HERE IS THE CODE; module bram_pl( input clk, input rst, input [31:0]din, input [3:0]wr_addr, input we, output wire[31:0]dout ); /////////////////////////////////////////////////////////////////////////////////// reg[31:0]ram[15:0]; reg [31:0]dout_sig = 32'd0; reg [3:0]rd_Addr = 4'b0000; reg [3:0]wr_addr_sig = 4'b0000; reg [2:0]state = 3'b000; reg [31:0]din_sig = 32'd0; /////////////////////////////////////////////////////////////////////////////////// parameter INIT_STATE = 3'b000; parameter RAM_OPERATION = 3'b001; parameter READ_TRIGGER_START = 3'b010; parameter ADDR_INC = 3'b011; parameter WB = 3'b100; parameter OUTPUT_STATE_TRIGGER_STOP = 3'b101; parameter DONE_STATE = 3'b110; /////////////////////////////////////////////////////////////////////////////////// assign dout = dout_sig; assign wr_addr = wr_addr_sig; assign din = din_sig; //////////////////////////////////////////////////////////////////////////////////// always@(posedge clk) begin case(state) INIT_STATE: if(!rst) state <= RAM_OPERATION; else state <= INIT_STATE; RAM_OPERATION: begin if(we == 1) ram[wr_addr_sig] <= din_sig;//data given to Ram,which increments Address(ie;Write Address) else begin rd_Addr <= wr_addr_sig;//rd_Addr given to Read data state <= READ_TRIGGER_START;////BRAM operation end end READ_TRIGGER_START: begin dout_sig <= ram[rd_Addr];//1.)Read data at each and every address state <= ADDR_INC; end ADDR_INC: begin din_sig <= din_sig + 32'd1; wr_addr_sig <= wr_addr_sig + 4'd1;//2.)Add 1 to it state <= WB; end WB: begin ram[wr_addr_sig] <= din_sig;//WRITE BACK state <= OUTPUT_STATE_TRIGGER_STOP; end OUTPUT_STATE_TRIGGER_STOP: begin dout_sig <= ram[wr_addr_sig];///writing of data to output signal state <= DONE_STATE; end DONE_STATE: begin dout_sig <= 32'd0; state <= DONE_STATE; end default: begin dout_sig <= 32'd0; din_sig <= 32'd0; end endcase end endmodule TESTBENCH TOO; module TB_BRAM(); reg clk; reg [31:0]din; reg [3:0]wr_addr; reg rst; reg we; wire[31:0]dout; bram_pl b1 (.clk(clk),.din(din),.wr_addr(wr_addr),.rst(rst),.we(we),.dout(dout)); initial begin clk = 1'b0; din = 32'd0; we = 1'b0; wr_addr = 4'd0; end always #5 clk = ~clk; initial begin rst = 1'b1; #10; rst = 1'b0; //#70; //rst = 1'b1; //#75; //rst = 1'b0; end initial begin din = 32'h0a3d70a3;//100mhz wr_addr = 4'd0; #100; din = 32'h0e560418;//140mhz wr_addr = 4'd1; we = 1'b1; #100; din = 32'h147ae147;//200mhz wr_addr = 4'd2; we = 1'b1; #100; din = 32'h20c49a5;//320mhz wr_addr = 4'd3; we = 1'b1; #100; wr_addr = 4'd0; we = 1'b0; #100; wr_addr = 4'd1; we = 1'b0; #100; wr_addr = 4'd2; we = 1'b0; #100; wr_addr = 4'd3; we = 1'b0; #100; end endmodule
@ronnywebers wrote:@sam007, I don't have any code ready at this moment, especially not Verilog as I use VHDL
Did you try to write to the BRAM from the PS and read back from the PS first? Just to see that the PS code is working fine.
Also can you share a screenshot of your entire block diagram here and your entire verilog file? (please use the 'insert code' function for this, it's the </> icon above this editor.
Did you add an 'ILA' on the interfaces to see what's happening?
02-13-2019 04:30 AM
02-13-2019 09:36 PM
02-14-2019 01:19 AM
@sam007, please be a bit more patient ... I'm probably living in a different time zone, and I don't wake up at night to answer forum questions :-)
1) First of all : the screenshot with the waveforms : is this from your simulator? If so, can you add more 'internal signals' to it, like 'state', so you can see the different states your FSM is going through. Better to put enough signals there, so we can see better what's going on there
2) if you would have used 'enum' to name your states, it will be even more easy to see the states in the simulation output, checkout for example this 5 minute video on how to do this
3) can you tell me what you're trying to accomplish in this part of the code - it looks strange to me, like a 'state' (RAM_OPERATION) inside a 'state' (INIT_STATE) - again, I'm not a Verilog programmer, so this might be correct, but it looks kinda strange to me :
case(state) INIT_STATE: if(!rst) state <= RAM_OPERATION; else state <= INIT_STATE; RAM_OPERATION: begin if(we == 1) ram[wr_addr_sig] <= din_sig;//data given to Ram,which increments Address(ie;Write Address) else begin rd_Addr <= wr_addr_sig;//rd_Addr given to Read data state <= READ_TRIGGER_START;////BRAM operation end end
5) In your simulation I think your 'we' should be already high when you write the value 'h0a3d70a3'
6) referring to your block diagram : where exactly is this FSM packaged in? Did you build a custom IP with this FSM code inside of it, and named it 'block memory generator' ?? Or are are you just simulating your code and haven't packaged it yet into a custom IP?
02-14-2019 05:42 AM
1.)sir..since Iam using Verilog ...not SYSTEM verilog..so i think..ENUM is something iam not too familiar using
2.)secondly i have mentioned the internal signals,"current state"...here i have changed the code..and look into the simulation as my DATA_IN_SIG and DATA_OUT_SIG are showing unknown.
3.)i havent used ILA since...my normal simulation isnt coming as expected...please help me in framing that logic,
and tell me what i need to do,in order to correct that...I have shared my code.....
4.) I havent packaged it...since iam checking functionlity....
5.)i have attached the simulation shots and the DUT and testbench...
6.) Here since you discussed about this logic"you could for example build an FSM that reads the data on each address, adds 1 to it, and writes it back. Then you'll also need something to trigger a 'start' of this caluclation, and optinally signal an end."..i have written that code itself...and there is one code in VHDL which they tried the same logic...please guide me on how to use it...iam attaching that to...
THANKS IN ADVANCE
//DUT// module bram_pl( input clk, input Rst, input[31:0]data_in, input[31:0]address, input wr_enable, output wire[31:0] data_out ); /////////////////////////////////////////////////////////////////////////////////////////////// reg [31:0]data_out_sig = 32'h00000000; reg [31:0]data_in_sig = 32'h00000000; reg [2:0]current_state = 3'b000; reg [31:0]address_wr_sig = 32'h00000000; reg [31:0]RAM[1023:0]; reg [31:0]address_rd_sig = 32'h00000000; /////////////////////////////////////////////////////////////////////////////////////////////// parameter INIT = 3'b000; parameter READING_ADDRESS = 3'b001; parameter INC_ADDRESS = 3'b010; parameter WRITE_BACK = 3'b011; parameter DONE = 3'b100; /////////////////////////////////////////////////////////////////////////////////////////////// assign data_out = data_out_sig; assign data_in = data_in_sig; assign address = address_rd_sig; /////////////////////////////////////////////////////////////////////////////////////////////// always@(posedge clk) begin case(current_state) INIT: if(Rst == 1) begin current_state <= INIT; data_out_sig <= 32'h00000000; end else current_state <= READING_ADDRESS; READING_ADDRESS: begin RAM[address_rd_sig] <= data_in_sig; data_out_sig <= RAM[address_rd_sig]; current_state <= INC_ADDRESS; end INC_ADDRESS: begin data_in_sig <= data_in_sig + 32'h04000004; address_rd_sig <= address_rd_sig + 32'h00000004; current_state <= WRITE_BACK; end WRITE_BACK: if(wr_enable == 1) RAM[address_rd_sig] <= data_in_sig; else begin address_wr_sig <= address_rd_sig; current_state <= DONE; end DONE: begin data_out_sig <= RAM[address_wr_sig]; current_state <= DONE; end default: begin data_out_sig <= 32'h00000000; address_rd_sig <= 32'h00000000; end endcase end endmodule //TB// module TB_BRAM(); reg clk; reg [31:0]data_in; reg [31:0]address; reg wr_enable; reg Rst; wire[31:0]data_out; bram_pl b1 (.clk(clk),.data_in(data_in),.address(address),.Rst(Rst),.wr_enable(wr_enable),.data_out(data_out)); initial begin clk = 1'b0; end always #5 clk = ~clk; initial begin Rst = 1'b1; #10; Rst = 1'b0; //#70; //rst = 1'b1; //#75; //rst = 1'b0; end initial begin wr_enable = 1'b1; #35; wr_enable = 1'b0; #50; wr_enable = 1'b1; #75; wr_enable = 1'b0; #105; end endmodule
02-14-2019 06:34 AM
@sam007, I'd try to find a verilog tutorial that first gives you a working module and testbench, so you can start from that. I googled a bit and found the one attached. I really think you should calm down and have a look at that tutorial first. you'll win back that time later.
Looking at that code quickly, I think at least one issue is here :
I think you should end your init state here. If you do so, you'll need to remove one 'end' statement at the bottom of your code.
Then next, your testbench looks incomplete - you should define signals for all inputs (stimuli) of your DUT, these are :
input clk, input Rst, input[31:0]data_in, input[31:0]address, input wr_enable,
If I'm correct, you're not defining anything for data_in and address, hence the red signals ..
Also, look at your simulation : next_state shows that immediately after reset ends, you go from 0 -> 1 -> 2 -> 3 -> 4, and you seem to stay in '4' forever ... ? So there's one of your issues I guess, but to be honest, your design looks unclear to me ...
try to draw your system on paper : start drawing an FSM block and a BRAM block, and see how these connect. Then create 2 verilog source files, one for the BRAM, one for the FSM, then hook both up in a testbench. I'm confused by your files : you also showed a screenshot of 'counter_data.vhd' which is a VHDL file... I don't see how / where that is connected to your FSM or BRAM ...?
Also, check UG937 - Logic Simulation Tutorial - it might take you a few hours to go through this, but you'll have a good verilog code and testbench example.
I really recommend you reading a good Verilog book that approaches things in a modular way, you'll win all that time back. A good book IMHO is from Pong P. Chu, it's rather old, but still a good one to start with. He has many other good books.
02-15-2019 01:35 AM
i have done changes,here it goes
1.) I have added that "end" in the INIT state,and thus there is a more Systematic flow to the FSM.
2.)i have defined the "Data_in" and "Address values" in the Testbench. I have a Question... is it Required to define these values in the DUT.(ie;0a3d70a3,values so on...) TESTBENCH ATTACHED TOO.
3.) In the simulation it is not getting stuck at that "4" state...but atleast DATA_IN and DATA_OUT are kindof Matching..where DATA_IN is being incremented,and DATA_OUT Increment occurs..(SIMULATION SNAPSHOT ATTACHED)
4.) I Have attached a changed version of this code.(DUT AND TESTBENCH).So i want to understand one thing...BRAM is just basic READ/WRITE..right? or is there something else more to be added within the bram.
Secondly,this statement in the DUT
data_in_sig <= data_in_sig + 32'h04000004;
address_rd_sig <= address_rd_sig + 4'd4;
is the logic of the FSM that you mentioned ..quoted by Yourself" FSM that reads the data on each address, adds 1 to it, and writes it back." is this that logic....
here i have Written "BRAM and the Logic which you mentioned in one FSM"..is it the right thing what iam doing?
or should i just write one source for Conventional BRAM and one FSM...for the logic that is mentioned.. by you.
separtely
5.) you said to make two files one for FSM and one for BRAM them separtely,is doing them together an issue...please let me know on this..........
6.)iam going through Your references of FSM pdf which you sent,Verilog book,and logic simulation...i now what path i have to follow...it will take time..but good in long term.
7.)finally can you refer me a good soure for basic digital logic....for LOGIC SYNTHESIS...and hardware analysis?
let me know on the fsm and bram..confusion i have
THANKS YOU ADVANCE
//DUT// module bram_pl( input clk, input Rst, input[31:0]data_in, input[3:0]address, input wr_enable, output wire[31:0] data_out ); /////////////////////////////////////////////////////////////////////////////////////////////// reg [31:0]data_out_sig = 32'h00000000; reg [31:0]data_in_sig = 32'h00000000; reg [2:0]current_state = 3'b000; reg [3:0]address_wr_sig = 4'd0; reg [31:0]RAM[15:0]; reg [3:0]address_rd_sig = 4'd0; /////////////////////////////////////////////////////////////////////////////////////////////// parameter INIT = 3'b000; parameter READING_ADDRESS = 3'b001; parameter INC_ADDRESS = 3'b010; parameter WRITE_BACK = 3'b011; parameter DONE = 3'b100; /////////////////////////////////////////////////////////////////////////////////////////////// assign data_out = data_out_sig; //assign data_in = data_in_sig; //assign address = address_rd_sig; /////////////////////////////////////////////////////////////////////////////////////////////// always@(posedge clk) begin data_in_sig <= data_in; address_rd_sig <= address; case(current_state) INIT: begin if(Rst == 1) begin current_state <= INIT; data_out_sig <= 32'h00000000; end else current_state <= READING_ADDRESS; end///end has been added....to end the "INIT" state ..as the FSM will be stuck in the same state. READING_ADDRESS: begin RAM[address_rd_sig] <= data_in_sig; data_out_sig <= RAM[address_rd_sig]; current_state <= INC_ADDRESS; end INC_ADDRESS: begin data_in_sig <= data_in_sig + 32'h04000004; address_rd_sig <= address_rd_sig + 4'd4; current_state <= WRITE_BACK; end WRITE_BACK: if(wr_enable == 1) begin RAM[address_rd_sig] <= data_in_sig; current_state <= DONE; end else begin address_wr_sig <= address_rd_sig; current_state <= DONE; end DONE: begin data_out_sig <= RAM[address_wr_sig]; current_state <= INIT;/////////Had Written "DONE"but in simulation,FSM was stuck..so its going back to 1(READING_ADDRESS) end default: begin data_out_sig <= 32'h00000000; address_rd_sig <= 4'd0; end endcase end endmodule //TB// module TB_BRAM(); reg clk; reg [31:0]data_in; reg [3:0]address; reg wr_enable; reg Rst; wire[31:0]data_out; bram_pl b1 (.clk(clk),.data_in(data_in),.address(address),.Rst(Rst),.wr_enable(wr_enable),.data_out(data_out)); initial begin clk = 1'b0; end always #5 clk = ~clk; initial begin Rst = 1'b1; #10; Rst = 1'b0; //#70; //rst = 1'b1; //#75; //rst = 1'b0; end initial begin data_in = 32'h0a3d70a3; address = 4'd0; wr_enable = 1'b1; #100; data_in = 32'h0e560418; address = 4'd1; wr_enable = 1'b1; #100; data_in = 32'h147ae147; address = 4'd2; wr_enable = 1'b1; #100; data_in = 32'h20c49ba5; address = 4'd3; wr_enable = 1'b1; #100; address = 4'd0; wr_enable = 1'b0; #100; address = 4'd1; wr_enable = 1'b0; #100; address = 4'd2; wr_enable = 1'b0; #100; address = 4'd3; wr_enable = 1'b0; #100; end endmodule
INITIALLY IT SHOWS UNKNOWN..WHY SO..
AND ALSO IN BETWEEN TOO?WHY?
AND THEN IT INCREMENTS AS SHOWN IN DATA_OUT...IS THAT PART CORRECT?
02-15-2019 09:25 PM
Sir,reply me whenever you are free...waiting for your Reply
02-16-2019 04:09 AM
sir there is increment in data_out values because of the "data_in <= data_in + 32'h04000004"let me know on this!!,is this simulation,correct..?let me know...i have attached the code were "i have combined both the BRAM and the FSM in one verilog file". sorry for asking ..stupid questions,at the start..
THANKS IN ADVANCE
02-16-2019 04:11 AM
CODE attached here
module bram_pl( input clk, input Rst, input[31:0]data_in, input[3:0]address, input wr_enable, output wire[31:0] data_out ); /////////////////////////////////////////////////////////////////////////////////////////////// //reg [31:0]data_out_sig = 32'h00000000; reg [31:0]data_in_sig = 32'h00000000; reg [2:0]current_state = 3'b000; reg [3:0]address_wr_sig = 4'd0; reg [31:0]RAM[15:0]; reg [3:0]address_rd_sig = 4'd0; /////////////////////////////////////////////////////////////////////////////////////////////// parameter INIT = 3'b000; parameter READING_ADDRESS = 3'b001; parameter INC_ADDRESS = 3'b010; parameter WRITE_BACK = 3'b011; //parameter DONE = 3'b100; /////////////////////////////////////////////////////////////////////////////////////////////// //assign data_in = data_in_sig; //assign address = address_rd_sig; /////////////////////////////////////////////////////////////////////////////////////////////// always@(posedge clk) begin data_in_sig <= data_in; address_rd_sig <= address; case(current_state) INIT: begin if(Rst == 1) begin current_state <= INIT; // data_out_sig <= 32'h00000000; end else current_state <= READING_ADDRESS; end///end has been added....to end the "INIT" state ..as the FSM will be stuck in the same state. READING_ADDRESS: begin RAM[address_rd_sig] <= data_in_sig; // data_out_sig <= RAM[address_rd_sig]; current_state <= INC_ADDRESS; end INC_ADDRESS: begin data_in_sig <= data_in_sig + 32'h04000004; address_rd_sig <= address_rd_sig + 4'd4; current_state <= WRITE_BACK; end WRITE_BACK: if(wr_enable == 1) begin RAM[address_rd_sig] <= data_in_sig; address_wr_sig <= address_rd_sig; current_state <= INIT; end //DONE: // begin // data_out_sig <= RAM[address_wr_sig]; // current_state <= INIT;/////////Had Written "DONE"but in simulation,FSM was stuck..so its going back to 1(READING_ADDRESS) // end default: begin // data_out_sig <= 32'h00000000; address_rd_sig <= 4'd0; data_in_sig <= 32'h00000000; end endcase end assign data_out = RAM[address_wr_sig]; endmodule
02-16-2019 04:36 AM
here the simulation...iam not sure whats going ...its incremneted the dout + 4 ...from the input data...just verify this
THANKS IN ADVANCE,@ronnywebersi need clarification on this..as in whether the logic simulation is correct? or not?
02-17-2019 04:52 AM - edited 02-17-2019 04:58 AM
@sam007, not yet sure what's going on, it incremented the lowest byte with 4 and highest byte with 4 too..
again, I think you should design in a more modular way :
create 1 separate file which is the RAM, see for example UG901 (Synthesis guide) on how to infer RAM in code. Later, you will probably replace this RAM module with the Block Memroy Generator + dual port RAM IP in the block diagram. Separating the RAM into 1 module will also simplify your understanding of what is happening.
So in UG901 in the link I gave you, check on page 111 for 'rams_sp_rf_rst.v', and build yourself a separate memory module. (there's are many ways to build a RAM shown in that chapter, single-port, dual-port, and so on. But start with a simple single-port block ram).
Then create a 2nd file for your FSM. Think of your FSM as a 'controller' that connects to the RAM (like a microprocessor). Draw a block diagram of your FSM module connecting to that single port RAM module (connect the ports like dout, we, addr, from the FSM block to the memory). So you need to see 2 blocks on paper, 1 FSM block, 1 RAM block, and then a bunch of connections. Your FSM will then generate all the signals to control the operation of that RAM. The RAM is just a 'slave' module to the FSM.
To make these 'connections', create a 3rd file, which will be your testbench. In that testbench, you instantiate and hook up both the RAM module and FSM with each other, and generate stimuli to your FSM (clock, reset, enable) and RAM (clock, reset). The we, data, ... for the RAM are generated by the FSM.
you really need to think modular, and I also think you should hold your breath, step back a little, read a good verilog book, start from some working examples (like UG937 Logic simulation tutorial), and then move on. I'm sorry I cannot help you much with verilog, but if you make a clean block design and think modular, I"m sure you'll get there. Also checkout that UG901 further, chapter 4 shows a lot of coding techniques, also for FSM on page 162