ch12_接口interface

接口interface

形式

type 接口名 interface{
    方法名(...) ...
    ...
}

核心思想

  • 只要一个结构体实现了该接口的所有方法,就认为这个结构体实现了这个方法,便可以用这个结构体去生成该接口的变量了。
type USB interface {
    Name() string
    Connect()
}
type PhoneConnector struct {
    name string
}

func (pc PhoneConnector) Name() string {
    return pc.name
}
func (pc PhoneConnector) Connect() {
    fmt.Println("Connected", pc.name)
}
func main() {
    var a USB
    a = PhoneConnector{"PhoneConnector"}
    a.Connect()
}

嵌入接口

type 接口名 interface{
    方法名(...) ...
    ...
    另一个接口名
}
type USB interface {
    Name() string
    Connector
}
type Connector interface {
    Connect()
}
type PhoneConnector struct {
    name string
}

func (pc PhoneConnector) Name() string {
    return pc.name
}
func (pc PhoneConnector) Connect() {
    fmt.Println("Connected", pc.name)
}
func Disconnect(usb USB) {
    fmt.Println("Disconnected.")
}
func main() {
    a := PhoneConnector{"PhoneConnector"}
    a.Connect()
    Disconnect(a)
}

类型断言

  • 判断实现这个接口的变量是什么类型的,以便使用这个类型内独有的函数和变量
  • 通过类型断言的ok pattern可以判断接口中的数据类型
  • 使用type switch则可针对空接口进行比较全面的类型判断
func Disconnect(usb USB) {
    if pc, ok := usb.(PhoneConnector); ok {
        fmt.Println("Disconnected:", pc.name)
    }
}
  • 所有类型都实现了空接口interface{}
func Disconnect(usb interface{}) {
    switch v := usb.(type) {
    case int:
        ...
    case ...:
        ...
    case PhoneConnector:
        fmt.Println("Disconnected:", v.name)
    default:
        fmt.Println("Unknown device.")
    }
}

接口转换

  • 一个接口只能"降级"转换成它所嵌入的子接口,反之不行
    a := PhoneConnector{"PhoneConnector"}
    b := Connector(a)
    //b.Name() //无法调用

注意事项

  • 将对象赋值给接口时,会发生拷贝,而接口内部存储的是指向这个
    复制品的指针,既无法修改复制品的状态,也无法获取指针。
    a := PhoneConnector{"PhoneConnector"}
    b := Connector(a)
    b.Connect()
    a.name = "22222"
    b.Connect()

输出结果

Connected PhoneConnector
Connected PhoneConnector

  • 只有当接口存储的类型和对象都为nil时,接口才等于nil
    var a interface{}
    fmt.Println(a == nil)
    var p *int = nil
    a = p
    fmt.Println(a == nil)

输出结果

true
false

  • 接口调用不会做receiver的自动转换
  • 接口同样支持匿名字段方法
  • 接口也可实现类似OOP中的多态
  • 空接口可以作为任何类型数据的容器
