总线仲裁(三)

Copyright (C) 2010 Alex Hsu
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <
http://www.gnu.org/licenses/>.


通过前面的方法进行仲裁有一个问题,当两个优先级比较高的Master都移位到了最高位的数组,这个时候,如果这两个Master每两次先后争夺总线资源,
会导致下面的情况:第一个clk,Master0获得总线资源,移位到了低优先级的数组中,第二个clk,Master1获得总线资源,移位到了低优先级的数组中,
但是同时把Master0从低优先级中移位到了高优先级中,第三个clk,Master0获得总线资源,移位到了低优先级的数组中,
但是同时把Master1从低优先级中移位到了高优先级中,如此反复,产生死循环,所以在最高优先级的数组中,将元素的顺序颠倒一下,
将原本低优先级的元素放到了数组的高优先级中,高优先级的元素放到了数组的低优先级中,这样就解决了这个问题。

module bus(
    clk,
rst_n,
awvalid,
awready,
op
);
input        clk;
input        rst_n;
input  [6:0] awvalid;
input  [6:0] awready;
output [6:0] op;

wire         clk;
wire         rst_n;
wire   [6:0] awvalid;
wire   [6:0] awready;
wire   [6:0] op;

reg [7:0] m0;
reg [7:0] m1;
reg [7:0] m2;
reg [7:0] m3;
reg [7:0] m4;
reg [7:0] m5;
reg [7:0] m6;

wire [7:0] m0_v;
wire [7:0] m1_v;
wire [7:0] m2_v;
wire [7:0] m3_v;
wire [7:0] m4_v;
wire [7:0] m5_v;
wire [7:0] m6_v;

wire [7:0] m0_0;
wire [7:0] m1_0;
wire [7:0] m2_0;
wire [7:0] m3_0;
wire [7:0] m4_0;
wire [7:0] m5_0;
wire [7:0] m6_0;

wire [6:0] b0;
wire [6:0] b1;
wire [6:0] b2;
wire [6:0] b3;
wire [6:0] b4;
wire [6:0] b5;
wire [6:0] b6;
wire [6:0] b7;

wire [6:0] b0_or;
wire [6:0] b1_or;
wire [6:0] b2_or;
wire [6:0] b3_or;
wire [6:0] b4_or;
wire [6:0] b5_or;
wire [6:0] b6_or;
wire [6:0] b7_or;

reg [6:0] b0_t;
reg [6:0] b1_t;
reg [6:0] b2_t;
reg [6:0] b3_t;
reg [6:0] b4_t;
reg [6:0] b5_t;
reg [6:0] b6_t;
reg [6:0] b7_t;

wire [6:0] b0_o;
wire [6:0] b1_o;
wire [6:0] b2_o;
wire [6:0] b3_o;
wire [6:0] b4_o;
wire [6:0] b5_o;
wire [6:0] b6_o;
wire [6:0] b7_o;

wire m6_op;
wire m5_op;
wire m4_op;
wire m3_op;
wire m2_op;
wire m1_op;
wire m0_op;

wire [6:0] pre_op;
reg [6:0] m_valid;

assign pre_op = op;

always @(posedge clk or negedge rst_n) begin
if(rst_n == 0) begin
m6 <= 8’b00000001;
end
    else if(pre_op[6] == 1 && m6[0] != 1) begin
m6 <= {1’b0, m6[7:1]};
    end
else if(pre_op[6] == 0 && m6[7] != 1) begin
m6 <= {m6[7:1], 1’b0};
end
else begin
m6 <= m6;
end
end

always @(posedge clk or negedge rst_n) begin
if(rst_n == 0) begin
m5 <= 8’b00000001;
end
    else if(pre_op[5] == 1 && m5[0] != 1) begin
m5 <= {1’b0, m5[7:1]};
    end
else if(pre_op[5] == 0 && m5[7] != 1) begin
m5 <= {m5[7:1], 1’b0};
end
else begin
m5 <= m5;
end
end

always @(posedge clk or negedge rst_n) begin
if(rst_n == 0) begin
m4 <= 8’b00000001;
end
    else if(pre_op[4] == 1 && m4[0] != 1) begin
m4 <= {1’b0, m4[7:1]};
    end
else if(pre_op[4] == 0 && m4[7] != 1) begin
m4 <= {m4[7:1], 1’b0};
end
else begin
m4 <= m4;
end
end

always @(posedge clk or negedge rst_n) begin
if(rst_n == 0) begin
m3 <= 8’b00000001;
end
    else if(pre_op[3] == 1 && m3[0] != 1) begin
m3 <= {1’b0, m3[7:1]};
    end
else if(pre_op[3] == 0 && m3[7] != 1) begin
m3 <= {m3[7:1], 1’b0};
end
else begin
m3 <= m3;
end
end

always @(posedge clk or negedge rst_n) begin
if(rst_n == 0) begin
m2 <= 8’b00000001;
end
    else if(pre_op[2] == 1 && m2[0] != 1) begin
