📄 dw8051_intr_1.v
字号:
// SFR Write process always @(posedge clk or negedge rst_n) begin : sfr_process // cs_process if (rst_n == 0) begin ie_reg <= 'b0; ip_reg <= 7'b0000000; it0 <= 0; it1 <= 0; tr0 <= 0; tr1 <= 0; tf0 <= 0; tf1 <= 0; ie0 <= 0; ie1 <= 0; exif_reg <= 4'b0000; eie_reg <= 5'b00000; eip_reg <= 5'b00000; smod1_reg <= 0; epfi <= 0; pfi_reg <= 0; wdti_reg <= 0; end else begin if (sfr_wr == 1) // Software update of registers begin if (ie_cs == 1) ie_reg <= intr_data_in; if (ip_cs == 1) ip_reg <= intr_data_in[6:0]; if (tcon_cs == 1) begin it0 <= intr_data_in[0]; it1 <= intr_data_in[2]; tr0 <= intr_data_in[4]; tr1 <= intr_data_in[6]; end if (eie_cs == 1) eie_reg <= intr_data_in[4:0]; if (eip_cs == 1) eip_reg <= intr_data_in[4:0]; end // Hardware update of TF0 has greater priority than software update. if (tf0_set == 1) tf0 <= 1; else if (tf0_clr == 1) tf0 <= 0; else if (tcon_wr == 1) tf0 <= intr_data_in[5]; // Hardware update of TF1 has greater priority than software update. if (tf1_set == 1) tf1 <= 1; else if (tf1_clr == 1) tf1 <= 0; else if (tcon_wr == 1) tf1 <= intr_data_in[7]; // Hardware update of IE0 has greater priority than software update. if (ie0_set == 1) ie0 <= 1; else if (ie0_clr == 1) ie0 <= 0; else if (tcon_wr == 1) ie0 <= intr_data_in[1]; // Hardware update of IE0 has greater priority than software update. if (ie1_set == 1) ie1 <= 1; else if (ie1_clr == 1) ie1 <= 0; else if (tcon_wr == 1) ie1 <= intr_data_in[3]; // Hardware update of IE2 has greater priority than software update. if (ie2_set == 1) exif_reg[4] <= 1; else if ((sfr_wr == 1) & (exif_cs == 1)) exif_reg[4] <= intr_data_in[4]; // Hardware update of IE3 has greater priority than software update. if (ie3_set == 1) exif_reg[5] <= 1; else if ((sfr_wr == 1) & (exif_cs == 1)) exif_reg[5] <= intr_data_in[5]; // Hardware update of IE4 has greater priority than software update. if (ie4_set == 1) exif_reg[6] <= 1; else if ((sfr_wr == 1) & (exif_cs == 1)) exif_reg[6] <= intr_data_in[6]; // Hardware update of IE5 has greater priority than software update. if (ie5_set == 1) exif_reg[7] <= 1; else if ((sfr_wr == 1) & (exif_cs == 1)) exif_reg[7] <= intr_data_in[7]; if (eicon_wr == 1) begin smod1_reg <= intr_data_in[7]; epfi <= intr_data_in[5]; end // Hardware update of PFI has greater priority than software update. if (pfi_set == 1) pfi_reg <= 1; else if (eicon_wr == 1) pfi_reg <= intr_data_in[4]; // Hardware update of WDTI has greater priority than software update. if (wdti_set == 1) wdti_reg <= 1; else if (eicon_wr == 1) wdti_reg <= intr_data_in[3]; end end //sfr_process // Aliases of IE register bits assign ea = ie_reg[7]; assign es0 = ie_reg[4]; assign es1 = ie_reg[6]; assign et0 = ie_reg[1]; assign et1 = ie_reg[3]; assign et2 = ie_reg[5]; assign ex0 = ie_reg[0]; assign ex1 = ie_reg[2]; // Aliases of IP register bits assign ps0 = ip_reg[4]; assign ps1 = ip_reg[6]; assign pt0 = ip_reg[1]; assign pt1 = ip_reg[3]; assign pt2 = ip_reg[5]; assign px0 = ip_reg[0]; assign px1 = ip_reg[2]; // Aliases of TCON register bits assign tcon_reg[0] = it0; assign tcon_reg[1] = ie0; assign tcon_reg[2] = it1; assign tcon_reg[3] = ie1; assign tcon_reg[4] = tr0; assign tcon_reg[5] = tf0; assign tcon_reg[6] = tr1; assign tcon_reg[7] = tf1; // Aliases of EXIF register bits assign ie5 = exif_reg[7]; assign ie4 = exif_reg[6]; assign ie3 = exif_reg[5]; assign ie2 = exif_reg[4]; // Aliases of EIE register bits assign ewdi = eie_reg[4]; assign ex5 = eie_reg[3]; assign ex4 = eie_reg[2]; assign ex3 = eie_reg[1]; assign ex2 = eie_reg[0]; // Aliases of EIP register bits assign pwdi = eip_reg[4]; assign px5 = eip_reg[3]; assign px4 = eip_reg[2]; assign px3 = eip_reg[1]; assign px2 = eip_reg[0]; // external interrupt requests always @(posedge clk or negedge rst_n) begin : int_latch_process if (rst_n == 0) begin x0_l1_n <= 0; x0_l2_n <= 0; x0_l3_n <= 0; x1_l1_n <= 0; x1_l2_n <= 0; x1_l3_n <= 0; x2_l1 <= 1; x2_l2 <= 1; x2_l3 <= 1; x3_l1_n <= 0; x3_l2_n <= 0; x3_l3_n <= 0; x4_l1 <= 1; x4_l2 <= 1; x4_l3 <= 1; x5_l1_n <= 0; x5_l2_n <= 0; x5_l3_n <= 0; pfi_l1 <= 0; pfi_l2 <= 0; wdti_l1 <= 0; wdti_l2 <= 0; wdti_l3 <= 0; end else begin x0_l1_n <= int0_n; // Stage 1 synchronizers for all interrupts x1_l1_n <= int1_n; // work at each clock. x2_l1 <= int2; x3_l1_n <= int3_n; x4_l1 <= int4; x5_l1_n <= int5_n; pfi_l1 <= pfi; wdti_l1 <= wdti; if (cycle == `c4) begin x0_l2_n <= x0_l1_n; // Stage 2 and Stage 3 synchronizers are x1_l2_n <= x1_l1_n; // enabled only at the end of clock phase C4. x2_l2 <= x2_l1; x3_l2_n <= x3_l1_n; x4_l2 <= x4_l1; x5_l2_n <= x5_l1_n; x0_l3_n <= x0_l2_n; x1_l3_n <= x1_l2_n; x2_l3 <= x2_l2; x3_l3_n <= x3_l2_n; x4_l3 <= x4_l2; x5_l3_n <= x5_l2_n; pfi_l2 <= pfi_l1; wdti_l2 <= wdti_l1; wdti_l3 <= wdti_l2; end end end //int_latch_process // Interrupt Mask Logic assign x0_req = ie0 & ex0; assign x1_req = ie1 & ex1; assign t0_req = (tf0 | tf0_set) & et0; assign t1_req = (tf1 | tf1_set) & et1; assign s0_req = (ri0 | ti0) & es0; assign t2_req = (tf2 | exf2) & et2; assign x2_req = ie2 & ex2; assign x3_req = ie3 & ex3; assign x4_req = ie4 & ex4; assign x5_req = ie5 & ex5; assign s1_req = (ri1 | ti1) & es1; assign wd_req = wdti_reg & ewdi; assign pf_req = pfi_reg & epfi; // priorities of requests assign x0_hp_req = x0_req & px0; assign x0_lp_req = x0_req & ~px0; assign x1_hp_req = x1_req & px1; assign x1_lp_req = x1_req & ~px1; assign x2_hp_req = x2_req & px2; assign x2_lp_req = x2_req & ~px2; assign x3_hp_req = x3_req & px3; assign x3_lp_req = x3_req & ~px3; assign x4_hp_req = x4_req & px4; assign x4_lp_req = x4_req & ~px4; assign x5_hp_req = x5_req & px5; assign x5_lp_req = x5_req & ~px5; assign t0_hp_req = t0_req & pt0; assign t0_lp_req = t0_req & ~pt0; assign t1_hp_req = t1_req & pt1; assign t1_lp_req = t1_req & ~pt1; assign t2_hp_req = t2_req & pt2; assign t2_lp_req = t2_req & ~pt2; assign s0_hp_req = s0_req & ps0; assign s0_lp_req = s0_req & ~ps0; assign s1_hp_req = s1_req & ps1; assign s1_lp_req = s1_req & ~ps1; assign wd_hp_req = wd_req & pwdi; assign wd_lp_req = wd_req & ~pwdi; // interrupt sources // High priority queue assign hp_src = (x0_hp_req == 1) ? `x0_src : (t0_hp_req == 1) ? `t0_src : (x1_hp_req == 1) ? `x1_src : (t1_hp_req == 1) ? `t1_src : (s0_hp_req == 1) ? `s0_src : (t2_hp_req == 1) ? `t2_src : (s1_hp_req == 1) ? `s1_src : (x2_hp_req == 1) ? `x2_src : (x3_hp_req == 1) ? `x3_src : (x4_hp_req == 1) ? `x4_src : (x5_hp_req == 1) ? `x5_src : `wd_src; // Low priority queue assign lp_src = (x0_lp_req == 1) ? `x0_src : (t0_lp_req == 1) ? `t0_src : (x1_lp_req == 1) ? `x1_src : (t1_lp_req == 1) ? `t1_src : (s0_lp_req == 1) ? `s0_src : (t2_lp_req == 1) ? `t2_src : (s1_lp_req == 1) ? `s1_src : (x2_lp_req == 1) ? `x2_src : (x3_lp_req == 1) ? `x3_src : (x4_lp_req == 1) ? `x4_src : (x5_lp_req == 1) ? `x5_src : `wd_src; // High-priority interrupt request generation. assign hp_req = (x0_hp_req | t0_hp_req | x1_hp_req | t1_hp_req | s0_hp_req | t2_hp_req | s1_hp_req | x2_hp_req | x3_hp_req | x4_hp_req | x5_hp_req | wd_hp_req) & ea & (~(pf_req | iip2)); // Low priority interrupt request generation. // The lp_req is enabled only when there is no high-priority request, // and when there is no hi-pri request being serviced, and when there is // no low-pri request being serviced. assign lp_req = (x0_lp_req | t0_lp_req | x1_lp_req | t1_lp_req | s0_lp_req | t2_lp_req | s1_lp_req | x2_lp_req | x3_lp_req | x4_lp_req | x5_lp_req | wd_lp_req) & ea & (~(pf_req | iip2)) & (~(hp_req | iip1)); // requests for all interrupt levels sampled at the begin of c3 always @(posedge clk or negedge rst_n) begin : req_process if (rst_n == 0) begin pf_req_l <= 0; hp_req_l <= 0; lp_req_l <= 0; end else begin if (cycle == `c2) begin pf_req_l <= pf_req; hp_req_l <= hp_req; lp_req_l <= lp_req; end end end //req_process // control signals for iip process assign iip2_set = pf_req_l & int_ack; assign iip2_clr = int_clr; assign iip1_set = hp_req_l & int_ack; assign iip1_clr = int_clr & ~iip2; assign iip0_set = lp_req_l & int_ack; assign iip0_clr = int_clr & (~(iip1 | iip2)); always @(posedge clk or negedge rst_n) begin : iip_process if (rst_n == 0) begin iip0 <= 0; iip1 <= 0; iip2 <= 0; end else begin if (iip0_set == 1) iip0 <= 1; else if (iip0_clr == 1) iip0 <= 0; if (iip1_set == 1) iip1 <= 1; else if (iip1_clr == 1) iip1 <= 0; if (iip2_set == 1) iip2 <= 1; else if (iip2_clr == 1) iip2 <= 0; end end //iip_process // compute output signals assign i_src = (pf_req == 1) ? `pf_src : (hp_req == 1) ? hp_src : lp_src; assign int_src = i_src_l; assign int_req = (pf_req_l & ~iip2) | (hp_req_l & ~iip1) | (lp_req_l & ~iip0); assign intr_sfr_cs = ie_cs | ip_cs | tcon_cs | exif_cs | eie_cs | eip_cs | eicon_cs; assign ena_t0 = tr0; assign ena_t1 = tr1; assign smod1 = smod1_reg; assign eicon_reg = {smod1_reg, 1'b1, epfi, pfi_reg, wdti_reg, 3'b000}; // output mux assign intr_data_out = (ie_cs == 1) ? ie_reg : (ip_cs == 1) ? {1'b1, ip_reg} : (tcon_cs == 1) ? tcon_reg : (exif_cs == 1) ? {exif_reg, 4'b1000} : (eie_cs == 1) ? {3'b111, eie_reg} : (eip_cs == 1) ? {3'b111, eip_reg} : eicon_reg; // store source of actual interrupt always @(posedge clk or negedge rst_n) begin : i_src_latch_process if (rst_n == 0) begin i_src_l <= 'b0; end else begin if (cycle == `c2) i_src_l <= i_src; end end // delay int_ack 1 cycle always @(posedge clk or negedge rst_n) begin : i_int_ack_process if (rst_n == 0) begin ack_l <= 0; end else begin ack_l <= int_ack; end end endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -