konglp题目HCL系统内存外设实现和流水初步设计_第1页
konglp题目HCL系统内存外设实现和流水初步设计_第2页
konglp题目HCL系统内存外设实现和流水初步设计_第3页
konglp题目HCL系统内存外设实现和流水初步设计_第4页
konglp题目HCL系统内存外设实现和流水初步设计_第5页
已阅读5页,还剩93页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

中 第一章绪 第二章国内外背景与设计意 第三章内存外设在整个HCL系统中的位 第四章开发环境介 第五章内存及总线控制器的实 第六章串口控制器设计与实 第七章LCD的设计与实 第八章串行Flash的控制以及从Flash载入程 第九章流水线的支持模块设 第十章未来的工 第十一章结 附录A主要器件实现代 致 参考文 EmbeddedSystemDevelopment.Thedesignofpipelineandtheimplementationofsomeentitieswhichsupportthepipelinecannotonlyimprovetheperformanceofthesystem,butalsodrawaclearpictureoftheCPUinsidestructure.Inthispaper,wedescribethemethodsofdesigningandimplementationusingVHDLanddiscussaboutthedifficultiesandthesolutionsforthem.Finally,weverifyourdesignedmemoryandperipheraldevicesontheFPGAboardanddiscusswherecanbeimprovedinthefuture.:VHDL,Memory,PeripheralDevices,FPGA,第一章HCLCPUPCPC端。另一方面,这一部分的工作也是相对独立的,现今嵌入式开发已经越来成原理课程的教学带来的帮助。也使得我们可以更清楚的了解到CPU的结第二章内外背景与设计意第三章内存外设在整个HCL中的位3.1HCL如上图所示,内存外设的内容包括内存总线控制器(MEM-I/OBusInterface(Memory设备收发器(UART)串口数据通信设备(RS232-DCE)LCD控制器(LCDControllerLCD和程序加载器(OSLoader)和串行Flash(SPIFlash其中SPIFlash,Memory,RS232-DCE,LCD是物理设备(Memory实际上是FPGA中提供的调用FPGAVHDL第四章发环境介这次毕设的硬件部分,我们所选用的语言是VHDL(VHSICHardwareDescriptionLanguage)速集成电路硬件描述语言。它是现在在EDA领域包括可编程逻辑器件上编程最为常用的两种语言之一(另一种是Verilog),同时IEEEVHDL设中所使用到的一些重点的VHDL的语法和结构。关于VHDL语言,在这次毕设当VHDL语言最大的优势一个是来源于思,一个是来源于效率上。在思路上,VHDL语言为我们打破了软件硬件的界限,事实上,作为一种语言它为像我们这样的从来没有做过电路设计硬件制作的人提供了一个很好的从逻辑上对硬件进行描述的平台。VHDLEDAEDA使得电子系统现在向集成化、大规模和高速度等方向发展。在效率上,VHDL相比于传统的电原理图描述VHDL(1)VHDL(2)VHDL语言可读性强,易于修改和发现错误(这一点在我们多次的互相修改代码之中体现最多,读VHDL(3)ISE(4)VHDL设计不依赖于器件(除了在我们本次所使用的XilinxSpartan3estarterFPGAAlteraFPGA在设计一个实体时,我们需要用到的是实体。VHDL既支持自底向上的entity实体名[generic[port(端口表:方式类型;…);]end[entity]Port…的类型有两种,分别是in和out,用来区别这个接口数据的流向,in端口的数据对于实体来说只能作为用,而out端口的数据对于实体来说只能写出。个什么要的逻辑来执行或者它是一个什么样的实体,这就需要使用结构体(architecture)architectureofend结构体中的语句是对结构体的功能描述语句中将要用到的信(SIGNAL(TYPE(CONSTANT数据流(RTL)辑都是通过找们通过结构化的描述(componentportmap)VHDL通过类比C语言,并不特别的难于理解。所以在这一个小节中,简单介绍第二个部分介绍VHDL语言的特色process。4.1值言一样,变量的赋值是即时的,但是信号的赋值则不然(我们在QuartusII中的(process(void)中的process则不同,它只是在进程中的语句之间是顺序执行的,但是进程与进特点,可以说,VHDL┇END需要说明的是,进程是由上面所写的敏感信号触发的,即敏感信号表中的(MFCVHDL有许多思想可)第五章存及总线控制器的实虽然内存可以在FPGA中直接通过大寄存器的方式进行模拟,但是这种方式ISE中提供的FPGA中提供的内存来充当机器的内存并且使用MemoryInterfaceMemoryInterfaceVHDLentityMemory_InterfaceisMCLK:instd_logic;MemCtrlBus:instd_logic;MemAddrBus:instd_logic_vector(31downto0);MemDataBusIn:instd_logic_vector(31downto0);MemDataBusOut:outstd_logic_vector(31downto0);MemMode:instd_logic_vector(1downto0)其中,MCLKmemoryclockCPU为6.25MHz。MemCtrlBus为内存的写信号,emAddrBus为读地址或写地址,MemDataBusInCPUMemDataBusOut据MemMode是两位选择内存的模式取字还是字节还是双字等其中字的00。们采用的结构是内存组成的。内存的输出分别为MemDataOut0,componentMemory1port(clka:instd_logic;--内存工作时钟wea:instd_logic_vector(0downto0);addra:instd_logic_vector(12downto0);dina:instd_logic_vector(7downto0);douta:outstd_logic_vector(7downto0));endcomponent每一片内存的大小都是8bit*2K,其中,信号clka即内存的工作时钟,因在上升沿开始的,所以我们把MCLK进行取反之后再接到clka上。Wea为内存的写允许信号Addra为操作内存的地址,dina为希望写入内存的数据,doutaMemDataOut0 MemDataOut1,MemDataOut2,MemDataOut3分别发送到内存接收线的相应接收线。有两行8个单元,假设它们的是0,1,2,3;4,5,6,7。则当我们在lw$t0,2的时候,我们需要取的实际上是3,4,5,6四个单元,这是跨行的,所以在这个阶段我们需要计算两个值,第一个值是remainder为的地址(此处为2)和42,减去余数(此处为2)再和4取余,实际上得到了行地址。所以,在余数为2的 的数据,不过根据大端的原则,MemDataBusOut(31downto24)此时应该被赋予的就是MemDataOut2的值了,之后是MemDataOut3MemDataOut00还需要给出写的控制信号,这个信号在MemCtrlBus1,不过我们并不能简单的把这个信号抄送给内存,因为这在写一个word的时1,而另外两个不写的单元,必须将其信0,否则就会引起他们数据线上的数据错误的写入内存。所以我们在判断了MemCtrlBus上的信号为1确定是写操作后,根据MemMode和刚才提到remaindercasectrlMIPS系统中,IO的方式不是孤立的进行操作的。而是在内存的单元面如我们的设计当中串口的读写口分别在内存的80和81两个地址从CPU的角度上看对于这些特殊的内存单元进行写入和并没有和别的内存的单元进行写入和有什么特别大的区别。不过,在内存IO总线控制器(MEM-I/OBUSControllerCPU到相应的设备(如:内存,串口,LCD等。因为外设按照约定是在系统工作时沿之前的某一个时间又因为CPU对于内存的控制信号是在系统工作时钟的上升5.1SysCLK6.25MHzIO线控制器中一个时钟CLK,它的频率是系统时钟的两倍(12.5MHz,然后让我们就可以开始进行内存IOCPU存外设,让他们能够在SysCLK的下降沿接收到控制信号和数据信号。此控制器CPU下接口,接收CPU输入的地址总线的信号SysAddrBus,写入数据线的信号SysDataBusIn,控制信号SysCtrlBus当然还有需要发给CPU数据使用的接口信号时,先对SysAddrBus上的值是否是80,81,82,83,如果是,则转入相应的80先将内存写控制信号MemCtrlBus和LCD写控制信号LCDWrite全部置为0,保证之后对串口的操作不会对他们产生影响然后判断SysCtrlBus上的值是10还是01,即是否是写数据操作,如果是10,表示是读操作,则将串口的控制信号1Mux_Selector10,SysDataBusOut8bitMux_Selector是内存IO总线控制器的一个信号它在逻辑上做了一个多路选择器的作用00时表示没有读入SysDataBusOut置为全0,01表示从内存读入数据,10表示从串口进数据,11表示从LCD进数据,当然这个第六章口控制器设计与实本机外设采用内存的方案(MappedI/O)完成。主要部件有:串行接(LCD我们在FPGA上实现了一个通用串行收发器(UART)来实现对RS-232接口的接收端工作时钟仍然由开发板系统时钟分频得到(工作时钟为9600*16Hz。接收时,8发送端9600*16Hz,发送时,先将发送线置为低电平,用于发送起始位,81(包括开始和停止位)16串口特殊寄存(UARTPC,Receiver是串行收发器的接收端(PC。A8251ControlCPU6.1从外部看如图所示RS-232串行接口中一共有三根线发送(RS232_TxD6.2CLK_GeneratorVHDLentityCLK_GeneratorisCLK:instd_logic;TX_RX_CLK:outstd_logicendentity其中,输入CLK为从开发板上连接过来的源时钟信号,而TX_RX_CLK为串口当中读写所需要的读写工作时钟,因为我们设定波特率为9600,所以此时钟的频率应该是9600*16Hz(16个读写工作时钟我们完成一位数据的读写。用50MHz/(9600*16Hz)我们得到,我们时钟的一个周期应该相当于326个CLK的周期。所以我们163个周期将其置为高电平,在后面的一半周期将它置为低电TX_RX_CLKVHDLentityReceiverisRst:Rx_CLK:instd_logic;RS232_RxD:instd_logic;Rx_Ready:outstd_logic;RxData_Ready:outstd_logic;Dout:outstd_logic_vector(7downtoendentity(Reset,Rx_CLK读写工作时钟,RS232_RxD即是RS232的接收线。Rx_Ready信号代表是否完整的完成了一个接收流程(即从开始位开始,到停止位结束,RxData_Ready则表示8位的数据信号的接收已经完成。Dout用来将接收到数据向A8251Control中的的有限状态机共有四个状态,空闲状态(Idle)(Rx_StopBitVHDL的代码实现了上述自,对于存放目前机器现态的Rx_State进行case语句分析,如果在空闲状态,则判断接收线RS232_RxD是否是低电平(这根线在Rx_State置为Rx_StartBit开始接收开始位。开始位的接收一共持续16个Rx_CLK的周期。我们在第八个时钟上升沿(counter_16=7)时采样其值(之Rx_Data状态,开始接收8位数据。仍然在第八个时钟上升沿对于RS232_RxD的值进行采样(如图所示,图中第一个信号的频率为9600Hz,是理论上属于一个数据位的周期(实际并不需要这根线,第二行是串口的工作时钟,频率为6.3在接收端,我们一个bit_count的变量,用来计算目前接收的是哪一位,并将其放入Rx_Shift_Reg的相应位置(Rx_Shift_Reg(bit_count)<=RS232_RxD。Rx_Shift_Reg是中Dout的八位输出相连。在接收第八位数据完成的时候(即属于第八位数据的第八个上升沿counter_168Rx_Shift_Reg(DoutA8251ContrlRx_Buffer_Reg所以这个在这个时钟的上升沿,我们把RxData_Ready信号置为1A8251Control16(可以再接收数据Rx_Ready1A8251ControlA8251Control,A8251Control那边已经有充足的时间完成了DataRxData_Ready0。entityTransmitterisCLK:instd_logic;Tx_CLK:instd_logic;En:instd_logic;Rst:inDin:instd_logic_vector(7downto0);Tx_Ready:outstd_logic;RS232_TxD:outendentityCLKCPUCPUDin信号进行接下来的发送,n这个信号同样是来自于CPU中的发送数据寄存器Tx_Shift_Reg的写信号(我们把串口CPUEnCPU。Tx_CLKTx_Ready按照串口的规定,串口的数据发送应该在Tx_CLK的下降沿进行(即Tx_CLK'EVENTandTx_CLK='0'。事实上,与接收端相同,发送端也了一个四状态自。且四个状态相应的是空闲状态(Idle),发送开始位状(Tx_StopBit发送每一个数位持续16个Tx_CLK在发送数据的过程中一个shift_count的计数,对于串口发送线进行8个数据位的顺序写入(RS232_TxD<=Tx_Shift_Reg(shift_count);)且在最后8个数据发送完之后将发送器切换到发CPU比串口的工作时钟快得多,所以,CPUEnTx_CLK接收到CPU发出的信号En='1'之后一个的信号Start置为'1'样在串口工作时钟的下降沿我们只要判断Start='1'便让自进入发送1(Start='1'andTx_State/=Idle,Start信CLKProcess0。Tx_ReadyCPU快的,直接决定了CPU是否可以向串口发送数据。所以其值的至关重要,如Tx_ReadyEn,StartTx_StateEn='1'或Start='1'CPU0Tx_StateIdleTx_Ready0,不允许Tx_StateIdleEnStart0CPUTx_Ready1表示可以接收新的输入。这样便完成了对于串口发送端状态的。串口控制器主要负责和CPU打交道,当然同时它也负责串口的一些必要的逻辑。在串口控制器当中,我们了两个寄存器,一个寄存器是来存放串口目前的状态,Status寄存器一共有八位,具体每一位的含义可以参考[8],最为常用也是重要的,是它的第0Txrdy,用来表示是否处于发送状(101Rxrdy,用来表示是否接收到一个有效的数据(0表示没有,CPU不可进行,1表示有CPU可以进行。TxrdyTx_Ready进行的。不过Rxrdy这一位却不是用Rx_Ready的,其原因还是在于CPU始终和串口工作时钟的频率相差甚远,如图所示,CPU数据的,则CPU必定会重复Rx_Buffer_Reg中的值如下图中的CLK和CPU读一个数据(实际上这之中也只有这一个有效数据,因此我们有了控制器的Rx_Buffer_Valid这个信号,和与之为它服务的一个锁信号RxRdy_Lock6.4Rx_Buffer_ValidRx_Buffer_ValidCPURxrdy_LockRx_Ready1Rx_Buffer_Valid1,表示可以读数据,并且将锁变Rx_Buffer_Lock1,CPURx_Buffer_Valid1Rx_Ready电平时(证明串口新的一次数据又开始了将Rxrdy_Lock置回1,等待数Rx_Buffer_ValidCLK,Rx_Buffer_Valid1,。CPU值的逻辑相对比较简单,在RD='1'时,证明CPU要读串口数据并且由CND控制是取状态寄存器Status_Reg还是数据寄存器Rx_Buffer_Reg。如果是取状态寄存器,则直接把Status_Reg给到Dout线上即可。若是数据寄存器(这个逻辑上是正确的,因为已经通过之前的轮询发现可以读,则将Rx_Buffer_Reg的值放上DoutRx_Buffer_Valid置为0,表示已经完成了这次数据的。Rx_Buffer_RegRx_Shift_Reg8RxData_Ready1,Rx_Buffer_RegRx_Ready1,Rx_Buffer_RegCPU进行,保证了这一过程的正确和安全。第七章LCD设计与实LCD,TheSpartan®-3EFPGAStarter的LCD屏幕来实现。LCD的控制,主要通过我们编写的LCD控制器(LCDController)来完成。作为一个显示设备,LCDLCD数据(虽然LCD可以支持从它的器数据。LCD设计的主要问题在于如何通过一个控制器,采用LCD所规定的接收数据的方法,向LCD屏幕进LCD7.1LCD其中LCD_RS信号主要用来区分这一次是一次数据传输操作还是一个命令的操作,SF_D是四位数据的信号,LCD_RW为LCD的读写信号,低电平时使得LCD接收数据的输入,而高电平时让LCD处于读状态,显示数据。而LCD_E为读写操Interface四个接口LCD8bit发送八位令。下面我们先介绍第一个问题。CLOCK,LCD_RS,SF_D[11:8],LCD_RW,LCD_E40nsLCD230nsLCDLCD_ELCD_RSCLD_RW10ns7.2LCDVHDLLCD_RS,SF_D置为需要的值,并同时把LCD_RW置为低电平,如此持续LCD_E1230ns(12周期,然后进入第三个状态,在这个状态中,我们把LCD_E置低10ns(1个周期最后第四个状态中,LCD_RW重新置为高电平。如此一来,一次4位4。7.3LCD在VHDL中我们需要一个更大的自这个自把四位数据的发送看成是一个状态SS,之后1usS(SS状态发送第四位。这样其实一个8位令就发送40us40us,8在介绍LCD如何进行数据显示之前,我们需要了解一下刚才我们使用8位命令传送方式传送给LCD的有哪些命令。我们罗列出常用的几条指令,具体的可7.1LCD0000000001SetDD001 toCGRAMDD101.64ms(82,000SetDDRAMAddressWriteDatatoCGRAMorDDRAM因为他们的最A7都是0,所以可以不写,在命令中指明A6-A0即可。另外,0x10-0x270x50-0x67,他们写入之后,如果设置7.4WriteDatatoCGRAMorDDRAM进行写入。其中的LCD_RS='1'清楚的表示了这一个操作不是一个命令,而是一RAMAddress)之外,还要写入字符对应的Data的编码D7-D0。这个LCD屏可以ASCIID7-D0ASCII7.5LCDLCD7.6LCDSF_D<11:8>0x3,LCD_E12(一4bit)4.1ms(205000SF_D<11:8>0x3,LCD_E12(一4bit)100us(50004bit)等待40us(20004bit)40us(2000这个初始化的流程将通过VHDL的九步状态完成,当然,其中的7.7LCDFunctionSet0x28诉LCD它自己的行数等硬件信息。接下来发出一条EntryMode指令,这条0x06地址自动递增还是递减DisplayOn/Off指令,这条0x0C指令,会告知是否闪动光标。我们选择不闪动。最后发出ClearDisplay指令清屏。当然清屏指令需要执行1.64ms,这之中必须等待。这样便完成了设置接下来就可以指定写入的位置后开始不断的写入数据让LCD现实了。当然,除了ClearDisplay要等够足够时间以外,别的指令之间也是需要8第八章串行Flash的控制以及从Flash载入程串行Flash我们使用的是开发板上所带的一块STMicroElectrionicM25P16。它主要完成的任务是我们设计的程序并将其加载到内存之中。这样内存就不需要在硬件的编译阶段进入内存之中了了调试如下图所示,M25P16Flash器的主要接口有D,C,^S,Q四个。其^W,^HOLD信号已经被开发板管理,没有连接到FPGA上,所以不是我们关心的对象。我们关心的四个接口,其中D是接收数据的接口,Q是数据的出口,C是一个控制Flash的同步时钟,^S是低电平有效的片选信号,用来选中对Flash储8.1Flash与LCD有相似的是,串行Flash也有其自身令和数据的写入逻辑。不同于LCD所使用4位数据接口,Flash使用的是串行的,换而言之,它的数据时一位一位进行收发的,对于Flash的控制指令也是一样。我们采用两个时钟来指导向Flahs发出数据和指令。连接到开发板本身提供的50MHz时钟之后,我们把这个时钟分成两个时钟,频率除以2一个(TX_CLK),频率除以4一个(SCK/InterCLK在每两个周期的TX_CLK信号的上升沿将信号发出,则Flash在SCK信号的下降8.2FlashLCDFlashFlash,Flashspartan3estarter开发板上,SPI总线是由许多SPI外设所共享的,所以使用串行Flash之前,需要把别的SPI的设备全部关闭。按[6]的说明,将信号DAC_CS'1',AMP_CS'1',AD_CONV'0',SF_CE0为'1',FPGA_INIT_B信号置为'0'。Flash(Flash'1'Flash进行写入之前,只需要对进行写入的部分清空即可,但是考虑到我们的flash最后的目的是用来加载程序只放置程序这一个程序所以我们在写入之前对其全部擦除,比较方便。在VHDL之中,我们了一个Programmer_FSM的大状态机,用来大的步骤。其中的连续状态SPI_WREN1,SPI_RDSR1,SPI_WRSR,SPI_RDSR2,SPI_WREN2,SPI_RDSR3,SPI_BE。这个里面的状态时SPI_WRSR和SPI_BE。前的操作SPI_WREN1和FlashSPI_RDSR1statusWIPSPI_WREN1指令是否执行完当执行完了之后第一个状态开始SPI_WRSR状态中我们对Status寄存器进行写入主要是将其的最SRWD置为1Flash10,blck0以做全局的写入。第二个的状态SPI_BE即是大规模擦除,在这一步我们把FlashSPI_RDSR4EraseReady信号从0置为1,通知Receive从串口接收数据并写入Flash我们的要的数据,是从串口传输进来的。而串口的速度比Flash写512*8bit8.3在Flash控制器中,我们两个用作指针的信号。Recv_ptr表示FlashSPI_ptr0EraseReadyReceive之后,串口开始接收数据(接收的方法与串口部分描述相同8bitRecv_ptr1mod512(注:因为对缓定,最后一位信号采用了当时串口接收线上的信号进行直接的写入。)此时Programmer_FSMWaitForWRabs(Recv_ptrSPI_ptr)=256即串口指针了256个8bit。然后我们通过状态SPI_PP缓冲FlashSPIAddress256SPIAddress256Programmer_FSMWaitForWRFlash刚才的章节我们介绍了Flash的微观上的1位数据接口和宏观上的接收逻辑这一节介绍Flash的相关操作指(比如之前我们所说的写入Flash的操作,需要通过PageProgram指令来完成,而对于状态寄存器的写入,需要通过WRSR指令来完成。Flash的指令如下表所示,我们下面来介绍用来完成指令发送逻辑的自MAND因为flash是从D口接收这些指令控制的。 MAND主要的是控制的对于D口的发送逻辑。可以发现,指令并不是需要同样多的过程来完成的(这个情况和CPU中的指令很相似。所以在状态机在经过OPCODEMANDIdleFlash8.4FlashMANDProgrammer_FSM大的状态需要运行某条指令时,Programmer_FSM状态机先将该指令的操作码写入到操作码的缓存之中,然后会置StartSPI信号为高(StartSPI<='1';Opcode_BUFWREN_Opcode;StartSPIMAND机在Idle状态下判别的启动信号,它会启动执行相应的逻辑。在此过程中Programmer_FSM状态机只需要维持StartSPI信号为0,使之不会重复启动,然后等待。在接收状态寄存器这一个状态中(RECV,在把^S信号置低后,进入一ToIdleMAND^S拉回。Flash向内存的逻在将程序的代码从PC端发送到Flash之后,我们还需要从Flash把这部分数据到内存当中去。这个工作是通过OSLoader来完成的。OSLoader在Flash这个方面的操作,几乎是上面所提及的Flash控制器的一个子集。它在此的opcode确定为"00000011",对照上表可知,就是一条读指令(ReadDataBytes我们把上面的MAND自也简化为在这一步所使用的几个状(IdleOPCODEADDR,RECV。在使用ReadDataBytes指令后,记录数字,每次为256个8bit(ReadDataBytes指令执行后,Flash的输出端即会不断的在上面图中的InterCLK时钟的上升沿向外发出连续的1bit的数据我们只要在此时钟的上升沿从Flash的输出口SPI_MISO接收到辅助的8位暂存器Aux_Byte8bit存器中的信号写入到FIFO中这个写入逻辑相对于一位flash信号的接收是相当,是一个长度为256的每个元素为8bit的数组通过信号tail作为其尾指针,我们可以很轻松的控制向其写入,当写入的数量达到256时,此次的即算完成,将Flash的地址加256,我们通过置ToIdle(和上文一样)的值完成这次过程通过置DataValid信号的值来通知整体状态机OSLoader_st将内MEM_WR T信号,置初值为9216,用它来维持整个的的一个LED上,这样外界就可以看到是否完成。在写入内存的过程中,OSLoaderCPU达到T11,主要是用来完成=( T1)MemSrcOSLoaderIO第九章水线的支持模块设9.1如上图所示,MIPSCPU的五步操作分解为独立的环节。这样,CPU的状态机需要做一些调整。原来的State[1]状态将需要将原先的所有指令的状态扩展到五步(R个状态,加存这一步,但是在这一步不执行任何实际操作,然后将被根据EX/MEM寄存器,MEM/WB寄存器的状态值进行控制信号的提供(此部分的工当然,要实现一个真正能够使用的MIPS流水线,还需要考虑更为重要的一(forward,(hazard,分为两种,结构和数据。当然在MIPS当中,结构是并不一个限制。再有就是数据。数据分为两种情况。add$s0,$t0,$t1sub$t2,$s0,$t3这种情况,在顺序执行的时候并没有问题,因为第一条指令已经在第五步将$s0$s0$s0ALU$s0法指令得到的值是错误的。这个情况,我们通过转发单元进行处理。forwardVHDLENTITYforwardPORT(exmRegWrite,memwbRegWrite:inexmWriteReg,memwbWriteReg:instd_logic_vector(4downto0);idexReadOne,idexReadTwo:instd_logic_vector(4downto0);aluSelA,aluSelB:outstd_logic_vector(1downto0));ENDENTITY其中,exmRegWrite为EX/MEM寄存器的写信号,memwbRegWrite为MEM/WB寄存器的写入信号。exmWriteRegEX/MEM的寄存器的,memwbWriteReg为MEM/WB阶段要写入的寄存器的值。idexReadOne和idexReadTwo为ID/EX寄存器中存放的要的两个寄存器的编号。aluSelAaluSelB两个输出信号,表示ALU的A口B口对于数据的选择,,10ALU01表示操作数来自MEM/WB图 exmRegWrite1,EX/MEMmemwbRegWrite1MEM/WB是否被写,如果这两个同时都被写入,则先验证idexReadOne,idexReadTwoEX/MEM10,通过MEM/WB01,进00。第二种情况的数据,就不能通过转发来完成了。比下面的例子lw$t0,20($gp)addi$t0,t0,1$t0我们取用$t01Access)的时候才能得到$t0$t0ALU(结果是错误的逻辑。(hazardENTITYhazardPORT(idexmemread:inidexregrt,ifidregrs,ifidregrt:instd_logic_vectordowntopcenable,ifidenable,idexflush:outENDENTITY9.3hazardRTL其中,idexmemread是在idex阶段我们发现这条指令时是否要内存,如果它需要内存则我们判断它的Rt是否与前面的IF/ID阶段指令的Rs或者Rt相同,如果相同,我们通过把pcenable信号pc寄存器写入,从而不再有新指令进入流水线,同时又用ifidenable信号将IF/ID写入,从而维持这一段的现状。然后使用idexflush信号掉ID/EX的值,使得刚才来的新第十章来的工第一,内存的80,81,82地址,原则上应该被用来到外设,但实际79开始读一个word的话,那么这个将会被分派到内存的当中,而真正的内存的80,81,82单元的值,与所期望的不相符合,所以应该将MemMode这一LCD如果现在LCD使用简单的系统调用进行控制,它还非常不稳定,需要进行校验位和异常我们还没有处理。另外和LCD一样,串口也需要上升到汇编语言对第十一章行连接后,我们对整个工程进行了综合、实现时序仿真并最终到了XilinxSpartan3EStarter中。经过小组同学大量的测试后,我们发现对现在已经实附录A器件实现代entityMemory_InterfaceisMCLK:instd_logic;MemCtrlBus:instd_logic;MemAddrBus:instd_logic_vector(31downto0);MemDataBusIn:instd_logic_vector(31downto0);MemDataBusOut:outstd_logic_vector(31downto0);MemMode:instd_logic_vector(1downto0)endentityarchitectureBehavioralofMemory_InterfaceissignalNMCLK:std_logic;signalMemCtrl0:std_logic_vector(0downto0);signalMemCtrl1:std_logic_vector(0downto0);signalMemCtrl2:std_logic_vector(0downto0);signalMemCtrl3:std_logic_vector(0downto0);signalMemAddr0:std_logic_vector(12downto0);signalMemAddr1:std_logic_vector(12downto0);signalMemAddr2:std_logic_vector(12downto0);signalMemAddr3:std_logic_vector(12downto0);signalMemDataIn0:std_logic_vector(7downto0);signalMemDataIn1:std_logic_vector(7downto0);signalMemDataIn2:std_logic_vector(7downto0);signalMemDataIn3:std_logic_vector(7downto0);signalMemDataOut0:std_logic_vector(7downto0);signalMemDataOut1:std_logic_vector(7downto0);signalMemDataOut2:std_logic_vector(7downtosignalMemDataOut3:std_logic_vector(7downtocomponentMemory0port(clka:inwea:instd_logic_vector(0downto0);addra:instd_logic_vector(12downto0);dina:instd_logic_vector(7downto0);douta:outstd_logic_vector(7downto0));endcomponentcomponentMemory1port(clka:inwea:instd_logic_vector(0downto0);addra:instd_logic_vector(12downto0);dina:instd_logic_vector(7downto0);douta:outstd_logic_vector(7downto0));endcomponentcomponentMemory2port(clka:inwea:instd_logic_vector(0downto0);addra:instd_logic_vector(12downto0);dina:instd_logic_vector(7downto0);douta:outstd_logic_vector(7downto0));endcomponentcomponentMemory3port(clka:inwea:instd_logic_vector(0downto0);addra:instd_logic_vector(12downto0);dina:instd_logic_vector(7downto0);douta:outstd_logic_vector(7downto0));endcomponentMemory3;NMCLK<=notvariableremainder:integerrange0to3;variablebase:integerrange0to8188;remainder:=CONV_INTEGER(MemAddrBus)modbase:=(CONV_INTEGER(MemAddrBus)-remainder)/4;caseremainderiswhen0ifMemMode="00"MemDataBusOut(31downto24)<=MemDataOut0;MemDataBusOut(23downto16)<=MemDataOut1;MemDataBusOut(15downto8)<=MemDataOut2;MemDataBusOut(7downto0)<=MemDataOut3;elsifMemMode="01"MemDataBusOut(31downto24)<=(others=>'0');MemDataBusOut(23downto16)<=(others=>'0');MemDataBusOut(15downto8)<=MemDataOut0;MemDataBusOut(7downto0)<=MemDataOut1;elsifMemMode="10"MemDataBusOut(31downto24)<=(others=>'0');MemDataBusOut(23downto16)<=(others=>'0');MemDataBusOut(15downto8)<=(others=>'0');MemDataBusOut(7downto0)<=MemDataOut0;endif;when1=>ifMemMode="00"MemDataBusOut(31downto24)<=MemDataOut1;MemDataBusOut(23downto16)<=MemDataOut2;MemDataBusOut(15downto8)<=MemDataOut3;MemDataBusOut(7downto0)<=MemDataOut0;elsifMemMode="01"MemDataBusOut(31downto24)<=(others=>'0');MemDataBusOut(23downto16)<=(others=>'0');MemDataBusOut(15downto8)<=MemDataOut1;MemDataBusOut(7downto0)<=MemDataOut2;elsifMemMode="10"MemDataBusOut(31downto24)<=(others=>'0');MemDataBusOut(23downto16)<=(others=>'0');MemDataBusOut(15downto8)<=(others=>'0');MemDataBusOut(7downto0)<=MemDataOut1;endif;when2=>ifMemMode="00"MemDataBusOut(31downto24)<=MemDataOut2;MemDataBusOut(23downto16)<=MemDataOut3;MemDataBusOut(15downto8)<=MemDataOut0;MemDataBusOut(7downto0)<=MemDataOut1;elsifMemMode="01"MemDataBusOut(31downto24)<=(others=>'0');MemDataBusOut(23downto16)<=(others=>'0');MemDataBusOut(15downto8)<=MemDataOut2;MemDataBusOut(7downto0)<=MemDataOut3;elsifMemMode="10"MemDataBusOut(31downto24)<=(others=>'0');MemDataBusOut(23downto16)<=(others=>'0');MemDataBusOut(15downto8)<=(others=>'0');MemDataBusOut(7downto0)<=MemDataOut2;endif;when3=>ifMemMode="00"MemDataBusOut(31downto24)<=MemDataOut3;MemDataBusOut(23downto16)<=MemDataOut0;MemDataBusOut(15downto8)<=MemDataOut1;MemDataBusOut(7downto0)<=MemDataOut2;elsifMemMode="01"MemDataBusOut(31downto24)<=(others=>'0');MemDataBusOut(23downto16)<=(others=>'0');MemDataBusOut(15downto8)<=MemDataOut3;MemDataBusOut(7downto0)<=MemDataOut0;elsifMemMode="10"MemDataBusOut(31downto24)<=(others=>'0');MemDataBusOut(23downto16)<=(others=>'0');MemDataBusOut(15downto8)<=(others=>'0');MemDataBusOut(7downto0)<=MemDataOut3;endwhenothers=>null;endcase;endprocessvariableremainder:integerrange0to3;variablebase:integerrange0to8188;remainder:=CONV_INTEGER(MemAddrBus)modbase:=(CONV_INTEGER(MemAddrBus)-remainder)/4;caseremainderiswhen0MemAddr0<=CONV_STD_LOGIC_VECTOR((base),13);MemAddr1<=CONV_STD_LOGIC_VECTOR((base),13);MemAddr2<=CONV_STD_LOGIC_VECTOR((base),13);MemAddr3<=when1MemAddr0<=CONV_STD_LOGIC_VECTOR((base+MemAddr1<=CONV_STD_LOGIC_VECTOR((base),13);MemAddr2<=CONV_STD_LOGIC_VECTOR((base),13);MemAddr3<=when2MemAddr0<=CONV_STD_LOGIC_VECTOR((base+1),13);MemAddr1<=CONV_STD_LOGIC_VECTOR((base+1),13);MemAddr2<=CONV_STD_LOGIC_VECTOR((base),13);MemAddr3<=CONV_STD_LOGIC_VECTOR((base),13);when3MemAddr0<=CONV_STD_LOGIC_VECTOR((base+1),13);MemAddr1<=CONV_STD_LOGIC_VECTOR((base+1),13);MemAddr2<=CONV_STD_LOGIC_VECTOR((base+1),13);MemAddr3<=CONV_STD_LOGIC_VECTOR((base),13);whenothers=>null;endcase;--MemoryReadoperationifMemCtrlBus='0'MemCtrl0(0)<=MemCtrl1(0)<=MemCtrl2(0)<=MemCtrl3(0)<=MemDataIn0<=(others=>'0');MemDataIn1<=(others=>'0');MemDataIn2<=(others=>'0');MemDataIn3<=(others=>--MemoryWriteoperationelsifMemCtrlBus='1'--WordifMemMode="00"thenMemCtrl0(0)<=MemCtrl1(0)<=MemCtrl2(0)<=MemCtrl3(0)<=caseremainderwhen0MemDataIn0<=MemDataBusIn(31downto24);MemDataIn1<=MemDataBusIn(23downto16);MemDataIn2<=MemDataBusIn(15downto8);MemDataIn3<=MemDataBusIn(7downto0);when1MemDataIn1<=MemDataBusIn(31downto24);MemDataIn2<=MemDataBusIn(23downto16);MemDataIn3<=MemDataBusIn(15downto8);MemDataIn0<=MemDataBusIn(7downto0);when2MemDataIn2<=MemDataBusIn(31downto24);MemDataIn3<=MemDataBusIn(23downto16);MemDataIn0<=MemDataBusIn(15downto8);MemDataIn1<=MemDataBusIn(7downto0);when3MemDataIn3<=MemDataBusIn(31downto24);MemDataIn0<=MemDataBusIn(23downto16);MemDataIn1<=MemDataBusIn(15downto8);MemDataIn2<=MemDataBusIn(7downto0);whenothers=>null;endcase;--HalfWordoperationelsifMemMode="01"thencaseremainderiswhen0=>MemDataIn0<=MemDataBusIn(15downto8);MemDataIn1<=MemDataBusIn(7downto0);MemDataIn2<=(others=>'0');MemDataIn3<=(others=>'0');when1MemDataIn1<=MemDataBusIn(15downto8);MemDataIn2<=MemDataBusIn(7downto0);MemDataIn3<=(others=>'0');MemDataIn0<=(others=>'0');when2=>MemDataIn2<=MemDataBusIn(15downto8);MemDataIn3<=MemDataBusIn(7downto0);MemDataIn0<=(others=>'0');MemDataIn1<=(others=>'0');when3MemDataIn3<=MemDataBusIn(15downto8);MemDataIn0<=MemDataBusIn(7downto0);MemDataIn1<=(others=>'0');MemDataIn2<=(others=>'0');whenothers=>null;endcase;caseremainderiswhen0=>MemCtrl0(0)<=MemCtrl1(0)<=MemCtrl2(0)<=MemCtrl3(0)<=when1MemCtrl0(0)<=MemCtrl1(0)<=MemCtrl2(0)<=MemCtrl3(0)<=when2MemCtrl0(0)<=MemCtrl1(0)<=MemCtrl2(0)<=MemCtrl3(0)<=when3MemCtrl0(0)<=MemCtrl1(0)<=MemCtrl2(0)<=MemCtrl3(0)<=whenothers=>null;endcase;--ByteelsifMemMode="10"thencaseremainderiswhen0MemDataIn0<=MemDataBusIn(7downto0);MemDataIn1<=(others=>'0');MemDataIn2<=(others=>'0');MemDataIn3<=(others=>'0');when1MemDataIn1<=MemDataBusIn(7downto0);MemDataIn2<=(others=>'0');MemDataIn3<=(others=>'0');MemDataIn0<=(others=>'0');when2MemDataIn2<=MemDataBusIn(7downto0);MemDataIn3<=(others=>'0');MemDataIn0<=(others=>'0');MemDataIn1<=(others=>'0');when3MemDataIn3<=MemDataBusIn(7downto0);MemDataIn0<=(others=>'0');MemDataIn1<=(others=>'0');MemDataIn2<=(others=>'0');whenothers=>null;endcase;caseremainderiswhen0=>MemCtrl0(0)<=MemCtrl1(0)<=MemCtrl2(0)<=MemCtrl3(0)<=when1MemCtrl0(0)<=MemCtrl1(0)<=MemCtrl2(0)<=MemCtrl3(0)<=when2MemCtrl0(0)<=MemCtrl1(0)<=MemCtrl2(0)<=MemCtrl3(0)<=when3MemCtrl0(0)<=MemCtrl1(0)<=MemCtrl2(0)<=MemCtrl3(0)<=whenothers=>null;endcase;endif;endif;endprocessMEM0:Memory0portmapclka=>NMCLK,wea=>MemCtrl0,addra=>MemAddr0,dina=>MemDataIn0,douta=>MEM1:Memory1portmapclka=>NMCLK,wea=>MemCtrl1,addra=>dina=>MemDataIn1,douta=>MEM2:Memory2portmapclka=>NMCLK,wea=>MemCtrl2,addra=>MemAddr2,dina=>MemDataIn2,douta=>MEM3:Memory3portmapclka=>NMCLK,wea=>MemCtrl3,addra=>MemAddr3,dina=>MemDataIn3,douta=>endarchitectureentityCLK_GeneratorisCLK:inTX_RX_CLK:outstd_logic--BaudrateendentityarchitecturebehavofCLK_Generatorsignalcounter:integerrange0to325:=ifCLK'EVENTandCLK='1'thenifcounter=162thenTX_RX_CLK<=counter<=counter+1;elsifcounter=325thenTX_RX_CLK<=counter<=0;counter<=counter+1;endif;endif;endprocess;endarchitectureentityReceiverisRst:Rx_CLK:instd_logic;--Rx_CLKis16timesBaudrateRS232_RxD:instd_logic;Rx_Readyoutstd_logic;面的ready一个停止位)RxData_Ready:outstd_logic;--完整的接收到了一个数据Doutoutstd_logic_vector(7downto0)ControlendentityarchitecturebehavofReceiver--StatesofthetypeRx_FSMis(Idle,Rx_StartBit,Rx_Data,Rx_StopBit);signalRx_State:Rx_FSM:=signalRx_Shift_Regstd_logic_vector(7downto0);--零时存放接收数Dout<=variablebit_count:integerrange0to7:=0;variablecounter_16:integerrange0to15:=0;--ResetoperationifRst='1'thencounter_16:=bit_count:=Rx_Ready<=RxData_Ready<='0';Rx_State<=Idle;elsifRx_CLK'EVENTandRx_CLK='1'thencaseRx_StateiswhenIdleifRS232_RxD='0' --Start

Rx_State<=Rx_StartBit;endif;counter_16:=bit_count:=Rx_Ready<=RxData_Ready<='0';whenRx_StartBit=>ifcounter_167then直接进去接收状态(0Rx_State<=endcounter_16:=counter_16+1;whenRx_Data=>--Sampleonthe8thrisingCLKifcounter_16=7thenRx_Shift_Reg(bit_count)<=RS232_RxD;bit_count:=bit_count+1;ifbit_count=0then8Rx_StateRx_StopBit;endif;endcounter_16:=counter_16+1;whenRx_StopBit=>ifcounter_168thenRxData_Ready'1';readycounter_16:=counter_16+1;elsifcounter_167then--停止位第七个了Rx_State<=Idle;--回空闲counter_16:=Rx_Ready'1';1(这位是状态寄存器中的一位先传完数据再置状态位)RxData_Ready<='0';counter_16:=counter_16+endwhenothers=>null;endcase;endendprocessRECEIVE;endarchitecturebehav;entityA8251ControlisCLK:instd_logic; --6.25MHzclockCND:instd_logic;WR:instd_logic;RD:instd_logic;Rst:inTx_Readyinstd_logic;(为轮询设计(与状态寄存Rx_Readyinstd_logic;(为轮询设计(与状态寄存RxData_Ready:inRx_Data:instd_logic_vector(7downto0);Tx_Data:outstd_logic_vector(7downto0);Request_Tx:outstd_logic;Din:instd_logic_vector(7downto0);Dout:outstd_logic_vector(7downtoendentityarchitecturebehavofA8251ControlsignalStatus_Reg:std_logic_vector(7downtosignalRx_Buffer_Regstd_logic_vector(7downto0);buffersignalRxrdy_Lock:std_logic:='0';signalRx_Buffer_Valid:std_logic:='0';aliasTxrdyisStatus_Reg(0);10aliasRxrdyisStatus_Reg(1);--接收到一个有效的数据01aliasTxemptyisStatus_Reg(2);aliasParityErrorisaliasOverrunErrorisStatus_Reg(4);aliasFramingErrorisStatus_Reg(5);aliasSynBrkisStatus_Reg(6);aliasDataSetrdyisStatus_Reg(7);STATUS_SET:process(Rst,Tx_Ready,Rx_Buffer_Valid)--InitializationifRst='1'thenTxrdy<='1';Rxrdy<=Txempty<=ParityError<=OverrunError<=FramingError<=SynBrk<=DataSetrdy<='1';--SetTxreadyifTx_Ready'1'then(与状态寄存器同步)Txrdy<='1';Txempty<=elsifTx_Ready'0'then--(与状态寄存器同步)Txrdy<='0';Txempty<='0';endif;--SetRxreadyifRx_Buffer_Valid='0'thenRxrdy<='0';elsifRx_Buffer_Valid='1'thenRxrdy<='1';endif;endif;endprocessRequest_Tx<=WR;endprocessTx_Data<=ifRst='1'Rx_Buffer_Reg<=(others=>'0');elsifCLK'EVENTandCLK='1'thenifRxData_Ready'1'thenReceiverdatareadyReceiverRx_ReadyRx_Buffer_Reg<=Rx_Data;endif;endendprocess ifCLK'EVENTandCLK='0'ifRxrdy_Lock'0'andRx_Ready'1'thenRxrdy_LockRx_VaildRx_CLK也就是一次读数据寄存器的过程中只能被程序端取走Rx_Buffer_Valid<=RxRdy_Lock<=elsifRx_Ready='0'then--一次成功完成之后把锁打RxRdy_Lock<='0';endif;ifRD='1'ifCND='1'Dout<=elsifCND='0'Dout<=Rx_Buffer_Reg;Rx_Buffer_Valid<=endelsifRD='0'Dout<=(others=>'0');endif;endendprocessRD_REG;endarchitectureentityIn8251AisSYSCLK:instd_logic; --6.25MHz系统工作时钟CLK:instd_logic; --50MHz源输入时钟CND:instd_logic; --

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论