m2 <= {1’b0, m2[7:1]};
    end
else if(pre_op[2] == 0 && m2[7] != 1) begin
m2 <= {m2[7:1], 1’b0};
end
else begin
m2 <= m2;
end
end

always @(posedge clk or negedge rst_n) begin
if(rst_n == 0) begin
m1 <= 8’b00000001;
end
    else if(pre_op[1] == 1 && m1[0] != 1) begin
m1 <= {1’b0, m1[7:1]};
    end
else if(pre_op[1] == 0 && m1[7] != 1) begin
m1 <= {m1[7:1], 1’b0};
end
else begin
m1 <= m1;
end
end

always @(posedge clk or negedge rst_n) begin
if(rst_n == 0) begin
m0 <= 8’b00000001;
end
    else if(pre_op[0] == 1 && m0[0] != 1) begin
m0 <= {1’b0, m0[7:1]};
    end
else if(pre_op[0] == 0 && m0[7] != 1) begin
m0 <= {m0[7:1], 1’b0};
end
else begin
m0 <= m0;
end
end

always @(posedge clk or negedge rst_n) begin
if(rst_n == 0) begin
m_valid <= 0;
end
else begin
        m_valid = awvalid & aready;
end
end

assign m6_v = m_valid[6] ? m6 : 8’h0;
assign m5_v = m_valid[5] ? m5 : 8’h0;
assign m4_v = m_valid[4] ? m4 : 8’h0;
assign m3_v = m_valid[3] ? m3 : 8’h0;
assign m2_v = m_valid[2] ? m2 : 8’h0;
assign m1_v = m_valid[1] ? m1 : 8’h0;
assign m0_v = m_valid[0] ? m0 : 8’h0;

assign b7 = {m6_v[7], m5_v[7], m4_v[7], m3_v[7], m2_v[7], m1_v[7], m0_v[7]};
assign b6 = {m6_v[6], m5_v[6], m4_v[6], m3_v[6], m2_v[6], m1_v[6], m0_v[6]};
assign b5 = {m6_v[5], m5_v[5], m4_v[5], m3_v[5], m2_v[5], m1_v[5], m0_v[5]};
assign b4 = {m6_v[4], m5_v[4], m4_v[4], m3_v[4], m2_v[4], m1_v[4], m0_v[4]};
assign b3 = {m6_v[3], m5_v[3], m4_v[3], m3_v[3], m2_v[3], m1_v[3], m0_v[3]};
assign b2 = {m6_v[2], m5_v[2], m4_v[2], m3_v[2], m2_v[2], m1_v[2], m0_v[2]};
assign b1 = {m6_v[1], m5_v[1], m4_v[1], m3_v[1], m2_v[1], m1_v[1], m0_v[1]};
assign b0 = {m6_v[0], m5_v[0], m4_v[0], m3_v[0], m2_v[0], m1_v[0], m0_v[0]};

assign b7_or = |b7;
assign b6_or = |b6;
assign b5_or = |b5;
assign b4_or = |b4;
assign b3_or = |b3;
assign b2_or = |b2;
assign b1_or = |b1;
assign b0_or = |b0;

assign b6_en = b7_or;
assign b5_en = b7_or | b6_or;
assign b4_en = b7_or | b6_or | b5_or;
assign b3_en = b7_or | b6_or | b5_or | b4_or;
assign b2_en = b7_or | b6_or | b5_or | b4_or | b3_or;
assign b1_en = b7_or | b6_or | b5_or | b4_or | b3_or | b2_or;
assign b0_en = b7_or | b6_or | b5_or | b4_or | b3_or | b2_or | b1_or;

always @(b7) begin
casex(b7)
7’b1xxxxxx: b7_t = 7’b1000000;
7’bx1xxxxx: b7_t = 7’b0100000;
7’bxx1xxxx: b7_t = 7’b0010000;
7’bxxx1xxx: b7_t = 7’b0001000;
7’bxxxx1xx: b7_t = 7’b0000100;
7’bxxxxx1x: b7_t = 7’b0000010;
7’bxxxxxx1: b7_t = 7’b0000001;
default: b7_t = 7’h0;
endcase
end

always @(b6) begin
casex(b6)
7’b1xxxxxx: b6_t = 7’b1000000;
7’bx1xxxxx: b6_t = 7’b0100000;
7’bxx1xxxx: b6_t = 7’b0010000;
7’bxxx1xxx: b6_t = 7’b0001000;
7’bxxxx1xx: b6_t = 7’b0000100;
7’bxxxxx1x: b6_t = 7’b0000010;
7’bxxxxxx1: b6_t = 7’b0000001;
default: b6_t = 7’h0;
endcase
end

always @(b5) begin
casex(b5)
6’b1xxxxxx: b5_t = 7’b1000000;
6’bx1xxxxx: b5_t = 7’b0100000;
6’bxx1xxxx: b5_t = 7’b0010000;
6’bxxx1xxx: b5_t = 7’b0001000;
6’bxxxx1xx: b5_t = 7’b0000100;
6’bxxxxx1x: b5_t = 7’b0000010;
6’bxxxxxx1: b5_t = 7’b0000001;
default: b5_t = 7’h0;
endcase
end

