[BLOG UNDER CONSTRUCTION]
AMBA
AMBA is a bus protocol.
AMBA
AMBA is a bus protocol.
What is a protocol ?
In Practical life you can say
It is a way of communication from one entity(let mobile) to
another entity (say cloud).
Now every communication system has its specific
syntax,semantics and timing.
In Nasa Mars rover
protocol is so slow that rover data takes 1 hour to reach to the earth.
AMBA BURST
AMBA RETRY
AMBA SPLIT
Code for Master
- module ahb_master4(
- //transfer response
- input hready,
- //global signals
- input hclk,
- input hresetn, //active low
- input [1:0]hresp,
- //read data
- input [31:0]hrdata,
- input hgrant,
- //address and control
- output reg [31:0]haddr,
- output reg hwrite,
- output reg [2:0]hsize,
- output reg [2:0]hburst,
- output reg [1:0]htrans,
- output reg hreq,
- //DATA
- output reg [31:0]hwdata
- );
- reg [31:0] rhaddr;
- reg [31:0]rhrdata;
- reg [31:0] mem[8:0]; //it means it has nine meom loc under which there is further 32 locations
- reg [2:0] ps,ns;
- integer count;
- parameter idle=3'b000,trans=3'b001,check=3'b010,Nonseq=3'b011,Seq=3'b100,Write=3'b101,Read=3'b110;
- always @(posedge hclk)
- begin
- $readmemb("memory.txt",mem);
- case(ps)
- idle : begin
- if(!hresetn)
- begin
- haddr=0;
- hsize=0;
- hburst=0;
- htrans=0;
- hwdata=0;
- hwrite=1;
- ns=idle;
- end
- else if(hready & !hresp)
- begin
- hreq=1'b1;
- ns=trans;
- end
- end
- trans : begin
- if(hready & hgrant & !hresp)
- begin
- htrans<=2'b10;
- haddr<=32'd00;
- rhaddr<=haddr;
- hburst<=3'b010;
- hwrite<=1;
- hsize<=3'b010;
- ns=check;
- end
- else
- ns=idle;
- end
- check : begin
- if(hready & !hresp) begin
- if(htrans==2'b10)
- begin
- ns=Nonseq;
- count=0;
- end
- else if(htrans==2'b11)
- begin
- ns=Seq;
- count=0;
- end
- else if(htrans==2'b00)
- ns=idle;
- end
- end
- Nonseq : begin
- if((hgrant==1'b1) & hready & !hresp)
- begin
- /*haddr<=haddr;
- hburst<=3'b000;
- hsize<=3'b010;
- hwrite<=0;
- end*/
- if(hwrite)
- ns=Write;
- else
- ns=Read;
- end
- end
- Seq : begin
- if((hgrant==1'b1) && hready && !hresp && htrans!=2'b01) //Busy transfer htrans=2'b01
- begin
- htrans=2'b11;
- case(hburst)
- 3'b000 : haddr=haddr; //Single Burst
- 3'b001 : begin //Incrementing Burst with undefined length
- count=count+1;
- if(hsize==3'b000)
- haddr=haddr+1;
- else if(hsize==3'b001)
- haddr=haddr+2;
- else if(hsize==3'b010)
- haddr=haddr+4;
- end
- 3'b010 : begin
- count=count+1; //Wrapping Burst with 4 beats
- if(hsize==3'b000)
- begin
- haddr=haddr+1;
- if(haddr==rhaddr+16)
- haddr=rhaddr;
- end
- else if(hsize==3'b001)
- begin
- haddr=haddr+2;
- if(haddr==rhaddr+16)
- haddr=rhaddr;
- end
- else if(hsize==3'b010)
- begin
- haddr=haddr+4;
- if(haddr==rhaddr+16)
- haddr=rhaddr;
- end
- end
- 3'b011 : begin
- count=count+1; // Incrementing Burst with 4 beats
- if(hsize==3'b000)
- haddr=haddr+1;
- else if(hsize==3'b001)
- haddr=haddr+2;
- else if(hsize==3'b010)
- haddr=haddr+4;
- end
- 3'b100 : begin
- count=count+1;
- if(hsize==3'b000) //8 Beat wrapping burst
- begin
- haddr=haddr+1;
- if(haddr!=rhaddr+32)
- haddr=rhaddr;
- end
- else if(hsize==3'b001)
- begin
- haddr=haddr+2;
- if(haddr!=rhaddr+32)
- haddr=rhaddr;
- end
- else if(hsize==3'b010)
- begin
- haddr=haddr+4;
- if(haddr!=rhaddr+32)
- haddr=rhaddr;
- end
- end
- 3'b101 : begin
- count=count+1; // Incrementing Burst with 8 beats
- if(hsize==3'b000)
- haddr=haddr+1;
- else if(hsize==3'b001)
- haddr=haddr+2;
- else if(hsize==3'b010)
- haddr=haddr+4;
- end
- 3'b110 : begin
- count=count+1;
- if(hsize==3'b000) //16 Beat wrapping burst
- begin
- haddr=haddr+1;
- if(haddr!=rhaddr+64)
- haddr=rhaddr;
- end
- else if(hsize==3'b001)
- begin
- haddr=haddr+2;
- if(haddr!=rhaddr+64)
- haddr=rhaddr;
- end
- else if(hsize==3'b010)
- begin
- haddr=haddr+4;
- if(haddr!=rhaddr+64)
- haddr=rhaddr;
- end
- end
- 3'b111 : begin
- count=count+1; // Incrementing Burst with 16 beats
- if(hsize==3'b000)
- haddr=haddr+1;
- else if(hsize==3'b001)
- haddr=haddr+2;
- else if(hsize==3'b010)
- haddr=haddr+4;
- end
- endcase
- if(hwrite)
- ns=Write;
- else
- ns=Read;
- end
- else if(hresp==2'b10)
- begin
- htrans=0;
- ns=idle; end
- else if(hresp==2'b11)
- begin ns<=ps; htrans<=0; end
- end
- Write : begin
- if(hready & !hresp) begin
- if(hsize==3'b000)
- begin
- hwdata[7:0]=mem[7];
- end
- else if(hsize==3'b001)
- begin
- hwdata[15:0]=mem[5];
- end
- else if(hsize==3'b010)
- begin
- hwdata=mem[2];
- end
- if(hburst!=0)
- begin
- if(hburst==3'b001)
- ns=Seq;
- else if((hburst==3'b010 | hburst==3'b011) & count<3)
- ns=Seq;
- else if((hburst==3'b100 | hburst==3'b101) & count<7)
- ns=Seq;
- else if((hburst==3'b110 | hburst==3'b111) & count<15)
- ns=Seq;
- else
- ns=idle;
- end
- else
- ns=idle;
- end
- end
- Read :begin if(hready & !hresp)
- begin
- if(hsize==3'b000)
- begin
- rhrdata=hrdata[7:0];
- end
- else if(hsize==3'b001)
- begin
- rhrdata=hrdata[15:0];
- end
- else if(hsize==3'b010)
- begin
- rhrdata=hrdata;
- end
- if(hburst!=0)
- begin
- if(hburst==3'b001)
- ns=Seq;
- else if((hburst==3'b010 | hburst==3'b011) & count<3)
- ns=Seq;
- else if((hburst==3'b100 | hburst==3'b101) & count<7)
- ns=Seq;
- else if((hburst==3'b110 | hburst==3'b111) & count<15)
- ns=Seq;
- else
- ns=idle;
- end
- else
- ns=idle;
- end
- end
- endcase
- end
- always@(posedge hclk)
- begin
- if(!hresetn)
- ps<=idle;
- else
- ps<=ns;
- end
- endmodule
Testbench for Master
- module ahb_master4_tb;
- // Inputs
- reg hready;
- reg hclk;
- reg hresetn;
- reg [1:0]hresp;
- reg [31:0] hrdata;
- reg hgrant;
- // Outputs
- wire [31:0] haddr;
- wire hwrite;
- wire [2:0] hsize;
- wire [2:0] hburst;
- wire [1:0] htrans;
- wire hreq;
- wire [31:0] hwdata;
- // Instantiate the Unit Under Test (UUT)
- ahb_master4 uut (
- .hready(hready),
- .hclk(hclk),
- .hresetn(hresetn),
- .hresp(hresp),
- .hrdata(hrdata),
- .hgrant(hgrant),
- .haddr(haddr),
- .hwrite(hwrite),
- .hsize(hsize),
- .hburst(hburst),
- .htrans(htrans),
- .hreq(hreq),
- .hwdata(hwdata)
- );
- initial begin
- // Initialize Inputs
- hready = 0;
- hclk = 0;
- hresetn = 0;
- hresp = 0;
- hrdata = 0;
- hgrant = 0;
- // Wait 100 ns for global reset to finish
- #100;
- hready <= 1;
- hresetn <= 1;
- hresp <= 0;
- hrdata <= 32'd4100450780;
- hgrant <= 1;
- // Wait 100 ns for global reset to finish
- #200;
- hready <= 1;
- hresetn <= 1;
- hresp <= 0;
- hrdata <= 32'd4123450460;
- hgrant <= 1;
- #200;
- hready <= 0;
- hresetn <= 1;
- hresp <= 0;
- hrdata <= 32'd4123450461;
- hgrant <= 1;
- // Wait 100 ns for global reset to finish
- #200;
- hready <= 1;
- hresetn <= 1;
- hresp <= 2'b11;
- hrdata <= 32'd4123450461;
- hgrant <= 1;
- // Wait 100 ns for global reset to finish
- #200;
- hready <= 1;
- hresetn <= 1;
- hresp <= 0;
- hrdata <= 32'd4123450461;
- hgrant <= 1;
- end
- always #20 hclk=~hclk;
- initial
- $monitor("time=%d,hready=%b,read_data=%d,address=%d",$time,hready,uut.rhrdata,haddr);
- // Add stimulus here
- endmodule
Code for slave
- module ahb_slave2(
- input hsel,
- //Address and control
- input [31:0]haddr,
- input hwrite,
- input [1:0]htrans,
- input [2:0]hsize,
- input [2:0]hburst,
- //Data
- input [31:0]hwdata,
- //Global Signal
- input hclk,
- input hresetn,
- //Output signals
- output reg hready,
- output reg [1:0]hresp,
- output reg [31:0]hrdata
- );
- reg rhsel;
- reg [31:0]rhaddr;
- reg rhwrite;
- reg [1:0]rhtrans;
- reg [2:0]rhsize;
- reg [2:0]rhburst;
- reg [31:0]mem[12:0];
- always @(posedge hclk,negedge hresetn)
- begin
- if(!hresetn)
- begin
- rhsel<=hsel;
- rhaddr<=0;
- rhwrite<=0;
- rhtrans<=0;
- rhsize<=0;
- rhburst<=0;
- hready<=1;
- hresp<=0;
- end
- else if(rhsel)
- begin
- rhaddr<=haddr;
- rhwrite<=hwrite;
- rhtrans<=htrans;
- rhsize<=hsize;
- rhburst<=hburst;
- hready=1;
- end
- end
- always @(posedge hclk,rhaddr)
- begin
- if(rhsel && rhwrite)
- begin
- if(rhsize==3'b000)
- mem[rhaddr[29:0]]=hwdata[7:0];
- else if(rhsize==3'b001)
- mem[rhaddr[29:0]]=hwdata[15:0];
- else if(rhsize==3'b010)
- mem[rhaddr[29:0]]=hwdata;
- if(rhaddr<=12) begin
- hready=1;
- hresp=0;
- end
- else begin
- hready=0;
- hresp=2'b01;
- end
- end
- else if(rhsel && !rhwrite)
- begin
- if(rhsize==3'b000) begin
- hrdata[7:0]=8'd13;
- hrdata[31:8]=24'bx; end
- else if(rhsize==3'b001) begin
- hrdata[15:0]=16'd34;
- hrdata[31:16]=16'bx; end
- else if(rhsize==3'b010)
- hrdata=32'd134;
- if(rhaddr<=12) begin
- hready=1;
- hresp=0;
- end
- else begin
- hready=0;
- hresp=2'b01;
- end
- end
- end
- endmodule
Test Bench for Slave
- module ahb_slave2_tb;
- // Inputs
- reg hsel;
- reg [31:0] haddr;
- reg hwrite;
- reg [1:0] htrans;
- reg [2:0] hsize;
- reg [2:0] hburst;
- reg [31:0] hwdata;
- reg hclk;
- reg hresetn;
- // Outputs
- wire hready;
- wire [1:0] hresp;
- wire [31:0] hrdata;
- // Instantiate the Unit Under Test (UUT)
- ahb_slave2 uut (
- .hsel(hsel),
- .haddr(haddr),
- .hwrite(hwrite),
- .htrans(htrans),
- .hsize(hsize),
- .hburst(hburst),
- .hwdata(hwdata),
- .hclk(hclk),
- .hresetn(hresetn),
- .hready(hready),
- .hresp(hresp),
- .hrdata(hrdata)
- );
- initial begin
- // Initialize Inputs
- hsel = 1;
- haddr = 0;
- hwrite = 0;
- htrans = 0;
- hsize = 0;
- hburst = 0;
- hwdata = 0;
- hclk = 0;
- hresetn = 0;
- // Wait 100 ns for global reset to finish
- #100;
- hsel = 1;
- haddr = 32'd00;
- hwrite = 1;
- htrans = 2'b10;
- hsize = 3'b010;
- hburst = 3'b010;
- hwdata = 32'd49;
- hresetn = 1;
- // Wait 100 ns for global reset to finish
- #100;
- hsel = 1;
- haddr = 32'd04;
- hwrite = 1;
- htrans = 2'b11;
- hsize = 3'b010;
- hburst = 3'b010;
- hwdata = 32'd45;
- hresetn = 1;
- // Wait 100 ns for global reset to finish
- #100;
- hsel = 1;
- haddr = 32'd08;
- hwrite = 1;
- htrans = 2'b11;
- hsize = 3'b010;
- hburst = 3'b010;
- hwdata = 32'd47;
- hresetn = 1;
- // Wait 100 ns for global reset to finish
- #100;
- hsel = 1;
- haddr = 32'd12;
- hwrite = 1;
- htrans = 2'b11;
- hsize = 3'b010;
- hburst = 3'b010;
- hwdata = 32'd43;
- hresetn = 1;
- // Add stimulus here
- end
- always #50 hclk=~hclk;
- endmodule
Code for AHB
- module ahb(
- input hclk,
- input hresetn,
- input hgrant,
- output reg hreq,
- input hsel
- );
- wire hready;
- wire [1:0]hresp;
- wire hwrite;
- wire [31:0]haddr;
- wire [31:0]hwdata;
- wire [31:0]hrdata;
- wire [2:0]hsize;
- wire [2:0]hburst;
- wire [1:0]htrans;
- ahb_master4 m1(hready,hclk,hresetn,hresp,hrdata,hgrant,haddr,hwrite,hsize,hburst,htrans,hreq,hwdata);
- ahb_slave s1(hsel,haddr,hwrite,htrans,hsize,hburst,hwdata,hclk,hresetn,hready,hresp,hrdata);
- endmodule
Code for AHB test bench
module ahb_tb;
- // Inputs
- reg hclk;
- reg hresetn;
- reg hgrant;
- reg hsel;
- // Outputs
- wire hreq;
- // Instantiate the Unit Under Test (UUT)
- ahb uut (
- .hclk(hclk),
- .hresetn(hresetn),
- .hgrant(hgrant),
- .hreq(hreq),
- .hsel(hsel)
- );
- initial begin
- // Initialize Inputs
- hclk = 0;
- hresetn = 0;
- hgrant = 0;
- hsel = 0;
- // Wait 100 ns for global reset to finish
- #200;
- hresetn =0;
- hgrant = 1;
- hsel = 1;
- // Wait 100 ns for global reset to finish
- #100;
- // Add stimulus here
- hresetn = 1;
- hgrant = 1;
- hsel = 1;
- // Wait 100 ns for global reset to finish
- end
- always #50 hclk=~hclk;
- endmodule
No comments:
Post a Comment