Skip to end of metadata
Go to start of metadata

You are viewing an old version of this content. View the current version.

Compare with Current View Version History

« Previous Version 2 Next »

本实验可按功能进行模块化设计,最终由顶层文件LED.v将各模块实例化后完成上述要求的设计。设计分为以下两个模块:寄存器接口模块interface.v,七段数码管显示模块display.v。总体架构如下图所示

 

顶层实例模块(LED.v):

实例化接口模块和显示模块,组成最终的完整设计

接口模块(interface.v):

用于和APB BUS进行通信,实现APB BUS MASTER对寄存器的读写操作;完成定时器操作及中断处理;

显示模块(display.v):

将显示缓冲区的内容通过七段数码管显示

4.6.1 设计模块实现

本设计实例中共包含3个Verilog文件,其对应完成整体设计中各独立模块的功能。通过从总线接口读取数据和命令,控制七段数码管显示

4.6.2 总线接口功能设计

本模块设计中共包含1个Verilog文件interface.v,完成寄存器的读写操作,定时器操作及中断处理的功能。相关代码如下:

`define EX_CON_REG  5'h00 //EX_CON_REG

`define EX_TO_REG   5'h01 //EX_TO_REG

`define EX_BUFFER_REG   5'h02 //EX_BUFFER_REG

`define EX_STATE_REG    5'h03 //EX_STATE_REG

/////////register files/////////////////////////////////////

reg [31:0]  EX_CON;         //Control register

reg [31:0]  EX_TO;          //Timer set register

reg [31:0]      EX_BUFFER;   //Display buffer register

wire [31:0]      EX_STATE;  //State register

/////////register R/W judge /////////////////////////////////////

wire            READ_OPER;

wire            WRITE_OPER;

assign READ_OPER    = (!PWRITE) & (!PENABLE) & PSEL;

assign WRITE_OPER   = PWRITE & (!PENABLE) & PSEL;

////////////////////////////write EX_CON register ////////////////////

reg [31:0]  EX_CON_N;  

always @ (posedge SYSCLK or negedge RST_B)

begin

  if(!RST_B)

    EX_CON <= `UD 32'B0;

  else

    EX_CON <= `UD EX_CON_N;

end

always @(*)

begin

 if( WRITE_OPER && ( PADDR == `EX_CON_REG) )

    EX_CON_N = PWDATA;

else

    EX_CON_N = EX_CON;

end

/////////////////////////write  EX_TO register ///////////////////////////////

reg [31:0]  EX_TO_N;      //

always @ (posedge SYSCLK or negedge RST_B)

begin

  if(!RST_B)

    EX_TO <= `UD 32'hffff_ffff;

  else

    EX_TO <= `UD EX_TO_N;

end

always @(*)         

begin

if(WRITE_OPER && (PADDR == `EX_TO_REG))

    EX_TO_N = PWDATA;

else

    EX_TO_N = EX_TO;

end

//////////////////////////////write EX_BUFFER register //////////////////////

reg     [31:0]  EX_BUFFER_N;

always @ (posedge SYSCLK or negedge RST_B)

begin   

  if(!RST_B)

    EX_BUFFER <= `UD 32'B0;

  else

    EX_BUFFER <= `UD EX_BUFFER_N;

end

always @(*)

begin

