OpenCores
URL https://opencores.org/ocsvn/spicc/spicc/trunk

Subversion Repositories spicc

[/] [spicc/] [trunk/] [wb_picc.v] - Rev 6

Go to most recent revision | Compare with Previous | Blame | View Log

 
module top (  input clk,
    input ir0,
    input ir1,
    input ir2,
    input ir3,
    input ir4,
    input ir5,
    input ir6,
    input rst,
    input wb_cyc,
    input wb_sel,
    input wb_std,
    input wb_we,
    input [7:0] wb_addr,
    input [7:0] wb_din,
    output wb_ack,
    output wb_irq,
    output [7:0] wb_dout
    );
 
    wire [2:0] irq_no;
    wire [7:0] w_mask;
    wire [2:0] w_pir;
 
    pri_rslv1 U1
              (
                  .int_o(wb_irq),
                  .ir0(ir0),
                  .ir1(ir1),
                  .ir2(ir2),
                  .ir3(ir3),
                  .ir4(ir4),
                  .ir5(ir5),
                  .ir6(ir6),
                  .ir7(ir6),
                  .irq_no(irq_no),
                  .mask_in(w_mask),
                  .pri_in(w_pir)
              );
 
    wb_if U2
          (
              .clk(clk),
              .irq_no(irq_no),
              .mask(w_mask),
              .pri_no_reg(w_pir),
              .ret(rst),
              .wb_ack(wb_ack),
              .wb_addr(wb_addr[7:0]),
              .wb_cyc(wb_cyc),
              .wb_din(wb_din),
              .wb_dout(wb_dout),
              .wb_sel(wb_sel),
              .wb_std(wb_std),
              .wb_we(wb_we)
          );
 
endmodule
 
 
`define ADDR_MASK_REG 0
`define ADDR_PRI_NO_REG 1
`define ADDR_IRQ_NO_REG 2
`define WB_B2
//`define WB_B3
 
module wb_if(
        input clk,
        input rst,
 
        input [7:0] wb_din,
        output reg [7:0] wb_dout,
        input wb_sel,
        input wb_std,
        input wb_we,
        input wb_cyc,
        input [1:0] wb_addr,
        output reg wb_ack,
 
        input  [2:0] irq_no,
        output reg [7:0] mask,
        output reg [2:0] pri_no_reg
    );
 
    /*
    latch the irq_no input 
    */
    reg [2:0] irq_no_reg ;
    always@(posedge clk)   
		if (ret)irq_no_reg<=3'bxxx;
        irq_no_reg<=irq_no;
 
    reg [7:0] mask_reg ;
	/* the bit bit 0 is the mask of ir0
	for exmple the bit 0 is the mask of ir0.
	so when you clear bit 0 ,the ir0 interrupt request will be ignored 
	*/
 
    assign wb_access = wb_sel & wb_std & wb_cyc ;						
 
    assign sel_mask = wb_addr == `ADDR_MASK_REG && wb_access ;
    assign sel_irq_no_reg = wb_addr == `ADDR_IRQ_NO_REG&& wb_access ;
    assign sel_pri_no_reg = wb_addr == `ADDR_PRI_NO_REG && wb_access ;
	/*
 
	*/
 
`ifdef WB_B2
		always@(posedge clk)//WISHBONE B2        
`else
		always@(*) //WISHBONE B3
`endif
	  wb_ack = wb_access ;
 
    assign wr_mask = sel_mask & wb_we ;
    assign wr_irq_no_reg = sel_irq_no_reg & wb_we ;
    assign wr_pri_no_reg = sel_pri_no_reg& wb_we ;
 
    always@(posedge clk)
    case({sel_mask,sel_irq_no_reg,sel_pri_no_reg})
        1: wb_dout<={5'bxxxxx,pri_no_reg[2:0]} ; /*read the pripority number setted by WISHHONE bus before */
        2: wb_dout<={5'bxxxxx,irq_no_reg[2:0]};	 /*read which line has a interrupt request*/
        4: wb_dout<=mask_reg;/*read mask setted by WISHHONE bus before*/
        default :
            wb_dout<=8'bxxxx_xxxx; 	/*WISHBONE bus does not want to read this device after all and will ignore the output_data*/
    endcase
 
    always@(posedge clk)
    if (rst)begin 
    	mask_reg<=0;//disable all interrput
    	pri_no_reg <=3'bxxx;
    end else
    case ({wr_mask,wr_pri_no_reg})
        2:mask_reg <= wb_din; //write mask register
        1:pri_no_reg <= wb_din[2:0]; //write priory number register
    endcase
endmodule
 
 
module pri_rslv1(
        input ir0,
        input ir1,
        input ir2,
        input ir3,
        input ir4,
        input ir5,
        input ir6,
        input ir7,
        input [7:0] mask_in,
        input [2:0] pri_in,
        output reg [2:0] irq_no,
        output reg int_o
    );
 
    wire [7:0] valid_ir_data= {ir7,ir6,ir5,ir4,ir3,ir2,ir1,ir0} & mask_in;
    /*mask here used to disable some interrupt request which we do not care about*/
 
    reg [3:0] int_pri_ir;
    /*to indicate  priority of the current legal interruput*/
 
    always @(*)
    casex( valid_ir_data )
        /*
        8-3 Line Priority Encoder which is similar with 74LS148 device
        the ir0 has the highest pripority while the ir7 has the lowwest one
        */
        {8'bxxxxxxx1}: int_pri_ir = 7;
        {8'bxxxxxx10}: int_pri_ir = 6;
        {8'bxxxxx100}: int_pri_ir = 5;
        {8'bxxxx1000}: int_pri_ir = 4;
        {8'bxxx10000}: int_pri_ir = 3;
        {8'bxx100000}: int_pri_ir = 2;
        {8'bx1000000}: int_pri_ir = 1;
        {8'b10000000}: int_pri_ir = 0;
        default 
        int_pri_ir<=3'bxxx;
        /*
        each interrupt request bit is 0 ,namely,there are not bits setted 
        the int_o =0 && (pri_in < int_pri_ir) =0,(see below)
        so we can safly set  int_pri_ir = 3'bxxx as default to reduce the logic resource usage.
        */
    endcase
 
/*
if there is a interruput and the priority is greater than the current 
interrupt priority,the generate a gloable interrput request signal.
*/
    always@(*)
        int_o  =  (valid_ir_data!=0)&&(pri_in < int_pri_ir);
 
/*
there bits interrupt number
*/
    always@(*)
        irq_no = int_pri_ir[2:0] ;
 
endmodule
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.