Commit f5884ddc authored by Roberto Hexsel's avatar Roberto Hexsel

VHDL code for SDcard controller

parent af6daa88
......@@ -101,18 +101,23 @@ done
if [ -z $inp ] ; then usage ; exit 1 ; fi
pkg_vhd="${srcVHDL}"/packageMemory.vhd
# pkg_vhd="${srcVHDL}"/packageMemory.vhd
if [ $miffile = true ]; then
S="-D FOR_SYNTHESIS" ;
ln -sf ${srcVHDL}/packageMemory_fpga.vhd $pkg_vhd
touch $pkg_vhd
pkg_vhd="${srcVHDL}"/packageMemory_fpga.vhd
(cd $srcVHDL ; ln -s -f packageMemory_fpga.vhd packageMemory.vhd)
# ln -sf ${srcVHDL}/packageMemory_fpga.vhd $pkg_vhd
# touch $pkg_vhd
else
S="-U FOR_SYNTHESIS" ;
ln -sf ${srcVHDL}/packageMemory_simu.vhd $pkg_vhd
touch $pkg_vhd
pkg_vhd="${srcVHDL}"/packageMemory_simu.vhd
(cd $srcVHDL ; ln -s -f packageMemory_simu.vhd packageMemory.vhd)
# ln -sf ${srcVHDL}/packageMemory_simu.vhd $pkg_vhd
# touch $pkg_vhd
fi
if [ $pkg_vhd -nt $c_ld -o $pkg_vhd -nt $c_s ] ; then
"${bin}"/edMemory.sh -v || errorED || exit 1
fi
......
#!/bin/bash
## ------------------------------------------------------------------------
## cMIPS, Roberto Hexsel, 30set2013, rev 08jan2015
## cMIPS, Roberto Hexsel, 30set2013, rev 08jan2015, 04apr2017
## ------------------------------------------------------------------------
# set -x
......@@ -19,6 +19,7 @@ EOF
exit 1
}
errorCOMPILING()
{
cat <<EOF
......@@ -33,6 +34,38 @@ exit 1
}
usage()
{
cat << EOF
usage: $0 [options]
creates VHDL simulator
OPTIONS:
-h Show this message
-syn Compile for Macnica's board, else for simulation
-x turn on "set -x"
EOF
}
synth=false
while true ; do
case "$1" in
-h) usage ; exit 1
;;
-mif | -syn ) synth=true
;;
-x) set -x
;;
*) break ; #usage
# echo " invalid option: $1"; exit 1
;;
esac
shift
done
if [ ! -v tree ] ; then
# you must set the location of the cMIPS root directory in the variable tree
......@@ -45,13 +78,20 @@ fi
bin="${tree}"/bin
include="${tree}"/include
srcVHDL="${tree}"/vhdl
# obj="${tree}"/obj
c_ld="${include}"/cMIPS.ld
c_s="${include}"/cMIPS.s
c_h="${include}"/cMIPS.h
pkg_vhd="$srcVHDL/packageMemory.vhd"
if [ $synth = tree ] ; then
pkg_vhd="$srcVHDL/packageMemory_fpga.vhd"
(cd $srcVHDL ; ln -s -f packageMemory_fpga.vhd packageMemory.vhd)
else
pkg_vhd="$srcVHDL/packageMemory_simu.vhd"
(cd $srcVHDL ; ln -s -f packageMemory_simu.vhd packageMemory.vhd)
fi
if [ $pkg_vhd -nt $c_ld -o\
$pkg_vhd -nt $c_s -o\
......@@ -67,7 +107,7 @@ simulator=tb_cmips
pkg="packageWires.vhd packageMemory.vhd packageExcp.vhd"
src="aux.vhd altera.vhd macnica.vhd cache.vhd instrcache.vhd sdram.vhd ram.vhd rom.vhd units.vhd io.vhd uart.vhd fpu.vhd pipestages.vhd exception.vhd core.vhd tb_cMIPS.vhd"
src="aux.vhd altera.vhd macnica.vhd cache.vhd instrcache.vhd sdram.vhd ram.vhd rom.vhd units.vhd SDcard.vhd io.vhd uart.vhd fpu.vhd pipestages.vhd exception.vhd core.vhd tb_cMIPS.vhd"
# build simulator
#ghdl --clean
......
......@@ -118,14 +118,14 @@ if [ $synth = true ]; then
S="-D FOR_SYNTHESIS" ;
c_start="${include}"/syn_start
c_hndlrs="${include}"/syn_handlers
touch $pkg_vhd -r ${srcVHDL}/packageMemory_fpga.vhd
touch $pkg_vhd
pkg_vhd="${srcVHDL}"/packageMemory_fpga.vhd
(cd $srcVHDL ; ln -s -f packageMemory_fpga.vhd packageMemory.vhd)
else
S="-U FOR_SYNTHESIS" ;
c_start="${include}"/start
c_hndlrs="${include}"/handlers
touch $pkg_vhd -r ${srcVHDL}/packageMemory_simu.vhd
touch $pkg_vhd
pkg_vhd="${srcVHDL}"/packageMemory_simu.vhd
(cd $srcVHDL ; ln -s -f packageMemory_simu.vhd packageMemory.vhd)
fi
if [ $pkg_vhd -nt $c_h -o\
......
......@@ -9,14 +9,12 @@
extern int _counter_val;
int conv1(int);
#define FALSE (0==1)
#define TRUE !FALSE
#define QUARTER 12500000
int main(void) {
void main(void) {
int i, j, k;
volatile int old_val;
int sec, min, hour;
......@@ -49,17 +47,25 @@ int main(void) {
old_val = _counter_val;
enableInterr();
// enableInterr();
startCounter(QUARTER,TRUE); // counter will interrupt after 1/4 second
sec = min = hour = 0;
i = 0;
if (SWget() != 0) {
LCDprint( print_status() ); // for debugging only
delay_ms(2000);
LCDprint( print_cause() ); // for debugging only
delay_ms(2000);
}
while (TRUE) {
while (old_val == _counter_val) { // busy wait for interrupt
delay_us(i); // that's really stupid but we have nothing else to do
delay_us(1); // that's really stupid but we have nothing else to do
}
old_val = _counter_val;
......@@ -118,42 +124,6 @@ int main(void) {
}
return 0;
}
int conv1(int c) {
int i;
switch(c) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
i = c + 0x30; ; break;
case 10:
i = 'a'; break;
case 11:
i = 'b'; break;
case 12:
i = 'c'; break;
case 13:
i = 'd'; break;
case 14:
i = 'e'; break;
case 15:
i = 'f'; break;
default:
i = '*';
}
return(i);
}
This diff is collapsed.
......@@ -347,7 +347,7 @@ begin
i_ena <= data_inp(31) when (sel='0' and wr='0') else int_en;
U_INTERR_EN: FFDsimple port map (clk, rst, i_ena, int_en);
equals <= '1' when (Q = Qlimit) else '0';
equals <= '1' when (Q = Qlimit(NUM_BITS-1 downto 0) ) else '0';
irq <= '1' when (equals = '1' and int_en = '1') else '0';
......@@ -359,7 +359,7 @@ end behavioral;
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- peripheral: simple UART
-- peripheral: simple UART bus interface (a wrapper to the real UART)
-- 8 data bits, no parity, 1 stop bit (8N1), catches: framing, overrun
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
library IEEE;
......@@ -938,3 +938,166 @@ begin
end behavioral;
-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- peripheral: SDcard bus interface (a wrapper to the SDcard controller)
-- base + b"0000" -> address register
-- base + b"0100" -> data registers (RD/WR)
-- base + b"1100" -> status register: busy(31) & "0..0" & error(15..0)
--
-- Software must ALWAYS check status(31) = busy before reading/writing
-- to controller. If controller is busy, check for errors. In case of
-- errors, reset controller by writing 0s into status register.
-- Wait states (rdy=0) are inserted as needed by the bus interface.
--++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
library IEEE;
use IEEE.std_logic_1164.all;
use work.p_wires.all;
use work.SdCardPckg.all;
entity SDcard is
port (rst : in std_logic;
clk : in std_logic;
sel : in std_logic;
rdy : out std_logic;
wr : in std_logic;
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)
end SDCard;
architecture behavioral of SDcard is
component wait_states is
generic (NUM_WAIT_STATES :integer);
port(rst : in std_logic;
clk : in std_logic;
sel : in std_logic; -- active in '0'
waiting : out std_logic); -- active in '1'
end component wait_states;
component registerN is
generic (NUM_BITS: integer; INIT_VAL: std_logic_vector);
port(clk, rst, ld: in std_logic;
D: in std_logic_vector;
Q: out std_logic_vector);
end component registerN;
component FFD is
port(clk, rst, set, D : in std_logic; Q : out std_logic);
end component FFD;
component FFDsimple is
port(clk, rst, D : in std_logic; Q : out std_logic);
end component FFDsimple;
component HandshakeIntfc is
port (ctrl_i : in std_logic; -- Control signal from source.
ctrl_o : out std_logic; -- Control signal to the destination.
done_i : in std_logic; -- Op done signal from the destination.
done_o : out std_logic); -- Op done signal to the source.
end component HandshakeIntfc;
component SdCardCtrl is
generic (
FREQ_G : real; -- Master clock frequency (MHz).
INIT_SPI_FREQ_G : real; -- Slow SPI clock freq during init (MHz).
SPI_FREQ_G : real; -- Operational SPI freq. to the SD card (MHz).
BLOCK_SIZE_G : natural; -- Num bytes in an SD card block or sector.
CARD_TYPE_G : CardType_t); -- Type of SD card connected.
port (
-- Host-side interface signals.
clk_i : in std_logic; -- Master clock.
reset_i : in std_logic; -- active-high, synchronous reset.
rd_i : in std_logic; -- active-high read block request.
wr_i : in std_logic; -- active-high write block request.
continue_i : in std_logic; -- If true, inc address and continue R/W.
addr_i : in std_logic_vector; -- Block address.
data_i : in std_logic_vector; -- Data to write to block.
data_o : out std_logic_vector; -- Data read from block.
busy_o : out std_logic; -- High when controller is busy.
hndShk_i : in std_logic; -- High when host has new or has taken data.
hndShk_o : out std_logic; -- High when cntlr has taken or new data.
error_o : out std_logic_vector;
-- I/O signals to the external SD card.
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.
end component SdCardCtrl;
signal s_addr, s_stat, s_read, s_write, s_reset, sdc_rst : std_logic;
signal continue, busy, hndShk_i, hndShk_o : std_logic;
signal wait1, wait2, waiting, new_trans : std_logic;
signal data_rd, data_rd_reg, data_wr_reg : reg8;
signal error_o : reg16;
signal addr_reg : reg32;
begin
U_SDcard: SdCardCtrl
generic map (50.0, 0.400, 25.0, 512, SD_CARD_E)
port map (clk, sdc_rst, s_read, s_write, '0', addr_reg,
data_wr_reg, data_rd, busy, hndshk_i, hndshk_o, error_o,
sdc_cs, sdc_clk, sdc_mosi_o, sdc_mosi_i);
-- ctrl_i _____/--------------------------\_____ (From source...)
-- ctrl_o _____/--------------\_________________ (to destination.)
-- done_i ____________________/--\______________ (From destination...)
-- done_o ____________________/-----------\_____ (to source.)
-- port (ctrl_i, ctrl_o, done_i, done_o);
U_HANDSHAKE: HandshakeIntfc
port map (new_trans, hndshk_i, hndshk_o, waiting);
-- a3a2 wr register (aligned to word addresses (a1a0=00)
-- 00 0 write to ADDR register (32 bits)
-- 00 1 no effect, returns current value of ADDR
-- 01 1 read from data register (8 bits, least significant byte)
-- 01 0 write to data register (8 bits, least significant byte)
-- 10 X no effect
-- 11 0 reset the SDcard constroller (write to status, value ignored)
-- 11 1 read status register
s_addr <= '0' when sel = '0' and addr = b"00" and wr = '0' else '1';
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_stat <= '1' when sel = '0' and addr = b"11" and wr = '1' else '0';
s_reset <= '1' when sel = '0' and addr = b"11" and wr = '0' else '0';
sdc_rst <= not(rst) or s_reset;
U_ADDR_REG: registerN generic map (32, x"00000000")
port map (clk, rst, s_addr, data_inp, addr_reg);
U_WRITE_REG: registerN generic map (8, x"00")
port map (clk, rst, s_write, data_inp(7 downto 0), data_wr_reg);
U_READ_REG: registerN generic map (8, x"00")
port map (clk, rst, s_read, data_rd, data_rd_reg);
new_trans <= not(s_write) or not(s_read);
U_WAIT1: component wait_states generic map (1)
port map (rst, clk, new_trans, wait1);
U_WAIT2: FFDsimple port map (clk, rst, wait1, wait2);
rdy <= not(wait1 or wait2 or waiting); -- wait for 260ns
data_out <= x"000000" & data_rd_reg when s_read = '1' else
busy & b"000" & x"000" & error_o;
end behavioral;
-- ++ simple uart +++++++++++++++++++++++++++++++++++++++++++++++++++++++
......@@ -90,6 +90,7 @@ package p_MEMORY is
constant IO_DSP7SEG_ADDR : integer := IO_BASE_ADDR + 9*IO_ADDR_RANGE;
constant IO_KEYBD_ADDR : integer := IO_BASE_ADDR + 10*IO_ADDR_RANGE;
constant IO_LCD_ADDR : integer := IO_BASE_ADDR + 11*IO_ADDR_RANGE;
constant IO_SDC_ADDR : integer := IO_BASE_ADDR + 12*IO_ADDR_RANGE;
constant IO_HIGHEST_ADDR : integer :=
IO_BASE_ADDR + (IO_MAX_NUM_DEVS - 1)*IO_ADDR_RANGE;
......
......@@ -90,6 +90,7 @@ package p_MEMORY is
constant IO_DSP7SEG_ADDR : integer := IO_BASE_ADDR + 9*IO_ADDR_RANGE;
constant IO_KEYBD_ADDR : integer := IO_BASE_ADDR + 10*IO_ADDR_RANGE;
constant IO_LCD_ADDR : integer := IO_BASE_ADDR + 11*IO_ADDR_RANGE;
constant IO_SDC_ADDR : integer := IO_BASE_ADDR + 12*IO_ADDR_RANGE;
constant IO_HIGHEST_ADDR : integer :=
IO_BASE_ADDR + (IO_MAX_NUM_DEVS - 1)*IO_ADDR_RANGE;
......
......@@ -35,6 +35,22 @@ architecture TB of tb_cMIPS is
port(clk, rst, set, D : in std_logic; Q : out std_logic);
end component FFD;
component SDcard is
port (rst : in std_logic;
clk : in std_logic;
sel : in std_logic;
rdy : out std_logic;
wr : in std_logic;
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)
irq : out std_logic); -- interrupt request (not yet used)
end component SDCard;
component LCD_display is
port (rst : in std_logic;
clk : in std_logic;
......@@ -216,6 +232,7 @@ architecture TB of tb_cMIPS is
dsp7seg_sel : out std_logic;
keybd_sel : out std_logic;
lcd_sel : out std_logic;
sdc_sel : out std_logic;
not_waiting : in std_logic);
end component io_addr_decode;
......@@ -433,9 +450,10 @@ architecture TB of tb_cMIPS is
signal io_keys_sel : std_logic := '1';
signal io_fpu_sel, io_fpu_wait : std_logic := '1';
signal io_lcd_sel, io_lcd_wait : std_logic := '1';
signal io_sdc_sel, io_sdc_wait : std_logic := '1';
signal d_cache_d_out, stdin_d_out, read_d_out, counter_d_out : reg32;
signal fpu_d_out, uart_d_out, sstats_d_out, keybd_d_out : reg32;
signal lcd_d_out, sdram_d_out : reg32;
signal lcd_d_out, sdc_d_out, sdram_d_out : reg32;
signal counter_irq : std_logic;
signal io_wait, not_waiting : std_logic;
......@@ -459,7 +477,9 @@ 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 sdcke, sdscs, sdras, sdcas, sdwe : std_logic; -- SDRAM
signal sddqm0, sddqm1, sdba0, sdba1 : std_logic;
signal sdaddr : reg12;
......@@ -543,7 +563,7 @@ begin -- TB
io_print_sel, io_stdout_sel, io_stdin_sel,io_read_sel,
io_write_sel, io_counter_sel, io_fpu_sel, io_uart_sel,
io_sstats_sel, io_7seg_sel, io_keys_sel, io_lcd_sel,
not_waiting);
io_sdc_sel, not_waiting);
U_DATA_ADDR_DEC: ram_addr_decode
port map (rst, cpu_d_aVal, d_addr,data_aVal, dev_select_ram);
......@@ -560,9 +580,10 @@ begin -- TB
counter_d_out when b"0111",
fpu_d_out when b"1000",
uart_d_out when b"1001",
sstats_d_out when b"1010",
-- sstats_d_out when b"1010",
keybd_d_out when b"1100",
lcd_d_out when b"1101",
sdc_d_out when b"1110",
-- sdram_d_out when b"1110",
(others => 'X') when others;
......@@ -635,6 +656,11 @@ begin -- TB
U_uart_remota: remota generic map ("serial.out","serial.inp")
port map (rst, clk, uart_rts, uart_txd, uart_rxd, bit_rt);
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);
U_FPU: FPU
port map (rst,clk, io_FPU_sel, io_FPU_wait, wr, d_addr(5 downto 2),
cpu_data, fpu_d_out);
......@@ -919,7 +945,8 @@ entity io_addr_decode is -- CPU side triggers access
SSTATS_sel : out std_logic; -- system statistics (act=0)
dsp7seg_sel : out std_logic; -- 7 segments display (act=0)
keybd_sel : out std_logic; -- telephone keyboard (act=0)
lcd_sel : out std_logic; -- telephone keyboard (act=0)
lcd_sel : out std_logic; -- LCD 2x16 char display (act=0)
sdc_sel : out std_logic; -- SDcard reader/writer (act=0)
not_waiting : in std_logic); -- no other device is waiting
end entity io_addr_decode;
......@@ -974,6 +1001,7 @@ begin
constant is_dsp7seg : integer := 11;
constant is_keybd : integer := 12;
constant is_lcd : integer := 13;
constant is_sdc : integer := 14;
begin
print_sel <= '1';
......@@ -988,6 +1016,7 @@ begin
dsp7seg_sel <= '1';
keybd_sel <= '1';
lcd_sel <= '1';
sdc_sel <= '1';
case dev is -- to_integer(signed(addr(HI_ADDR downto LO_ADDR))) is
when 0 => dev_sel := std_logic_vector(to_signed(is_print, 4));
......@@ -1014,9 +1043,11 @@ begin
keybd_sel <= aVal;
when 11 => dev_sel := std_logic_vector(to_signed(is_lcd, 4));
lcd_sel <= aVal;
when 12 => dev_sel := std_logic_vector(to_signed(is_sdc, 4));
sdc_sel <= aVal;
when others => dev_sel := std_logic_vector(to_signed(is_noise, 4));
end case;
-- assert false report "IO_addr "& SLV32HEX(addr);--DEBUG
assert TRUE report "IO_addr "& SLV32HEX(addr); -- DEBUG
if aVal = '0' then
dev_select <= dev_sel;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment