diff --git a/cMIPS/bin/run.sh b/cMIPS/bin/run.sh index 55974ae92ea526489e2857ee84ac6392f91e9496..c7977f3edbd9d8b69aa41ba563da7aa549668482 100755 --- a/cMIPS/bin/run.sh +++ b/cMIPS/bin/run.sh @@ -26,6 +26,7 @@ unset WAVE length=1 unit=m gtkwconf=pipe +synth= touch input.data input.txt serial.inp @@ -42,6 +43,7 @@ OPTIONS: -n send simulator output do /dev/null, else to v_cMIPS.vcd -w invoke GTKWAVE -- stdin will not read input from keyboard -v F gtkwave configuration file (e.g. pipe.sav, default v.sav) + -syn run simulation with synthesis RAM/ROM addresses EOF } @@ -60,6 +62,8 @@ while true ; do ;; -w) WAVE=true ;; + -syn | -mif ) synth="-syn" + ;; -v) gtkwconf=$2 shift ;; @@ -78,7 +82,7 @@ gfile=${gtkwconf%%.sav} sav="${tree}"/${gfile}.sav -"${bin}"/build.sh || exit 1 +"${bin}"/build.sh $synth || exit 1 options="--ieee-asserts=disable --stop-time=${length}${unit}s --vcd=${visual}" diff --git a/cMIPS/include/cMIPS.h b/cMIPS/include/cMIPS.h index 05346dd57dea5d10b6e3c0ed9fcea5efe6555272..fa8c85418631237d155e205f99b12308f37c4b77 100644 --- a/cMIPS/include/cMIPS.h +++ b/cMIPS/include/cMIPS.h @@ -22,12 +22,13 @@ #define IO_DSP7SEG_ADDR (x_IO_BASE_ADDR + 9 * x_IO_ADDR_RANGE) #define IO_KEYBD_ADDR (x_IO_BASE_ADDR +10 * x_IO_ADDR_RANGE) #define IO_LCD_ADDR (x_IO_BASE_ADDR +11 * x_IO_ADDR_RANGE) -#define IO_SDCARD_ADDR (x_IO_BASE_ADDR +12 * x_IO_ADDR_RANGE) +#define IO_SDC_ADDR (x_IO_BASE_ADDR +12 * x_IO_ADDR_RANGE) extern void exit(int); extern void cmips_delay(int); +extern void delay_cycle(int); extern void delay_us(int); extern void delay_ms(int); @@ -79,6 +80,11 @@ extern void DSP7SEGput(int, int, int, int, int); extern int KBDget(void); extern int SWget(void); +// RGB led color for DSP7SEGput (color must be in [0,7] +#define l_RED 0x4 +#define l_GREEN 0x2 +#define l_BLUE 0x1 + // struct to access the cache system statistics "peripheral" typedef struct sStats { diff --git a/cMIPS/include/cMIPS.s b/cMIPS/include/cMIPS.s index c343e165af49f15c27617ea7cb160920aa480904..7a216e6e4750cab41303ef5ecb19707b571d04b3 100644 --- a/cMIPS/include/cMIPS.s +++ b/cMIPS/include/cMIPS.s @@ -19,7 +19,7 @@ .set HW_dsp7seg_addr,(x_IO_BASE_ADDR + 9 * x_IO_ADDR_RANGE) .set HW_keybd_addr, (x_IO_BASE_ADDR + 10 * x_IO_ADDR_RANGE) .set HW_lcd_addr, (x_IO_BASE_ADDR + 11 * x_IO_ADDR_RANGE) - .set HW_SDcard_addr, (x_IO_BASE_ADDR + 12 * x_IO_ADDR_RANGE) + .set HW_sdc_addr, (x_IO_BASE_ADDR + 12 * x_IO_ADDR_RANGE) # see vhdl/packageMemory.vhd for addresses .set x_EXCEPTION_0000,0x00000130 diff --git a/cMIPS/include/handlers.s b/cMIPS/include/handlers.s index 2d5c425f7bfb8169ca7c0841fa0ac7d44b15ed6a..48121cf05b243e8776c3698285e70786d84e4a4d 100644 --- a/cMIPS/include/handlers.s +++ b/cMIPS/include/handlers.s @@ -69,21 +69,23 @@ extCounter: # interrupt handler for UART attached to IP6=HW4 # for UART's address see vhdl/packageMemory.vhd # - .global Ud, _uart_buff .bss .align 2 + .global Ud Ud: -rx_hd: .space 4 -rx_tl: .space 4 -rx_q: .space 16 # reception queue and pointers -tx_hd: .space 4 -tx_tl: .space 4 -tx_q: .space 16 # transmission queue and pointers +rx_hd: .space 4 # reception queue head index +rx_tl: .space 4 # tail index +rx_q: .space 16 # reception queue +tx_hd: .space 4 # transmission queue head index +tx_tl: .space 4 # tail index +tx_q: .space 16 # transmission queue nrx: .space 4 # characters in RX_queue ntx: .space 4 # spaces left in TX_queue _uart_buff: .space 16*4 # up to 16 registers to be saved here - + # _uart_buff[0]=UARTstatus, [1]=UARTcontrol, [2]=data_inp, [3]=new, + # [4]=$ra, [5]=$a0, [6]=$a1, [7]=$a2, [8]=$a3 + .set UART_rx_irq,0x08 .set UART_tx_irq,0x10 @@ -91,9 +93,6 @@ _uart_buff: .space 16*4 # up to 16 registers to be saved here .set noreorder .global UARTinterr .ent UARTinterr - - # _uart_buff[0]=UARTstatus, [1]=UARTcontrol, [2]=data_inp, [3]=new, - # [4]=$ra, [5]=$a0, [6]=$a1, [7]=$a2, [8]=$a3 UARTinterr: lui $k0, %hi(_uart_buff) # get buffer's address @@ -101,12 +100,12 @@ UARTinterr: sw $a0, 5*4($k0) # save registers $a0,$a1, others? sw $a1, 6*4($k0) + sw $a2, 7*4($k0) lui $a0, %hi(HW_uart_addr)# get device's address ori $a0, $a0, %lo(HW_uart_addr) lw $k1, 0($a0) # Read status, remove interrupt request - nop sw $k1, 0*4($k0) # and save UART status to memory #---------------------------------- @@ -121,12 +120,16 @@ UARTinterr: # handle reception lw $a1, 4($a0) # Read data from device - nop # and store it to UART's buffer - sw $a1, 2*4($k0) # and return from interrupt + + lui $a2, %hi(Ud) # get address for data & flag + ori $a2, $a2, %lo(Ud) + + sw $a1, 0*4($a2) # and return from interrupt addiu $a1, $zero, 1 - sw $a1, 3*4($k0) # Signal new arrival + sw $a1, 1*4($a2) # set flag to signal new arrival UARTret: + lw $a2, 7*4($k0) lw $a1, 6*4($k0) # restore registers $a0,$a1, others? lw $a0, 5*4($k0) @@ -153,6 +156,7 @@ countCompare: mfc0 $k0, c0_status # Read STATUS register ori $k0, $k0, M_StatusIEn # but do not modify its contents mtc0 $k0, c0_status # except for re-enabling interrupts + ehb eret # Return from interrupt .end countCompare #---------------------------------------------------------------- @@ -171,8 +175,10 @@ startCount: lui $v1, 0xf7ff ori $v1, $v1, 0xffff and $v0, $v0, $v1 - jr $ra mtc0 $v0, c0_cause + ehb + jr $ra + nop .end startCount #---------------------------------------------------------------- @@ -220,7 +226,7 @@ enableInterr: mfc0 $v0, c0_status # Read STATUS register ori $v0, $v0, 1 # and enable interrupts mtc0 $v0, c0_status - nop + ehb jr $ra # return updated STATUS nop .end enableInterr @@ -231,7 +237,7 @@ disableInterr: addiu $v1, $zero, -2 # and disable interrupts and $v0, $v0, $v1 # -2 = 0xffff.fffe mtc0 $v0, c0_status - nop + ehb jr $ra # return updated STATUS nop .end disableInterr @@ -481,11 +487,13 @@ pu_miss: jr $ra .ent cmips_delay delay_cycle: cmips_delay: - addiu $a0, $a0, -1 + beq $a0, $zero, _d_cye + nop +_d_cy: addiu $a0, $a0, -1 nop - bne $a0, $zero, cmips_delay + bne $a0, $zero, _d_cy nop - jr $ra +_d_cye: jr $ra nop .end cmips_delay #---------------------------------------------------------------- @@ -498,6 +506,8 @@ cmips_delay: .set noreorder .ent delay_us delay_us: + beq $a0, $zero, _d_use + nop li $v0, 10 mult $v0, $a0 nop @@ -508,7 +518,7 @@ _d_us: addiu $a0, $a0, -1 nop bne $a0, $zero, _d_us nop - jr $ra +_d_use: jr $ra nop .end delay_us #---------------------------------------------------------------- @@ -522,6 +532,8 @@ _d_us: addiu $a0, $a0, -1 .set noreorder .ent delay_ms delay_ms: + beq $a0, $zero, _d_mse + nop li $v0, 10000 mul $a0, $v0, $a0 nop @@ -530,7 +542,7 @@ _d_ms: addiu $a0, $a0, -1 nop bne $a0, $zero, _d_ms nop - jr $ra +_d_mse: jr $ra nop .end delay_ms #---------------------------------------------------------------- diff --git a/cMIPS/tests/mac_chrono.c b/cMIPS/tests/mac_chrono.c index 319bc28ebbe821eadbd84172b6a7ca08d381de6d..728b3bee1242cff9dca38bdf4fe8c144abb14a97 100644 --- a/cMIPS/tests/mac_chrono.c +++ b/cMIPS/tests/mac_chrono.c @@ -24,19 +24,22 @@ void main(void) { LCDtopLine(); #if 1 + LCDput('c'); + LCDput('M'); + LCDput('I'); + LCDput('P'); + LCDput('S'); LCDput(' '); - LCDput('H'); + LCDput('t'); + LCDput('i'); + LCDput('m'); LCDput('e'); - LCDput('l'); - LCDput('l'); - LCDput('o'); LCDput(' '); - LCDput('w'); - LCDput('o'); - LCDput('r'); - LCDput('l'); - LCDput('d'); - LCDput('!'); + LCDput('['); + LCDput('h'); + LCDput('e'); + LCDput('x'); + LCDput(']'); #else LCDprint( print_sp() ); // for debugging only #endif diff --git a/cMIPS/tests/uart_irx.c b/cMIPS/tests/uart_irx.c index 007ddb2633d46174d81f8e81b8364f7d109a4787..a0c00fc7769f849743afc6d78304427045733fc6 100644 --- a/cMIPS/tests/uart_irx.c +++ b/cMIPS/tests/uart_irx.c @@ -13,18 +13,20 @@ #include "uart_defs.c" - -extern int _uart_buff[16]; // declared in include/handlers.s +#define U_DATA 0 +#define U_FLAG 1 #define SPEED 2 // operate at 1/4 of the highest data rate -int main(void) { // receive a string through the UART serial interface +int main(void) { // receive a string through the UART serial interface volatile Tserial *uart; // tell GCC not to optimize away code Tcontrol ctrl; - volatile int *bfr = &(_uart_buff[0]); + extern int Ud[2]; // declared in include/handlers.s + volatile int *bfr; volatile char c; + bfr = (int *)Ud; uart = (void *)IO_UART_ADDR; // bottom of UART address range ctrl.ign = 0; @@ -36,7 +38,7 @@ int main(void) { // receive a string through the UART serial interface // handler sets flag=bfr[3] to 1 after new character is received; // this program resets the flag on fetching a new character from buffer - bfr[3] = 0; // reset flag + bfr[U_FLAG] = 0; // reset flag ctrl.ign = 0; ctrl.rts = 1; // make RTS=1 to activate remote unit @@ -46,12 +48,12 @@ int main(void) { // receive a string through the UART serial interface uart->cs.ctl = ctrl; do { - while ( (c = (char)bfr[3]) == 0 ) - {}; // nothing new - c = (char)bfr[2]; // get new character - bfr[3] = 0; // and reset flag - to_stdout( (int)c ); // and print new char - } while (c != '\0'); // end of string? + while ( (c = (char)bfr[U_FLAG]) == 0 ) // check flag in Ud[1] + {}; // nothing new + c = (char)bfr[U_DATA]; // get new character + bfr[U_FLAG] = 0; // and reset flag + to_stdout( (int)c ); // and print new char + } while (c != '\0'); // end of string? return c; diff --git a/cMIPS/vhdl/SDcard.vhd b/cMIPS/vhdl/SDcard.vhd index 8938a09a39775af66238a3e99e21818f4b363dad..6c22a55fcd016c7f8d6c9f6d8d4efcc2a9021606 100644 --- a/cMIPS/vhdl/SDcard.vhd +++ b/cMIPS/vhdl/SDcard.vhd @@ -264,15 +264,15 @@ package SdCardPckg is component SdCardCtrl is generic ( - FREQ_G : real := 100.0; -- Master clock frequency (MHz). - INIT_SPI_FREQ_G : real := 0.4; -- Slow SPI clock freq. during initialization (MHz). + FREQ_G : real := 100.0; -- Master clock frequency (MHz). + INIT_SPI_FREQ_G : real := 0.4; -- Slow SPI clock freq. during initialization (MHz). SPI_FREQ_G : real := 25.0; -- Operational SPI freq. to the SD card (MHz). - BLOCK_SIZE_G : natural := 512; -- Number of bytes in an SD card block or sector. + BLOCK_SIZE_G : natural := 512; -- Number of bytes in an SD card block or sector. CARD_TYPE_G : CardType_t := SD_CARD_E -- Type of SD card connected to this controller. ); port ( -- Host-side interface signals. - clk_i : in std_logic; -- Master clock. + clk_i : in std_logic; -- Master clock. reset_i : in std_logic := NO; -- active-high, synchronous reset. rd_i : in std_logic := NO; -- active-high read block request. wr_i : in std_logic := NO; -- active-high write block request. @@ -285,10 +285,11 @@ package SdCardPckg is hndShk_o : out std_logic; -- High when controller has taken data or has data to give. error_o : out std_logic_vector(15 downto 0) := (others => NO); -- I/O signals to the external SD card. - cs_bo : out std_logic := HI; -- Active-low chip-select. - sclk_o : out std_logic := LO; -- Serial clock to SD card. - mosi_o : out std_logic := HI; -- Serial data output to SD card. - miso_i : in std_logic := ZERO -- Serial data input from SD card. + cs_bo : out std_logic := HI; -- Active-low chip-select. + sclk_o : out std_logic := LO; -- Serial clock to SD card. + mosi_o : out std_logic := HI; -- Serial data output to SD card. + miso_i : in std_logic := ZERO; -- Serial data input from SD card. + state : out std_logic_vector(4 downto 0) -- state debugging only ); end component; @@ -309,10 +310,10 @@ use work.p_wires.all; entity SdCardCtrl is generic ( - FREQ_G : real := 100.0; -- Master clock frequency (MHz). - INIT_SPI_FREQ_G : real := 0.4; -- Slow SPI clock freq. during initialization (MHz). + FREQ_G : real := 100.0; -- Master clock frequency (MHz). + INIT_SPI_FREQ_G : real := 0.4; -- Slow SPI clock freq. during initialization (MHz). SPI_FREQ_G : real := 25.0; -- Operational SPI freq. to the SD card (MHz). - BLOCK_SIZE_G : natural := 512; -- Number of bytes in an SD card block or sector. + BLOCK_SIZE_G : natural := 512; -- Number of bytes in an SD card block or sector. CARD_TYPE_G : CardType_t := SD_CARD_E -- Type of SD card connected to this controller. ); port ( @@ -330,10 +331,11 @@ entity SdCardCtrl is hndShk_o : out std_logic; -- High when controller has taken data or has data to give. error_o : out std_logic_vector(15 downto 0) := (others => NO); -- I/O signals to the external SD card. - cs_bo : out std_logic := HI; -- Active-low chip-select. - sclk_o : out std_logic := LO; -- Serial clock to SD card. - mosi_o : out std_logic := HI; -- Serial data output to SD card. - miso_i : in std_logic := ZERO -- Serial data input from SD card. + cs_bo : out std_logic := HI; -- Active-low chip-select. + sclk_o : out std_logic := LO; -- Serial clock to SD card. + mosi_o : out std_logic := HI; -- Serial data output to SD card. + miso_i : in std_logic := ZERO; -- Serial data input from SD card. + state : out std_logic_vector(4 downto 0) -- state debugging only ); end entity; @@ -343,35 +345,37 @@ architecture arch of SdCardCtrl is signal sclk_r : std_logic := ZERO; -- Register output drives SD card clock. signal hndShk_r : std_logic := NO; -- Register output drives handshake output to host. + signal sd_state_dbg : integer:= 0; -- debugging only + begin process(clk_i) -- FSM process for the SD card controller. type FsmState_t is ( -- States of the SD card controller FSM. - START_INIT, -- Send initialization clock pulses to the deselected SD card. - SEND_CMD0, -- Put the SD card in the IDLE state. - CHK_CMD0_RESPONSE, -- Check card's R1 response to the CMD0. - SEND_CMD8, -- This command is needed to initialize SDHC cards. - GET_CMD8_RESPONSE, -- Get the R7 response to CMD8. - SEND_CMD55, -- Send CMD55 to the SD card. - SEND_CMD41, -- Send CMD41 to the SD card. - CHK_ACMD41_RESPONSE, -- Check if the SD card has left the IDLE state. - WAIT_FOR_HOST_RW, -- Wait for the host to issue a read or write command. - RD_BLK, -- Read a block of data from the SD card. - WR_BLK, -- Write a block of data to the SD card. - WR_WAIT, -- Wait for SD card to finish writing the data block. - START_TX, -- Start sending command/data. - TX_BITS, -- Shift out remaining command/data bits. - GET_CMD_RESPONSE, -- Get the R1 response of the SD card to a command. - RX_BITS, -- Receive response/data from the SD card. - DESELECT, -- De-select the SD card and send some clock pulses (Must enter with sclk at zero.) - PULSE_SCLK, -- Issue some clock pulses. (Must enter with sclk at zero.) - REPORT_ERROR -- Report error and stall until reset. + START_INIT, -- 0 Send initialization clock pulses to the deselected SD card. + SEND_CMD0, -- 1 Put the SD card in the IDLE state. + CHK_CMD0_RESPONSE, -- 2 Check card's R1 response to the CMD0. + SEND_CMD8, -- 3 This command is needed to initialize SDHC cards. + GET_CMD8_RESPONSE, -- 4 Get the R7 response to CMD8. + SEND_CMD55, -- 5 Send CMD55 to the SD card. + SEND_CMD41, -- 6 Send CMD41 to the SD card. + CHK_ACMD41_RESPONSE, -- 7 Check if the SD card has left the IDLE state. + WAIT_FOR_HOST_RW, -- 8 Wait for the host to issue a read or write command. + RD_BLK, -- 9 Read a block of data from the SD card. + WR_BLK, -- 10 Write a block of data to the SD card. + WR_WAIT, -- 11 Wait for SD card to finish writing the data block. + START_TX, -- 12 Start sending command/data. + TX_BITS, -- 13 Shift out remaining command/data bits. + GET_CMD_RESPONSE, -- 14 Get the R1 response of the SD card to a command. + RX_BITS, -- 15 Receive response/data from the SD card. + DESELECT, -- 16 De-select the SD card and send some clock pulses (Must enter with sclk at zero.) + PULSE_SCLK, -- 17 Issue some clock pulses. (Must enter with sclk at zero.) + REPORT_ERROR -- 18 Report error and stall until reset. ); attribute SYN_ENCODING of FsmState_t : type is "safe"; variable state_v : FsmState_t := START_INIT; -- Current state of the FSM. variable rtnState_v : FsmState_t; -- State FSM returns to when FSM subroutine completes. - + -- Timing constants based on the master clock frequency and the SPI SCLK frequencies. constant CLKS_PER_INIT_SCLK_C : real := FREQ_G / INIT_SPI_FREQ_G; constant CLKS_PER_SCLK_C : real := FREQ_G / SPI_FREQ_G; @@ -433,6 +437,10 @@ begin variable doDeselect_v : boolean; -- When true, de-select SD card after a command is issued. begin + + sd_state_dbg <= FsmState_t'pos(state_v); -- debugging only + state <= std_logic_vector(to_unsigned(sd_state_dbg, 5)); + if rising_edge(clk_i) then if reset_i = YES then -- Perform a reset. @@ -479,7 +487,7 @@ begin addr_v := (others => ZERO); -- Initialize address. rtnData_v := false; -- No data is returned to host during initialization. bitCnt_v := NUM_INIT_CLKS_C; -- Generate this many clock pulses. - state_v := DESELECT; -- De-select the SD card and pulse SCLK. + state_v := DESELECT; -- De-select the SD card and pulse SCLK. rtnState_v := SEND_CMD0; -- Then go to this state after the clock pulses are done. when SEND_CMD0 => -- Put the SD card in the IDLE state. @@ -495,24 +503,24 @@ begin if rx_v = IDLE_NO_ERRORS_C then state_v := SEND_CMD8; -- Continue init if SD card is in IDLE state with no errors else - state_v := SEND_CMD0; -- Otherwise, try CMD0 again. + state_v := SEND_CMD0; -- Otherwise, try CMD0 again. end if; when SEND_CMD8 => -- This command is needed to initialize SDHC cards. cs_bo <= LO; -- Enable the SD card. txCmd_v := CMD8_C & x"000001aa" & x"87"; -- 0x87 is the correct CRC for this command. bitCnt_v := txCmd_v'length; -- Set bit counter to the size of the command. - getCmdResponse_v := true; -- Sending a command that generates a response. + getCmdResponse_v := true; -- Sending a command that generates a response. doDeselect_v := false; -- Don't de-select, need to get the R7 response sent from the SD card. state_v := START_TX; -- Go to FSM subroutine to send the command. rtnState_v := GET_CMD8_RESPONSE; -- Then go to this state after the command is sent. when GET_CMD8_RESPONSE => -- Get the R7 response to CMD8. - cs_bo <= LO; -- The SD card should already be enabled, but let's be explicit. + cs_bo <= LO; -- The SD card should already be enabled, but let's be explicit. bitCnt_v := 31; -- Four bytes (32 bits) in R7 response. getCmdResponse_v := false; -- Not sending a command that generates a response. - doDeselect_v := true; -- De-select card to end the command after getting the four bytes. - state_v := RX_BITS; -- Go to FSM subroutine to get the R7 response. + doDeselect_v := true; -- De-select card to end the command after getting the four bytes. + state_v := RX_BITS; -- Go to FSM subroutine to get the R7 response. rtnState_v := SEND_CMD55; -- Then go here (we don't care what the actual R7 response is). when SEND_CMD55 => -- Send CMD55 as preamble of ACMD41 initialization command. @@ -521,7 +529,7 @@ begin bitCnt_v := txCmd_v'length; -- Set bit counter to the size of the command. getCmdResponse_v := true; -- Sending a command that generates a response. doDeselect_v := true; -- De-select SD card after this command finishes. - state_v := START_TX; -- Go to FSM subroutine to send the command. + state_v := START_TX; -- Go to FSM subroutine to send the command. rtnState_v := SEND_CMD41; -- Then go to this state after the command is sent. when SEND_CMD41 => -- Send the SD card the initialization command. @@ -530,7 +538,7 @@ begin bitCnt_v := txCmd_v'length; -- Set bit counter to the size of the command. getCmdResponse_v := true; -- Sending a command that generates a response. doDeselect_v := true; -- De-select SD card after this command finishes. - state_v := START_TX; -- Go to FSM subroutine to send the command. + state_v := START_TX; -- Go to FSM subroutine to send the command. rtnState_v := CHK_ACMD41_RESPONSE; -- Then check the response to the command. when CHK_ACMD41_RESPONSE => @@ -538,17 +546,17 @@ begin -- and become ready for SPI read/write operations. If still IDLE, then repeat the CMD55, CMD41 sequence. -- If one of the R1 error flags is set, then report the error and stall. if rx_v = ACTIVE_NO_ERRORS_C then -- Not IDLE, no errors. - state_v := WAIT_FOR_HOST_RW; -- Start processing R/W commands from the host. + state_v := WAIT_FOR_HOST_RW; -- Start processing R/W commands from the host. elsif rx_v = IDLE_NO_ERRORS_C then -- Still IDLE but no errors. - state_v := SEND_CMD55; -- Repeat the CMD55, CMD41 sequence. - else -- Some error occurred. - state_v := REPORT_ERROR; -- Report the error and stall. + state_v := SEND_CMD55; -- Repeat the CMD55, CMD41 sequence. + else -- Some error occurred. + state_v := REPORT_ERROR; -- Report the error and stall. end if; when WAIT_FOR_HOST_RW => -- Wait for the host to read or write a block of data from the SD card. clkDivider_v := SCLK_PHASE_PERIOD_C - 1; -- Set SPI clock frequency for normal operation. - getCmdResponse_v := true; -- Get R1 response to any commands issued to the SD card. - if rd_i = YES then -- send READ command and address to the SD card. + getCmdResponse_v := true; -- Get R1 response to any commands issued to the SD card. + if rd_i = YES then -- send READ command and address to the SD card. cs_bo <= LO; -- Enable the SD card. if continue_i = YES then -- Multi-block read. Use stored address. if CARD_TYPE_G = SD_CARD_E then -- SD cards use byte-addressing, @@ -561,39 +569,39 @@ begin txCmd_v := READ_BLK_CMD_C & addr_i & FAKE_CRC_C; -- Use address supplied by host. addr_v := unsigned(addr_i); -- Store address for multi-block operations. end if; - bitCnt_v := txCmd_v'length; -- Set bit counter to the size of the command. + bitCnt_v := txCmd_v'length; -- Set bit counter to the size of the command. byteCnt_v := RD_BLK_SZ_C; - state_v := START_TX; -- Go to FSM subroutine to send the command. - rtnState_v := RD_BLK; -- Then go to this state to read the data block. + state_v := START_TX; -- Go to FSM subroutine to send the command. + rtnState_v := RD_BLK; -- Then go to this state to read the data block. elsif wr_i = YES then -- send WRITE command and address to the SD card. cs_bo <= LO; -- Enable the SD card. if continue_i = YES then -- Multi-block write. Use stored address. if CARD_TYPE_G = SD_CARD_E then -- SD cards use byte-addressing, addr_v := addr_v + BLOCK_SIZE_G; -- so add block-size to get next block address. - else -- SDHC cards use block-addressing, + else -- SDHC cards use block-addressing, addr_v := addr_v + 1; -- so just increment current block address. end if; txCmd_v := WRITE_BLK_CMD_C & std_logic_vector(addr_v) & FAKE_CRC_C; - else -- Single-block write. + else -- Single-block write. txCmd_v := WRITE_BLK_CMD_C & addr_i & FAKE_CRC_C; -- Use address supplied by host. addr_v := unsigned(addr_i); -- Store address for multi-block operations. end if; bitCnt_v := txCmd_v'length; -- Set bit counter to the size of the command. - byteCnt_v := WR_BLK_SZ_C; -- Set number of bytes to write. - state_v := START_TX; -- Go to this FSM subroutine to send the command ... - rtnState_v := WR_BLK; -- then go to this state to write the data block. + byteCnt_v := WR_BLK_SZ_C; -- Set number of bytes to write. + state_v := START_TX; -- Go to this FSM subroutine to send the command + rtnState_v := WR_BLK; -- then go to this state to write the data block. else -- Do nothing and wait for command from host. - cs_bo <= HI; -- Deselect the SD card. + cs_bo <= HI; -- Deselect the SD card. busy_o <= NO; -- SD card interface is waiting for R/W from host, so it's not busy. - state_v := WAIT_FOR_HOST_RW; -- Keep waiting for command from host. + state_v := WAIT_FOR_HOST_RW; -- Keep waiting for command from host. end if; when RD_BLK => -- Read a block of data from the SD card. -- Some default values for these... - rtnData_v := false; -- Data is only returned to host in one place. + rtnData_v := false; -- Data is only returned to host in one place. bitCnt_v := rx_v'length - 1; -- Receiving byte-sized data. state_v := RX_BITS; -- Call the bit receiver routine. - rtnState_v := RD_BLK; -- Return here when done receiving a byte. + rtnState_v := RD_BLK; -- Return here when done receiving a byte. if byteCnt_v = RD_BLK_SZ_C then -- Initial read to prime the pump. byteCnt_v := byteCnt_v - 1; elsif byteCnt_v = RD_BLK_SZ_C -1 then -- Then look for the data block start token. @@ -606,11 +614,11 @@ begin state_v := REPORT_ERROR; end if; elsif byteCnt_v >= 3 then -- Now bytes of data from the SD card are received. - rtnData_v := true; -- Return this data to the host. + rtnData_v := true; -- Return this data to the host. byteCnt_v := byteCnt_v - 1; - elsif byteCnt_v = 2 then -- Receive the 1st CRC byte at the end of the data block. + elsif byteCnt_v = 2 then -- Receive the 1st CRC byte at the end of the data block. byteCnt_v := byteCnt_v - 1; - elsif byteCnt_v = 1 then -- Receive the 2nd + elsif byteCnt_v = 1 then -- Receive the 2nd byteCnt_v := byteCnt_v - 1; else -- Reading is done, so deselect the SD card. sclk_r <= LO; @@ -623,24 +631,24 @@ begin -- Some default values for these... getCmdResponse_v := false; -- Sending data bytes so there's no command response from SD card. bitCnt_v := txData_v'length; -- Transmitting byte-sized data. - state_v := START_TX; -- Call the bit transmitter routine. - rtnState_v := WR_BLK; -- Return here when done transmitting a byte. + state_v := START_TX; -- Call the bit transmitter routine. + rtnState_v := WR_BLK; -- Return here when done transmitting a byte. if byteCnt_v = WR_BLK_SZ_C then - txData_v := NO_TOKEN_C; -- Hold MOSI high for one byte before data block goes out. + txData_v := NO_TOKEN_C; -- Hold MOSI high for one byte before data block goes out. elsif byteCnt_v = WR_BLK_SZ_C - 1 then -- Send start token. - txData_v := START_TOKEN_C; -- Starting token for data block. - elsif byteCnt_v >= 4 then -- Now send bytes in the data block. - hndShk_r <= HI; -- Signal host to provide data. + txData_v := START_TOKEN_C; -- Starting token for data block. + elsif byteCnt_v >= 4 then -- Now send bytes in the data block. + hndShk_r <= HI; -- Signal host to provide data. -- The transmit shift register is loaded with data from host in the handshaking section above. elsif byteCnt_v = 3 or byteCnt_v = 2 then -- Send two phony CRC bytes at end of packet. txData_v := FAKE_CRC_C; elsif byteCnt_v = 1 then bitCnt_v := rx_v'length - 1; - state_v := RX_BITS; -- Get response of SD card to the write operation. + state_v := RX_BITS; -- Get response of SD card to the write operation. rtnState_v := WR_WAIT; else -- Check received response byte. if std_match(rx_v, DATA_ACCEPTED_C) then -- Data block was accepted. - state_v := WR_WAIT; -- Wait for the SD card to finish writing the data into Flash. + state_v := WR_WAIT; -- Wait for the SD card to finish writing the data into Flash. else -- Data block was rejected. error_o(15 downto 8) <= rx_v; state_v := REPORT_ERROR; -- Report the error. @@ -662,11 +670,11 @@ begin -- Start sending command/data by lowering SCLK and outputing MSB of command/data -- so it has plenty of setup before the rising edge of SCLK. sclk_r <= LO; -- Lower the SCLK (although it should already be low). - sclkPhaseTimer_v := clkDivider_v; -- Set the duration of the low SCLK. + sclkPhaseTimer_v := clkDivider_v; -- Set the duration of the low SCLK. mosi_o <= tx_v(tx_v'high); -- Output MSB of command/data. tx_v := tx_v(tx_v'high-1 downto 0) & ONE; -- Shift command/data register by one bit. - bitCnt_v := bitCnt_v - 1; -- The first bit has been sent, so decrement bit counter. - state_v := TX_BITS; -- Go here to shift out the rest of the command/data bits. + bitCnt_v := bitCnt_v - 1; -- The first bit has been sent, so decrement bit counter. + state_v := TX_BITS; -- Go here to shift out the rest of the command/data bits. when TX_BITS => -- Shift out remaining command/data bits and (possibly) get response from SD card. sclk_r <= not sclk_r; -- Toggle the SPI clock... @@ -674,46 +682,46 @@ begin if sclk_r = HI then -- SCLK is going to be flipped from high to low, so output the next command/data bit -- so it can setup while SCLK is low. - if bitCnt_v /= 0 then -- Keep sending bits until the bit counter hits zero. + if bitCnt_v /= 0 then -- Keep sending bits until the bit counter hits zero. mosi_o <= tx_v(tx_v'high); tx_v := tx_v(tx_v'high-1 downto 0) & ONE; bitCnt_v := bitCnt_v - 1; else if getCmdResponse_v then - state_v := GET_CMD_RESPONSE; -- Get a response to the command from the SD card. - bitCnt_v := Response_t'length - 1; -- Length of the expected response. + state_v := GET_CMD_RESPONSE; -- Get a response to the command from the SD card. + bitCnt_v := Response_t'length - 1; -- Length of the expected response. else - state_v := rtnState_v; -- Return to calling state (no need to get a response). - sclkPhaseTimer_v := 0; -- Clear timer so next SPI op can begin ASAP with SCLK low. + state_v := rtnState_v; -- Return to calling state (no need to get a response). + sclkPhaseTimer_v := 0; -- Clear timer so next SPI op can begin ASAP with SCLK low. end if; end if; end if; when GET_CMD_RESPONSE => -- Get the response of the SD card to a command. - if sclk_r = HI and miso_i = LO then -- MISO will be held high by SD card until 1st bit of R1 response, which is 0. - -- Shift in the MSB bit of the response. - rx_v := rx_v(rx_v'high-1 downto 0) & miso_i; + if sclk_r = HI and miso_i = LO then -- MISO will be held high by SD card until 1st bit + -- of R1 response, which is 0. + rx_v := rx_v(rx_v'high-1 downto 0) & miso_i; -- Shift in the MSB bit of the response. bitCnt_v := bitCnt_v - 1; - state_v := RX_BITS; -- Now receive the reset of the response. + state_v := RX_BITS; -- Now receive the reset of the response. end if; - sclk_r <= not sclk_r; -- Toggle the SPI clock... - sclkPhaseTimer_v := clkDivider_v; -- and set the duration of the next clock phase. + sclk_r <= not sclk_r; -- Toggle the SPI clock... + sclkPhaseTimer_v := clkDivider_v; -- and set the duration of the next clock phase. when RX_BITS => -- Receive bits from the SD card. - if sclk_r = HI then -- Bits enter after the rising edge of SCLK. + if sclk_r = HI then -- Bits enter after the rising edge of SCLK. rx_v := rx_v(rx_v'high-1 downto 0) & miso_i; if bitCnt_v /= 0 then -- More bits left to receive. bitCnt_v := bitCnt_v - 1; else -- Last bit has been received. if rtnData_v then -- Send the received data to the host. data_o <= rx_v; -- Output received data to the host. - hndShk_r <= HI; -- Signal to the host that the data is ready. + hndShk_r <= HI; -- Signal to the host that the data is ready. end if; if doDeselect_v then bitCnt_v := 1; state_v := DESELECT; -- De-select SD card before returning. else - state_v := rtnState_v; -- Otherwise, return to calling state without de-selecting. + state_v := rtnState_v; -- Otherwise, return to calling state without de-selecting. end if; end if; end if; @@ -723,16 +731,16 @@ begin when DESELECT => -- De-select the SD card and send some clock pulses (Must enter with sclk at zero.) doDeselect_v := false; -- Once the de-select is done, clear the flag that caused it. cs_bo <= HI; -- De-select the SD card. - mosi_o <= HI; -- Keep the data input of the SD card pulled high. + mosi_o <= HI; -- Keep the data input of the SD card pulled high. state_v := PULSE_SCLK; -- Pulse the clock so the SD card will see the de-select. - sclk_r <= LO; -- Clock is set low so the next rising edge will see the new CS and MOSI + sclk_r <= LO; -- Clock is set low so the next rising edge will see the new CS and MOSI sclkPhaseTimer_v := clkDivider_v; -- Set the duration of the next clock phase. when PULSE_SCLK => -- Issue some clock pulses. (Must enter with sclk at zero.) if sclk_r = HI then if bitCnt_v /= 0 then bitCnt_v := bitCnt_v - 1; - else -- Return to the calling routine when the pulse counter reaches zero. + else -- Return to the calling routine when the pulse counter reaches zero. state_v := rtnState_v; end if; end if; @@ -741,7 +749,7 @@ begin when REPORT_ERROR => -- Report the error code and stall here until a reset occurs. error_o(rx_v'range) <= rx_v; -- Output the SD card response as the error code. - busy_o <= NO; -- Not busy. + busy_o <= NO; -- Not busy. when others => state_v := START_INIT; diff --git a/cMIPS/vhdl/core.vhd b/cMIPS/vhdl/core.vhd index c4910c48493432e566cedad4168d7437932b3654..ccf6fb437b37af72f01d0a744ad7348a4e409cf3 100644 --- a/cMIPS/vhdl/core.vhd +++ b/cMIPS/vhdl/core.vhd @@ -1809,8 +1809,17 @@ begin -- delay the IRQ to make sure the interrupted instruction completes; -- This is needed to ensure forward-progress: at least one instruction -- must complete before another interrupt may be taken. + -- Also, delay the interrupt requests to avoid hazards while + -- the interrupt-enable bit is changed in the STATUS register. - dly_i0 <= '1' when is_exception = exERET else '0'; + dly_i0 <= '1' when ( (EX_exception = exERET) or -- forward progress + (EX_exception = exEI) or -- interrupt hazard + (EX_exception = exDI) or -- interrupt hazard + (EX_exception = exEHB) or -- interrupt hazard + (EX_exception = exMTC0 -- interrupt hazard + and EX_cop0_reg = cop0reg_STATUS) ) else + '0'; + U_DLY_INT1: FFD port map (clk, rst, '1',dly_i0, dly_i1); U_DLY_INT2: FFD port map (clk, rst, '1',dly_i1, dly_i2); dly_interr <= dly_i0 or dly_i1 or dly_i2; @@ -1864,7 +1873,7 @@ begin -- STATUS -- pg 79 -- cop0_12 -------------------- COP0_DECODE_EXCEPTION_AND_UPDATE_STATUS: process (MM_a_rt, is_exception, cop0_inp, - MM_cop0_reg, MM_cop0_sel, MM_int_req, + MM_cop0_reg, MM_cop0_sel, RF_is_delayslot, EX_is_delayslot, MM_is_delayslot, WB_is_delayslot, rom_stall,ram_stall, MM_is_mfc0, INDEX, RANDOM, EntryLo0, EntryLo1, CONTEXT, PAGEMASK, WIRED, diff --git a/cMIPS/vhdl/io.vhd b/cMIPS/vhdl/io.vhd index d622f68e54ef86660a4d402596dfd18be8fd19a5..b2c4683e9da9e0820cf2f3c3192424a862d76352 100644 --- a/cMIPS/vhdl/io.vhd +++ b/cMIPS/vhdl/io.vhd @@ -977,14 +977,14 @@ entity SDcard is sel : in std_logic; rdy : out std_logic; wr : in std_logic; - addr : in reg2; -- a03, a02 + addr : in reg2; -- a03, a02 data_inp : in reg32; data_out : out reg32; - sdc_cs : out std_logic; -- SDcard chip-select - sdc_clk : out std_logic; -- SDcard serial clock - sdc_mosi_o : out std_logic; -- SDcard serial data out (to card) - sdc_mosi_i : in std_logic; -- SDcard serial data inp (fro card) - irq : out std_logic); -- interrupt request (not yet used) + sdc_cs : out std_logic; -- SDcard chip-select + sdc_clk : out std_logic; -- SDcard serial clock + sdc_mosi_o : out std_logic; -- SDcard serial data out (to card) + sdc_miso_i : in std_logic; -- SDcard serial data inp (fro card) + irq : out std_logic); -- interrupt request (not yet used) end SDCard; architecture behavioral of SDcard is @@ -1033,27 +1033,30 @@ architecture behavioral of SDcard is cs_bo : out std_logic; -- Active-low chip-select. sclk_o : out std_logic; -- Serial clock to SD card. mosi_o : out std_logic; -- Serial data output to SD card. - miso_i : in std_logic); -- Serial data input from SD card. + miso_i : in std_logic; -- Serial data input from SD card. + state : out std_logic_vector); -- state, debugging only end component SdCardCtrl; signal s_addr, s_stat, s_ctrl, s_read, s_write : std_logic; signal continue, busy, hndShk_i, hndShk_o, wr_i, rd_i : std_logic; signal wait1, waiting, new_trans, new_data_rd, sdc_rst : std_logic; - signal ctrl_err, set_wr_i, clr_wr_i, set_rd_i, clr_rd_i : std_logic; + signal ctrl_err, set_wr_i, set_rd_i : std_logic; signal do_reset, do_reset1 : std_logic; signal data_rd, data_rd_reg, data_wr_reg : reg8; signal error_o : reg16; signal addr_reg : reg32; signal sel_data_out : reg3; + signal state : reg5; signal w : reg5; begin U_SDcard: SdCardCtrl - generic map (50.0, 0.400, 25.0, 512, SD_CARD_E) + -- generic map (50.0, 0.400, 12.5, 512, SD_CARD_E) + generic map (50.0, 25.0, 25.0, 512, SD_CARD_E) port map (clk, sdc_rst, rd_i, wr_i, '0', addr_reg, data_wr_reg, data_rd, busy, hndshk_i, open, error_o, -- data_wr_reg, data_rd, busy, hndshk_i, hndshk_o, error_o, - sdc_cs, sdc_clk, sdc_mosi_o, sdc_mosi_i); + sdc_cs, sdc_clk, sdc_mosi_o, sdc_miso_i, state); hndshk_i <= waiting; @@ -1076,7 +1079,7 @@ begin waiting <= w; end process U_WAIT; - rdy <= not(wait1 or waiting); -- wait for 260ns + rdy <= not(wait1 or waiting); -- wait for controller new_data_rd <= not(hndshk_o); U_W1: FFDsimple port map (clk, rst, wait1, w(0)); @@ -1103,25 +1106,21 @@ begin s_write <= '0' when sel = '0' and addr = b"01" and wr = '0' else '1'; s_read <= '0' when sel = '0' and addr = b"01" and wr = '1' else '1'; - s_ctrl <= '1' when sel = '0' and addr = b"10" and wr = '1' else '0'; + s_ctrl <= '1' when sel = '0' and addr = b"10" and wr = '0' else '0'; s_stat <= '1' when sel = '0' and addr = b"11" and wr = '1' else '0'; do_reset <= '1' when s_ctrl = '1' and data_inp(4) = '1' else '0'; U_RESET1: FFDsimple port map (clk, rst, do_reset, do_reset1); - sdc_rst <= not(rst) or do_reset or do_reset1; -- held for 2 cycles - - -- set_wr_i <= '1' when else '0'; - -- clr_wr_i <= rst and s_write; - - set_wr_i <= (s_ctrl and data_inp(0)) or (wr_i and s_write); - U_WR_STROBE: FFDsimple port map (clk, clr_wr_i, set_wr_i, wr_i); + sdc_rst <= not(rst) or do_reset or do_reset1; -- held HI for 2 cycles - -- set_rd_i <= '1' when s_ctrl = '1' and data_inp(1) = '1' else '0'; - -- clr_rd_i <= rst and s_read; + -- hold wr_i active until first access to WR-register + set_wr_i <= ((s_ctrl and data_inp(0)) or (wr_i and s_write)) and s_write; + U_WR_STROBE: FFDsimple port map (clk, rst, set_wr_i, wr_i); - set_rd_i <= (s_ctrl and data_inp(1)) or (rd_i and s_read); - U_RD_STROBE: FFDsimple port map (clk, clr_rd_i, set_rd_i, rd_i); + -- hold rd_i active until first access to RD-register + set_rd_i <= ((s_ctrl and data_inp(1)) or (rd_i and s_read)) and s_read; + U_RD_STROBE: FFDsimple port map (clk, rst, set_rd_i, rd_i); ctrl_err <= wr_i and rd_i; -- cannot both read AND write @@ -1140,7 +1139,7 @@ begin data_out <= addr_reg when "000", x"000000" & data_rd_reg when "001", x"000000" & b"000" & ctrl_err & b"00" & rd_i & wr_i when "010", - busy & ctrl_err & b"00" & x"000" & error_o when "011", + busy & ctrl_err & b"00" & b"000" & state & x"0" & error_o when "011", (others => 'X') when others; end behavioral; diff --git a/cMIPS/vhdl/tb_cMIPS.vhd b/cMIPS/vhdl/tb_cMIPS.vhd index bb25ab896a45d68b32c3fa1385eaa93d33bb5c8a..2d2bb5a9a5a75f46b0e14f821e01cfca595d1fc2 100644 --- a/cMIPS/vhdl/tb_cMIPS.vhd +++ b/cMIPS/vhdl/tb_cMIPS.vhd @@ -41,13 +41,13 @@ architecture TB of tb_cMIPS is sel : in std_logic; rdy : out std_logic; wr : in std_logic; - addr : in std_logic_vector; -- a03, a02 + addr : in std_logic_vector; -- a03, a02 data_inp : in std_logic_vector; data_out : out std_logic_vector; sdc_cs : out std_logic; -- SDcard chip-select sdc_clk : out std_logic; -- SDcard serial clock sdc_mosi_o : out std_logic; -- SDcard serial data out (to card) - sdc_mosi_i : in std_logic; -- SDcard serial data inp (fro card) + sdc_miso_i : in std_logic; -- SDcard serial data inp (fro card) irq : out std_logic); -- interrupt request (not yet used) end component SDCard; @@ -477,7 +477,7 @@ architecture TB of tb_cMIPS is signal LCD_DATA : std_logic_vector(7 downto 0); -- LCD data bus signal LCD_RS, LCD_RW, LCD_EN, LCD_BLON : std_logic; -- LCD control signal uart_txd, uart_rxd, uart_rts, uart_cts, uart_irq : std_logic; - signal sdc_cs, sdc_clk, sdc_mosi_o, sdc_mosi_i : std_logic; + signal sdc_cs, sdc_clk, sdc_mosi_o, sdc_miso_i : std_logic; signal sdcke, sdscs, sdras, sdcas, sdwe : std_logic; -- SDRAM @@ -659,7 +659,7 @@ begin -- TB U_sdcard: SDcard port map (rst, clk, io_sdc_sel, io_sdc_wait, wr, d_addr(3 downto 2), cpu_data, sdc_d_out, - sdc_cs, sdc_clk, sdc_mosi_o, sdc_mosi_i, open); + sdc_cs, sdc_clk, sdc_mosi_o, sdc_miso_i, open); U_FPU: FPU port map (rst,clk, io_FPU_sel, io_FPU_wait, wr, d_addr(5 downto 2), diff --git a/cMIPS/vhdl/uart.vhd b/cMIPS/vhdl/uart.vhd index 04f99d00cbf7c61b32de390054e7d6265fee04f1..adc1d5a45079f65c8dfa004e5ee7b76364f26303 100644 --- a/cMIPS/vhdl/uart.vhd +++ b/cMIPS/vhdl/uart.vhd @@ -21,15 +21,16 @@ -- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -- control register, least significant byte only --- b0..b2: transmit/receive clock speed +-- b2..b0: transmit/receive clock speed -- 000: 1/4 CPU clock rate -- for VHDL/C debugging only -- 001: 1/8 CPU clock rate -- for VHDL/C debugging only -- 010: 1/16 CPU clock rate -- for VHDL/C debugging only --- 011: 115.200 baud --- 100: 57.600 baud --- 101: 38.400 baud --- 110: 28.800 baud --- 111: 19.200 baud +-- 011: 1/32 CPU clock rate -- for VHDL/C debugging only +-- 100: 230.400 baud +-- 100: 115.200 baud +-- 101: 57.600 baud +-- 110: 19.200 baud +-- 111: 9.600 baus -- b3=1: signal interrupt on RX buffer full, when a new octet is available -- b4=1: signal interrupt on TX buffer empty, when TX space is available -- b5,b6: ignored, not used @@ -566,23 +567,22 @@ begin tx_baud_div <= 4/2 when b"000", 8/2 when b"001", 16/2 when b"010", - 434/2 when b"011", - 868/2 when b"100", - 1302/2 when b"101", - 1736/2 when b"110", - -- 2604/2 when others; - -- 3472/2 when b"110", - 5208/2 when others; - + 32/2 when b"011", + 217/2 when b"100", -- 230.400 + 434/2 when b"101", -- 115.200 + 868/2 when b"110", -- 57.600 + 2604/2 when b"110", -- 19.200 + 5208/2 when others; -- 9.600 -- 000: 1/4 CPU clock rate -- for VHDL/C debugging only -- 001: 1/8 CPU clock rate -- for VHDL/C debugging only -- 010: 1/16 CPU clock rate -- for VHDL/C debugging only --- 011: 115.200 baud --- 100: 57.600 baud --- 101: 38.400 baud --- 110: 28.800 baud --- 111: 9.600 baus -- 19.200 baud +-- 011: 1/32 CPU clock rate -- for VHDL/C debugging only +-- 100: 230.400 baud +-- 100: 115.200 baud +-- 101: 57.600 baud +-- 110: 19.200 baud +-- 111: 9.600 baus -- max divisor would be 50,000,000 / 1,200 bps = 46.667 < 64k-1 U_bit_rt_tx: process(clk, rst, tx_ld, en_tx_clk) @@ -618,13 +618,12 @@ begin rx_baud_div <= 4/2 when b"000", 8/2 when b"001", 16/2 when b"010", - 434/2 when b"011", - 868/2 when b"100", - 1302/2 when b"101", - 1736/2 when b"110", - -- 2604/2 when others; - -- 3472/2 when b"110", - 5208/2 when others; + 32/2 when b"011", + 217/2 when b"100", -- 230.400 + 434/2 when b"101", -- 115.200 + 868/2 when b"110", -- 57.600 + 2604/2 when b"110", -- 19.200 + 5208/2 when others; -- 9.600 U_bit_rt_rx: process(clk, rst, reset_rxck, en_rx_clk) variable baud_cnt : integer range 0 to 65535; @@ -1062,13 +1061,12 @@ begin tx_baud_div <= 4/2 when b"000", 8/2 when b"001", 16/2 when b"010", - 434/2 when b"011", - 868/2 when b"100", - 1302/2 when b"101", - 1736/2 when b"110", - -- 2604/2 when others; - -- 3472/2 when b"110", - 5208/2 when others; + 32/2 when b"011", + 217/2 when b"100", -- 230.400 + 434/2 when b"101", -- 115.200 + 868/2 when b"110", -- 57.600 + 2604/2 when b"110", -- 19.200 + 5208/2 when others; -- 9.600 U_bit_rt_tx: process(clk, rst) variable baud_cnt : integer; @@ -1092,13 +1090,12 @@ begin rx_baud_div <= 4/2 when b"000", 8/2 when b"001", 16/2 when b"010", - 434/2 when b"011", - 868/2 when b"100", - 1302/2 when b"101", - 1736/2 when b"110", - -- 2604/2 when others; - -- 3472/2 when b"110", - 5208/2 when others; + 32/2 when b"011", + 217/2 when b"100", -- 230.400 + 434/2 when b"101", -- 115.200 + 868/2 when b"110", -- 57.600 + 2604/2 when b"110", -- 19.200 + 5208/2 when others; -- 9.600 U_bit_rt_rx: process(clk, rst, reset_rxck, rx_run) variable baud_cnt : integer;