always @(b4) begin
casex(b4)
7’b1xxxxxx: b4_t = 7’b1000000;
7’bx1xxxxx: b4_t = 7’b0100000;
7’bxx1xxxx: b4_t = 7’b0010000;
7’bxxx1xxx: b4_t = 7’b0001000;
7’bxxxx1xx: b4_t = 7’b0000100;
7’bxxxxx1x: b4_t = 7’b0000010;
7’bxxxxxx1: b4_t = 7’b0000001;
default: b4_t = 7’h0;
endcase
end

always @(b3) begin
casex(b3)
7’b1xxxxxx: b3_t = 7’b1000000;
7’bx1xxxxx: b3_t = 7’b0100000;
7’bxx1xxxx: b3_t = 7’b0010000;
7’bxxx1xxx: b3_t = 7’b0001000;
7’bxxxx1xx: b3_t = 7’b0000100;
7’bxxxxx1x: b3_t = 7’b0000010;
7’bxxxxxx1: b3_t = 7’b0000001;
default: b3_t = 7’h0;
endcase
end

always @(b2) begin
casex(b2)
7’b1xxxxxx: b2_t = 7’b1000000;
7’bx1xxxxx: b2_t = 7’b0100000;
7’bxx1xxxx: b2_t = 7’b0010000;
7’bxxx1xxx: b2_t = 7’b0001000;
7’bxxxx1xx: b2_t = 7’b0000100;
7’bxxxxx1x: b2_t = 7’b0000010;
7’bxxxxxx1: b2_t = 7’b0000001;
default: b2_t = 7’h0;
endcase
end

always @(b1) begin
casex(b1)
7’b1xxxxxx: b1_t = 7’b1000000;
7’bx1xxxxx: b1_t = 7’b0100000;
7’bxx1xxxx: b1_t = 7’b0010000;
7’bxxx1xxx: b1_t = 7’b0001000;
7’bxxxx1xx: b1_t = 7’b0000100;
7’bxxxxx1x: b1_t = 7’b0000010;
7’bxxxxxx1: b1_t = 7’b0000001;
default: b1_t = 7’h0;
endcase
end

always @(b0) begin
casex(b0)
7’b1xxxxxx: b0_t = 7’b1000000;
7’bx1xxxxx: b0_t = 7’b0100000;
7’bxx1xxxx: b0_t = 7’b0010000;
7’bxxx1xxx: b0_t = 7’b0001000;
7’bxxxx1xx: b0_t = 7’b0000100;
7’bxxxxx1x: b0_t = 7’b0000010;
7’bxxxxxx1: b0_t = 7’b0000001;
default: b0_t = 7’h0;
endcase
end

assign b7_o = b7_t;
assign b6_o = b6_en ? 7’h0 : b6_t;
assign b5_o = b5_en ? 7’h0 : b5_t;
assign b4_o = b4_en ? 7’h0 : b4_t;
assign b3_o = b3_en ? 7’h0 : b3_t;
assign b2_o = b2_en ? 7’h0 : b2_t;
assign b1_o = b1_en ? 7’h0 : b1_t;
assign b0_o = b0_en ? 7’h0 : b0_t;

assign m6_o = {b7_o[0], b6_o[6], b5_o[6], b4_o[6], b3_o[6], b2_o[6], b1_o[6], b0_o[6]};
assign m5_o = {b7_o[1], b6_o[5], b5_o[5], b4_o[5], b3_o[5], b2_o[5], b1_o[5], b0_o[5]};
assign m4_o = {b7_o[2], b6_o[4], b5_o[4], b4_o[4], b3_o[4], b2_o[4], b1_o[4], b0_o[4]};
assign m3_o = {b7_o[3], b6_o[3], b5_o[3], b4_o[3], b3_o[3], b2_o[3], b1_o[3], b0_o[3]};
assign m2_o = {b7_o[4], b6_o[2], b5_o[2], b4_o[2], b3_o[2], b2_o[2], b1_o[2], b0_o[2]};
assign m1_o = {b7_o[5], b6_o[1], b5_o[1], b4_o[1], b3_o[1], b2_o[1], b1_o[1], b0_o[1]};
assign m0_o = {b7_o[6], b6_o[0], b5_o[0], b4_o[0], b3_o[0], b2_o[0], b1_o[0], b0_o[0]};

assign m6_op = |b6_o;
assign m5_op = |b5_o;
assign m4_op = |b4_o;
assign m3_op = |b3_o;
assign m2_op = |b2_o;
assign m1_op = |b1_o;
assign m0_op = |b0_o;

assign op = {m6_op, m5_op, m4_op, m3_op, m2_op, m1_op, m0_op};

endmodule

Advertisements
This entry was posted in Computers and Internet. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s