PLICの実装を試している。自作CPUのSoC環境にPLICをインスタンスして接続する。
PLICの実装は、どこからかオープンソースのものを取ってこようと思う。
とりあえず以下のように接続する。
logic [ 7: 0] w_ie [1]; // Interrupt enable per source, for each target logic [ 2: 0] w_ipriority[8]; // Priority for each source (priority is a reserved keyword) logic [ 2: 0] w_threshold[1]; // Priority Threshold for each target logic [ 0: 0] w_int_req; logic [ 3: 0] w_int_id[1]; logic [ 0: 0] w_int_claim; logic [ 0: 0] w_int_complete; assign w_ie[0] = {8{w_plic_if.ie}}; assign w_ipriority[0] = 3'h0; assign w_ipriority[1] = 3'h0; assign w_ipriority[2] = 3'h0; assign w_ipriority[3] = 3'h0; assign w_ipriority[4] = 3'h0; assign w_ipriority[5] = 3'h0; assign w_ipriority[6] = 3'h0; assign w_ipriority[7] = 3'h0; assign w_threshold[0] = 3'h0; assign w_plic_if.int_id = w_int_id[0]; plic_core #( .SOURCES (8), //Number of interrupt sources .TARGETS (1), //Number of interrupt targets .PRIORITIES (8), //Number of Priority levels .MAX_PENDING_COUNT (0) ) u_plic_core ( .clk (i_clk), // Input: System clock .rst_n (i_reset_n), // Input: Active low asynchronous reset .src (i_interrupts), // Input: Interrupt request from devices/sources .el (1'b0), // Input: Edge/Level sensitive for each source .ip (w_plic_if.ip), // Output: Interrupt Pending for each source .ie (w_ie), // Input: Interrupt enable per source, for each target .ipriority (w_ipriority), // Input: Priority for each source (priority is a reserved keyword) .threshold (w_threshold), // Input: Priority Threshold for each target .ireq (w_plic_if.int_valid ), // Output: Interrupt request for each target .id (w_int_id ), // Output: Interrupt ID (1..SOURCES), for each target .claim (1'b0 ), // Input: Interrupt claim .complete (w_plic_if.int_complete) // Input: Interrupt handling complete );
ここで、claim
ポートについてはなんだかよく分からないのでとりあえず0に設定している。それ以外は、ピンをPLICとCPUの間で接続して、CSRに結び付けている。
PLICの割込みポートの接続は以下のようにする。
# CPU Instance. self.cpu_params = dict( # Clk / Rst. i_i_clk = ClockSignal("sys"), i_i_reset_n = ~ResetSignal("sys") | self.reset, # Interrupts i_i_interrupts = self.interrupt,