ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [SystemVerilog] 인터페이스 2
    개발/SystemVerilog 2022. 1. 16. 21:38

    모듈을 파라미터로 인스턴스 할 수 있듯이, 인터페이스도 파라미터로 정의 가능하다.

     

    // paramterized interface with default value
    interface busA #(DATAWIDTH = 32, ADDRWIDTH = 16) (input clk);
    	
        logic [DATAWIDTH-1 : 0] data;
        logic [ADDRWIDTH-1 : 0] addr;
    	...
    endinterface
    
    interface busB (input clk);
        // internal parameter
        parameter WIDTH = 8;
        logic [WIDTH-1 : 0] data;
        logic [WIDTH-1 : 0] addr;
        ...
    endinterface
    
    
    module top;
        logic clk = 0;
        
        // positional
        busA #(16, 8) bus1(clk);		// DATAWIDTH = 16, ADDRWIDTH = 8
        
        // named
        busA #(.ADDRWIDHT(32)) bus2(clk);	// DATAWIDTH = 32, ADDRWIDTH = 32
        
        ...
        
    endmodule

     

     

     

    이전글의 예제에서 인터페이스 블럭으로 연결만 해주었다.

    모듈끼리 연결을 위해서는 각 모듈에 맞게 신호들의 방향을 정해야한다.

    modport 문법으로 각 블럭마다 신호들의 방향을 따로 지정해줄 수 있다.

     

    interface mod_if;
    
        logic a, b, c, d;
        
        modport master (
        	input a, b,
            output c, d
        );
        
        modport slave (
        	input c, d,
            output a, b
        );
        
        modport subset (
        	input a,
            output c
        );
    
    endinterface

    어떤 마스터와 슬레이브가 1:1 연결되었다고 가정하자.

    마스터 입장에서 a, b, 는 입력이고 c, d는 출력이다. 그렇다면 슬레이브는 반대로 a, b가 출력이고, c, d는 입력이 되야한다. modport 는 인터페이스 신호들 중 일부만 방향을 지정하는것도 가능하다.

     

     

     

    module masterModule(mod_if.master mbus);
       ...
    endmodule
    
    module slaveModule(mod_if.slave sbus);
       ...
    endmodule
    
    
    module top
        mod_if bus;
        masterModule master(.mbus(bus));
        slaveModule slave(.sbus(bus));
    endmodule

    모듈의 포트를 정의할때 modport를 포함할 수 있다. 

    모듈포트에 modport를 포함시킨다면, 굳이 bus.master / bus.slave 으로 쓰지 않아도 알아서 modport를 mapping 해준다.

     

     

     

    module masterModule(mod_if mbus);
       ...
    endmodule
    
    module slaveModule(mod_if sbus);
       ...
    endmodule
    
    
    module top
        mod_if bus;
        masterModule master(.mbus(bus.master));
        slaveModule slave(.sbus(bus.slave));
    endmodule

    만약 modport를 포함하지 않고 그냥 인터페이스만으로 모듈의 포트를 선언했다면,

    인터페이스를 인스턴스하고 각 모듈에 연결할 땐 bus.master / bus.slave 처럼 modport를 참조해야한다.

     

     

     

     

    인터페이스 내부에 task / function 정의할 수 있다. 이를 인터페이스의 메서드라고 한다.

    interface simple_bus(input clk);
        logic req, start, gnt, rdy;
        logic [1:0] mode;
        logic [7:0] addr;
        wire [7:0] data;
        
        task read (input [7:0] address, output [7:0] r_data);
        	@(negedge clk)
            addr = address;
            ...
        endtask
        
        task write (input [7:0] address, w_data);
        	@(negedge clk)
            addr = address;
            data = w_data;
            ...
        endtask
    endinterface
    
    
    module cpuModule(simple_bus bus);
        ...
        bus.read();
        ...
    endmodule

    만약에 인터페이스의 메서드가 없다면, 버스에 연결된 각각의 master / slave 내부에 트랜잭션을 만드는 태스크를 정의 해야한다. 이는 코드가 복잡해지고 유지보수가 어려워진다.

    반면 인터페이스에서 읽기, 쓰기 등의 메서드를 정의하면, 해당 인터페이스에 연결된 master / slave의  내부에 태스크를  정의할 필요 없이 인터페이스의 메서드를 사용 할 수 있다. 즉 인터페이스를 이용해서 트랜잭션을 만들 수 있다.

    또한 코드가 간결해지고 유지보수가 쉬워진다.

     

     

    인터페이스에 연결된 어떤 모듈은 특정 태스크만 사용할 수 있게 만들 수 있다.

    modport 를 이용해서 import <task> 로 지정하면, 해당 modport로 선언된 모듈은 그 태스크만 접근할 수 있다.

    interface simple_bus(input clk);
        logic req, start, gnt, rdy;
        logic [1:0] mode;
        logic [7:0] addr;
        wire [7:0] data;
        
        modport master(
        	input clk, gnt, rdy,
            output start, req, mode, addr,
            inout data,
            import read
        );
        
        task read (input [7:0] address, output [7:0] r_data);
        	@(negedge clk)
            addr = address;
            ...
        endtask
        
    endinterface
    
    
    module cpuModule(simple_bus.master bus);
        ...
        bus.read();
        ...
    endmodule

    modport 내부엔 신호들의 방향과 함께 메서드가 임포트 되어있다.

    cpuModule은 read 태스크만 접근하여 사용 할 수 있다.

Designed by Tistory.