给这个代码加上合适的英文注释。module DTP_ARB ( input wire clk , // System clock input wire rst_n , // Active-low reset // Buffer0 input interface input wire buf0_vld , // Input buffer valid input wire [ 2:0] buf0_id , // Input buffer ID input wire [ 7:0] buf0_data , // Input data input wire buf0_pre_eop , // Input pre-end-of-packet input wire buf0_qos , // Input QoS priority // Buffer1 input interface input wire buf1_vld , // Input buffer valid input wire [ 2:0] buf1_id , // Input buffer ID input wire [ 7:0] buf1_data , // Input data input wire buf1_pre_eop , // Input pre-end-of-packet input wire buf1_qos , // Input QoS priority // Buffer2 input interface input wire buf2_vld , // Input buffer valid input wire [ 2:0] buf2_id , // Input buffer ID input wire [ 7:0] buf2_data , // Input data input wire buf2_pre_eop , // Input pre-end-of-packet input wire buf2_qos , // Input QoS priority // Buffer3 input interface input wire buf3_vld , // Input buffer valid input wire [ 2:0] buf3_id , // Input buffer ID input wire [ 7:0] buf3_data , // Input data input wire buf3_pre_eop , // Input pre-end-of-packet input wire buf3_qos , // Input QoS priority // Buffer4 input interface input wire buf4_vld , // Input buffer valid input wire [ 2:0] buf4_id , // Input buffer ID input wire [ 7:0] buf4_data , // Input data input wire buf4_pre_eop , // Input pre-end-of-packet input wire buf4_qos , // Input QoS priority // Buffer5 input interface input wire buf5_vld , // Input buffer valid input wire [ 2:0] buf5_id , // Input buffer ID input wire [ 7:0] buf5_data , // Input data input wire buf5_pre_eop , // Input pre-end-of-packet input wire buf5_qos , // Input QoS priority // Buffer6 input interface input wire buf6_vld , // Input buffer valid input wire [ 2:0] buf6_id , // Input buffer ID input wire [ 7:0] buf6_data , // Input data input wire buf6_pre_eop , // Input pre-end-of-packet input wire buf6_qos , // Input QoS priority // Buffer7 input interface input wire buf7_vld , // Input buffer valid input wire [ 2:0] buf7_id , // Input buffer ID input wire [ 7:0] buf7_data , // Input data input wire buf7_pre_eop , // Input pre-end-of-packet input wire buf7_qos , // Input QoS priority // Ch0 output interface output reg ch0_vld_out , // Output valid output reg [ 2:0] ch0_id_out , // Output CH ID output reg [ 7:0] ch0_data_out , // Output data output reg ch0_sop_out , // Output start-of-packet output reg ch0_eop_out , // Output end-of-packet output reg ch0_qos_out , // Output QoS priority // Ch1 output interface output reg ch1_vld_out , // Output valid output reg [ 2:0] ch1_id_out , // Output CH ID output reg [ 7:0] ch1_data_out , // Output data output reg ch1_sop_out , // Output start-of-packet output reg ch1_eop_out , // Output end-of-packet output reg ch1_qos_out , // Output QoS priority // Ch2 output interface output reg ch2_vld_out , // Output valid output reg [ 2:0] ch2_id_out , // Output CH ID output reg [ 7:0] ch2_data_out , // Output data output reg ch2_sop_out , // Output start-of-packet output reg ch2_eop_out , // Output end-of-packet output reg ch2_qos_out , // Output QoS priority // Ch3 output interface output reg ch3_vld_out , // Output valid output reg [ 2:0] ch3_id_out , // Output CH ID output reg [ 7:0] ch3_data_out , // Output data output reg ch3_sop_out , // Output start-of-packet output reg ch3_eop_out , // Output end-of-packet output reg ch3_qos_out , // Output QoS priority // Ch4 output interface output reg ch4_vld_out , // Output valid output reg [ 2:0] ch4_id_out , // Output CH ID output reg [ 7:0] ch4_data_out , // Output data output reg ch4_sop_out , // Output start-of-packet output reg ch4_eop_out , // Output end-of-packet output reg ch4_qos_out , // Output QoS priority // Ch5 output interface output reg ch5_vld_out , // Output valid output reg [ 2:0] ch5_id_out , // Output CH ID output reg [ 7:0] ch5_data_out , // Output data output reg ch5_sop_out , // Output start-of-packet output reg ch5_eop_out , // Output end-of-packet output reg ch5_qos_out , // Output QoS priority // Ch6 output interface output reg ch6_vld_out , // Output valid output reg [ 2:0] ch6_id_out , // Output CH ID output reg [ 7:0] ch6_data_out , // Output data output reg ch6_sop_out , // Output start-of-packet output reg ch6_eop_out , // Output end-of-packet output reg ch6_qos_out , // Output QoS priority // Ch7 output interface output reg ch7_vld_out , // Output valid output reg [ 2:0] ch7_id_out , // Output CH ID output reg [ 7:0] ch7_data_out , // Output data output reg ch7_sop_out , // Output start-of-packet output reg ch7_eop_out , // Output end-of-packet output reg ch7_qos_out , // Output QoS priority // DFx output output reg [31:0] dtp0_out_pkt_cnt, output reg [31:0] dtp1_out_pkt_cnt, output reg [31:0] dtp2_out_pkt_cnt, output reg [31:0] dtp3_out_pkt_cnt, output reg [31:0] dtp4_out_pkt_cnt, output reg [31:0] dtp5_out_pkt_cnt, output reg [31:0] dtp6_out_pkt_cnt, output reg [31:0] dtp7_out_pkt_cnt, // Arb En output output wire [ 7:0] arb_en ); reg busy; wire grant_vld; wire rr_en ; wire [7:0] rr_ready ; wire [7:0] grant ; reg [7:0] arb_ch ; reg [2:0] buf_id ; reg buf_qos ; reg buf_pre_eop ; reg buf_pre_eop_d1; reg [7:0] buf_data ; reg cho_vld; reg buf_sop; assign rr_en = |rr_ready & !busy; assign rr_ready = {buf7_vld,buf6_vld,buf5_vld,buf4_vld,buf3_vld,buf2_vld,buf1_vld,buf0_vld}; assign arb_en = grant_vld ? grant : 8'b0; always @(posedge clk or negedge rst_n) begin if(!rst_n) begin busy <= 1'b0; end else begin if(grant_vld) begin busy <= 1'b1; end else if(buf_pre_eop) begin busy <= 1'b0; end end end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin buf_pre_eop_d1 <= 1'b0; end else begin buf_pre_eop_d1 <= buf_pre_eop; end end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin cho_vld <= 1'b0; end else begin if(grant_vld) begin cho_vld <= 1'b1; end else if(buf_pre_eop_d1) begin cho_vld <= 1'b0; end end end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin buf_sop <= 1'b0; end else begin buf_sop <= grant_vld; end end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin ch0_vld_out <= 1'b0; ch0_id_out <= 3'b0; ch0_data_out <= 8'b0; ch0_sop_out <= 1'b0; ch0_eop_out <= 1'b0; ch0_qos_out <= 1'b0; end else begin if(cho_vld && (buf_id == 3'd0))begin ch0_vld_out <= 1'b1; ch0_id_out <= buf_id; ch0_data_out <= buf_data; ch0_sop_out <= buf_sop; ch0_eop_out <= buf_pre_eop_d1; ch0_qos_out <= buf_qos; end else begin ch0_vld_out <= 1'b0; ch0_id_out <= 3'b0; ch0_sop_out <= 1'b0; ch0_eop_out <= 1'b0; ch0_qos_out <= 1'b0; end end end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin ch1_vld_out <= 1'b0; ch1_id_out <= 3'b0; ch1_data_out <= 8'b0; ch1_sop_out <= 1'b0; ch1_eop_out <= 1'b0; ch1_qos_out <= 1'b0; end else begin if(cho_vld && (buf_id == 3'd1))begin ch1_vld_out <= 1'b1; ch1_id_out <= buf_id; ch1_data_out <= buf_data; ch1_sop_out <= buf_sop; ch1_eop_out <= buf_pre_eop_d1; ch1_qos_out <= buf_qos; end else begin ch1_vld_out <= 1'b0; ch1_id_out <= 3'b0; ch1_sop_out <= 1'b0; ch1_eop_out <= 1'b0; ch1_qos_out <= 1'b0; end end end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin ch2_vld_out <= 1'b0; ch2_id_out <= 3'b0; ch2_data_out <= 8'b0; ch2_sop_out <= 1'b0; ch2_eop_out <= 1'b0; ch2_qos_out <= 1'b0; end else begin if(cho_vld && (buf_id == 3'd2))begin ch2_vld_out <= 1'b1; ch2_id_out <= buf_id; ch2_data_out <= buf_data; ch2_sop_out <= buf_sop; ch2_eop_out <= buf_pre_eop_d1; ch2_qos_out <= buf_qos; end else begin ch2_vld_out <= 1'b0; ch2_id_out <= 3'b0; ch2_sop_out <= 1'b0; ch2_eop_out <= 1'b0; ch2_qos_out <= 1'b0; end end end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin ch3_vld_out <= 1'b0; ch3_id_out <= 3'b0; ch3_data_out <= 8'b0; ch3_sop_out <= 1'b0; ch3_eop_out <= 1'b0; ch3_qos_out <= 1'b0; end else begin if(cho_vld && (buf_id == 3'd3))begin ch3_vld_out <= 1'b1; ch3_id_out <= buf_id; ch3_data_out <= buf_data; ch3_sop_out <= buf_sop; ch3_eop_out <= buf_pre_eop_d1; ch3_qos_out <= buf_qos; end else begin ch3_vld_out <= 1'b0; ch3_id_out <= 3'b0; ch3_sop_out <= 1'b0; ch3_eop_out <= 1'b0; ch3_qos_out <= 1'b0; end end end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin ch4_vld_out <= 1'b0; ch4_id_out <= 3'b0; ch4_data_out <= 8'b0; ch4_sop_out <= 1'b0; ch4_eop_out <= 1'b0; ch4_qos_out <= 1'b0; end else begin if(cho_vld && (buf_id == 3'd4))begin ch4_vld_out <= 1'b1; ch4_id_out <= buf_id; ch4_data_out <= buf_data; ch4_sop_out <= buf_sop; ch4_eop_out <= buf_pre_eop_d1; ch4_qos_out <= buf_qos; end else begin ch4_vld_out <= 1'b0; ch4_id_out <= 3'b0; ch4_sop_out <= 1'b0; ch4_eop_out <= 1'b0; ch4_qos_out <= 1'b0; end end end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin ch5_vld_out <= 1'b0; ch5_id_out <= 3'b0; ch5_data_out <= 8'b0; ch5_sop_out <= 1'b0; ch5_eop_out <= 1'b0; ch5_qos_out <= 1'b0; end else begin if(cho_vld && (buf_id == 3'd5))begin ch5_vld_out <= 1'b1; ch5_id_out <= buf_id; ch5_data_out <= buf_data; ch5_sop_out <= buf_sop; ch5_eop_out <= buf_pre_eop_d1; ch5_qos_out <= buf_qos; end else begin ch5_vld_out <= 1'b0; ch5_id_out <= 3'b0; ch5_sop_out <= 1'b0; ch5_eop_out <= 1'b0; ch5_qos_out <= 1'b0; end end end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin ch6_vld_out <= 1'b0; ch6_id_out <= 3'b0; ch6_data_out <= 8'b0; ch6_sop_out <= 1'b0; ch6_eop_out <= 1'b0; ch6_qos_out <= 1'b0; end else begin if(cho_vld && (buf_id == 3'd6))begin ch6_vld_out <= 1'b1; ch6_id_out <= buf_id; ch6_data_out <= buf_data; ch6_sop_out <= buf_sop; ch6_eop_out <= buf_pre_eop_d1; ch6_qos_out <= buf_qos; end else begin ch6_vld_out <= 1'b0; ch6_id_out <= 3'b0; ch6_sop_out <= 1'b0; ch6_eop_out <= 1'b0; ch6_qos_out <= 1'b0; end end end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin ch7_vld_out <= 1'b0; ch7_id_out <= 3'b0; ch7_data_out <= 8'b0; ch7_sop_out <= 1'b0; ch7_eop_out <= 1'b0; ch7_qos_out <= 1'b0; end else begin if(cho_vld && (buf_id == 3'd7))begin ch7_vld_out <= 1'b1; ch7_id_out <= buf_id; ch7_data_out <= buf_data; ch7_sop_out <= buf_sop; ch7_eop_out <= buf_pre_eop_d1; ch7_qos_out <= buf_qos; end else begin ch7_vld_out <= 1'b0; ch7_id_out <= 3'b0; ch7_sop_out <= 1'b0; ch7_eop_out <= 1'b0; ch7_qos_out <= 1'b0; end end end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin dtp0_out_pkt_cnt <= 32'b0; dtp1_out_pkt_cnt <= 32'b0; dtp2_out_pkt_cnt <= 32'b0; dtp3_out_pkt_cnt <= 32'b0; dtp4_out_pkt_cnt <= 32'b0; dtp5_out_pkt_cnt <= 32'b0; dtp6_out_pkt_cnt <= 32'b0; dtp7_out_pkt_cnt <= 32'b0; end else begin if(buf_pre_eop)begin case (buf_id) 3'd0 : dtp0_out_pkt_cnt <= dtp0_out_pkt_cnt + 32'b1; 3'd1 : dtp1_out_pkt_cnt <= dtp1_out_pkt_cnt + 32'b1; 3'd2 : dtp2_out_pkt_cnt <= dtp2_out_pkt_cnt + 32'b1; 3'd3 : dtp3_out_pkt_cnt <= dtp3_out_pkt_cnt + 32'b1; 3'd4 : dtp4_out_pkt_cnt <= dtp4_out_pkt_cnt + 32'b1; 3'd5 : dtp5_out_pkt_cnt <= dtp5_out_pkt_cnt + 32'b1; 3'd6 : dtp6_out_pkt_cnt <= dtp6_out_pkt_cnt + 32'b1; 3'd7 : dtp7_out_pkt_cnt <= dtp7_out_pkt_cnt + 32'b1; endcase end end end always @(*) begin buf_id = 3'b0; buf_qos = 1'b0; buf_pre_eop = 1'b0; buf_data = 8'b0; case (arb_ch) 8'bxxxxxx1 : begin buf_id = buf0_id; buf_qos = buf0_qos; buf_pre_eop = buf0_pre_eop; buf_data = buf0_data; end 8'bxxxxx1x : begin buf_id = buf1_id; buf_qos = buf1_qos; buf_pre_eop = buf1_pre_eop; buf_data = buf1_data; end 8'bxxxxx1x : begin buf_id = buf2_id; buf_qos = buf2_qos; buf_pre_eop = buf2_pre_eop; buf_data = buf2_data; end 8'bxxxx1xx : begin buf_id = buf2_id; buf_qos = buf2_qos; buf_pre_eop = buf2_pre_eop; buf_data = buf2_data; end 8'bxxx1xxx : begin buf_id = buf3_id; buf_qos = buf3_qos; buf_pre_eop = buf3_pre_eop; buf_data = buf3_data; end 8'bxx1xxxx : begin buf_id = buf4_id; buf_qos = buf4_qos; buf_pre_eop = buf4_pre_eop; buf_data = buf4_data; end 8'bx1xxxxx : begin buf_id = buf5_id; buf_qos = buf5_qos; buf_pre_eop = buf5_pre_eop; buf_data = buf5_data; end 8'b1xxxxxx : begin buf_id = buf6_id; buf_qos = buf6_qos; buf_pre_eop = buf6_pre_eop; buf_data = buf6_data; end default : begin buf_id = 3'b0; buf_qos = 1'b0; buf_pre_eop = 1'b0; buf_data = 8'b0; end endcase end ARB_RR #(8,1) U_ARB_RR ( .i_clk (clk ), .i_rst_n (rst_n ), .i_ready (rr_ready ), .i_schedule_en(rr_en ), .o_grant_vld (grant_vld), .o_grant (grant ) ); endmodule
07-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值