if( WRITE_OPER && (PADDR == `EX_BUFFER_REG))

    EX_BUFFER_N = PWDATA;

else

    EX_BUFFER_N = EX_BUFFER;

End

////////////////////// read register//////////////////

reg [31:0]      SLAVE_APB_BUS_N,PRDATA;

always @ (posedge SYSCLK or negedge RST_B)

begin   

  if(!RST_B)

    PRDATA <= `UD 32'B0;

  else

    PRDATA <= `UD SLAVE_APB_BUS_N;

end

always @(*)

begin

   case({READ_OPER,PADDR})

   {1'b1,`EX_CON_REG}   :   SLAVE_APB_BUS_N = EX_CON;

   {1'b1,`EX_TO_REG}    :   SLAVE_APB_BUS_N = EX_TO;

   {1'b1,`EX_BUFFER_REG}    :   SLAVE_APB_BUS_N = EX_BUFFER;

   {1'b1,`EX_STATE_REG} :   SLAVE_APB_BUS_N = EX_STATE;

     default    :   SLAVE_APB_BUS_N = PRDATA;

   endcase 

end

//////////////////////定时器操作(Timer to EX_TO and overflow)/////////////////

reg [31:0]  COUNT,COUNT_N;

wire            CNT_START;        //CNT_START signal

wire COUNT_OVERFLOW;

assign CNT_START=EX_CON[1];

assign COUNT_OVERFLOW= (COUNT < EX_TO)? 0:1;

always @(posedge SYSCLK or negedge RST_B)

begin

if(!RST_B)

        COUNT  <= `UD 32'B0;

else

        COUNT  <= `UD COUNT_N;

end

always @(*)

begin

if( CNT_START && (!COUNT_OVERFLOW))

    COUNT_N = COUNT +1'B1;

else 

    COUNT_N = 32'B0;

End

///////////////////////////中断信号INT_B 处理 ////////////////////////////////

reg OVFL_STA,OVFL_STA_N;

wire INT_EN;

wire OVFL_CLS;

assign INT_EN= EX_CON[2];

assign OVFL_CLS=EX_CON[3];

assign INT_B = OVFL_STA & INT_EN; //high active

//////////////////////状态寄存器处理EX_STATE//////////////////////////////////

assign EX_STATE={31'B0,OVFL_STA};

always @ (posedge SYSCLK or negedge RST_B)

begin

  if(!RST_B)

    OVFL_STA <= `UD 1'B0;

  else

    OVFL_STA <= `UD OVFL_STA_N;

end

always @(*)         

begin

if(COUNT_OVERFLOW)

    OVFL_STA_N = `UD 1'B1;

else if(OVFL_CLS)

  OVFL_STA_N = `UD 1'B0;

else   

    OVFL_STA_N = OVFL_STA;

end

 4.6.3  显示功能设计实现

本模块设计中共包含1个Verilog文件display.v,完成将显示缓冲区的内容通过七段数码管显示的功能。七段数码管显示原理图如下:

 相关设计实现代码如下:

//////////计数器实现数码管扫描时间(Count system clock for Scan the led)////////////

`define SCAN_COEF 24'h1F090     //七段数码管扫描时间5ms

always @ (posedge SYSCLK or negedge RST_B)

begin

  if(!RST_B)

    LED_SCAN_CNT   <= `UD 24'h0;

  else

    LED_SCAN_CNT   <= `UD LED_SCAN_CNT_N;

end

 

always @ (*)

begin

  if(LED_SCAN_CNT == `SCAN_COEF)

    LED_SCAN_CNT_N  = 24'h0;

  else

    LED_SCAN_CNT_N  = LED_SCAN_CNT + 24'h1;

end

 

////////////扫描时间记数器,从0到7共记8次////////////////////////////////////////

always @ (posedge SYSCLK or negedge RST_B)

begin

  if(!RST_B)

    LED_SEL_NUM   <= `UD 3'h0;

  else

    LED_SEL_NUM   <= `UD LED_SEL_NUM_N;

end

 

always @ (*)

begin

  if(LED_SCAN_CNT == `SCAN_COEF)

    LED_SEL_NUM_N  = LED_SEL_NUM +3'h1;

  else

    LED_SEL_NUM_N  = LED_SEL_NUM;

End

////////////根据扫描时间记数器,依次选择1到8个LED数码管工作//////////////////////

wire DISP_SEL;

assign DISP_SEL=EX_CON[0];

always @ (*)

begin

 if(DISP_SEL)

  case(LED_SEL_NUM)

    3'b000     :      COM = 8'b00000001;

    3'b001     :      COM = 8'b00000010;

    3'b010     :      COM = 8'b00000100;

    3'b011     :      COM = 8'b00001000;

    3'b100     :      COM = 8'b00010000;

    3'b101     :      COM = 8'b00100000;

    3'b110     :      COM = 8'b01000000;

    3'b111     :      COM = 8'b10000000;

    default    :      COM= 8'b00000000;

  endcase

 else

      COM   = 8'b00000000;

  end

//////根据扫描时间记数器,依次将显示缓冲区的内容送到1到8个LED数码管显示///////////////

always @ (*)

begin

   case(LED_SEL_NUM)  

     3'b000   :      LED_DATA_HEX = EX_BUFFER[31:28]; 

     3'b001   :      LED_DATA_HEX = EX_BUFFER[27:24]; 

     3'b010   :      LED_DATA_HEX = EX_BUFFER[23:20];

     3'b011   :      LED_DATA_HEX = EX_BUFFER[19:16];

     3'b100   :      LED_DATA_HEX = EX_BUFFER[15:12];

     3'b101   :      LED_DATA_HEX = EX_BUFFER[11:8];

     3'b110   :      LED_DATA_HEX = EX_BUFFER[7:4];

     3'b111    :      LED_DATA_HEX = EX_BUFFER[3:0];    

     default   :      LED_DATA_HEX = 4'h0;

   endcase

end

//////显示缓冲区的内容16进制译码为0到9,a到f /////////////////////////////////////

always @ (*)

begin

  case(LED_DATA_HEX) 

     4'h0       :      SEG_HEX = 8'b01111110;

     4'h1       :      SEG_HEX = 8'b00000110;

     4'h2       :      SEG_HEX = 8'b11011010;

     4'h3       :      SEG_HEX = 8'b11001110;

     4'h4       :      SEG_HEX = 8'b10100110;

     4'h5       :      SEG_HEX = 8'b11101100;

     4'h6       :      SEG_HEX = 8'b11111100;

     4'h7       :      SEG_HEX = 8'b01000110;

     4'h8       :      SEG_HEX = 8'b11111110;

     4'h9       :      SEG_HEX = 8'b11101110;

     4'ha    :    SEG_HEX = 8'b11100110;

     4'hb    :    SEG_HEX = 8'b10111100;

     4'hc    :    SEG_HEX = 8'b10011000;

     4'hd    :    SEG_HEX = 8'b10011110;

     4'he    :    SEG_HEX = 8'b11111010;

     4'hf    :    SEG_HEX = 8'b11110000;    

     default   :    SEG_HEX = 8'b01111110;    

  endcase

end

  • No labels