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

Subversion Repositories amber

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 34 to Rev 35
    Reverse comparison

Rev 34 → Rev 35

/amber/trunk/doc/ReleaseChecklist.txt
0,0 → 1,7
1. Run all tests using both A23 and A25 using all cache size configurations.
2. Synthesise both a23 and a25 cores.
Both cores must pass timing; Spartan6 at 40MHz, Virtex6 at 80Mhz, with max caches
Check all synthesis warnings, clean up as many as possible.
 
 
/amber/trunk/sw/include/amber_macros.h
0,0 → 1,50
/*----------------------------------------------------------------
// //
// amber_macros .h //
// //
// This file is part of the Amber project //
// http://www.opencores.org/project,amber //
// //
// Description //
// //
// Author(s): //
// - Conor Santifort, csantifort.amber@gmail.com //
// //
//////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2010 Authors and OPENCORES.ORG //
// //
// This source file may be used and distributed without //
// restriction provided that this copyright statement is not //
// removed from the file and that any derivative work contains //
// the original copyright notice and the associated disclaimer. //
// //
// This source file is free software; you can redistribute it //
// and/or modify it under the terms of the GNU Lesser General //
// Public License as published by the Free Software Foundation; //
// either version 2.1 of the License, or (at your option) any //
// later version. //
// //
// This source is distributed in the hope that it will be //
// useful, but WITHOUT ANY WARRANTY; without even the implied //
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
// PURPOSE. See the GNU Lesser General Public License for more //
// details. //
// //
// You should have received a copy of the GNU Lesser General //
// Public License along with this source; if not, download it //
// from http://www.opencores.org/lgpl.shtml //
// //
----------------------------------------------------------------*/
 
.macro expect, reg1, value, err_no
cmp \reg1, #\value
movne r10, #\err_no
bne testfail
.endm
 
.macro compare, reg1, reg2, err_no
cmp \reg1, \reg2
movne r10, #\err_no
bne testfail
.endm
/amber/trunk/sw/boot-loader/fpga-version.h
1,0 → 1,50
#define AMBER_FPGA_VERSION "20110202130047"
#define AMBER_FPGA_VERSION "20091027145749"
/amber/trunk/hw/tools/run.sh
55,6 → 55,8
SET_A=0
SET_5=0
SET_L=0
SET_NC=0 # no compile
SET_TO=0 # override timeout
 
 
# show program usage
67,7 → 69,9
echo " -d <cycle number to start dumping>: Create vcd file"
echo " -t <cycle number to start dumping>: Create vcd file and terminate"
echo " -l : Create wlf dump of complete design"
echo " -nc: Do not re-compile the Verilog. Starts the simulation more quickly"
echo " -s : Use Xilinx Spatran6 Libraries (slower sim)"
echo " -to: Ignore timeout limit for this test"
echo " -v : Use Xilinx Virtex6 Libraries (slower sim)"
echo " -5 : Use Amber25 core instead of Amber23 core"
echo ""
83,7 → 87,7
 
# show usage if '-h' or '--help' is the first argument or no argument is given
case $1 in
""|"-h"|"--help") show_usage ;;
""|"-h"|"--help"|"help"|"?") show_usage ;;
esac
 
# get the number of command-line arguments given
105,23 → 109,28
case $1 in
-a) SET_A=1 # all tests
shift ;;
-s) SET_S=1 # Xilinx libs
-s) SET_S=1 # Xilinx Spartan6 libs
shift ;;
-v) SET_V=1 # Xilinx libs
-v) SET_V=1 # Xilinx Virtex6 libs
shift ;;
-5) SET_5=1 # Xilinx libs
-5) SET_5=1 # Amber25 core (default is Amber23 core)
shift ;;
-g) SET_G=1 # Bring up GUI
shift ;;
-l) SET_L=1 # Create wlf wave dump file
shift ;;
-d) SET_D=1
DUMP_START=$2
-nc) SET_NC=1 # Don't recompile the Verilog
shift ;;
-to) SET_TO=1 # Override timeout value in timeout file
AMBER_TIMEOUT=$2 # New timeout value
shift 2;;
-d) SET_D=1 # Enable VCD dump
DUMP_START=$2 # Clock cycle to start dumping
shift 2;;
-t) SET_D=1
SET_T=1
DUMP_START=$2
-t) SET_D=1 # Enable VCD dump
SET_T=1 # Terminate test after vcd dump completes
DUMP_START=$2 # Clock cycle to start dumping
shift 2;;
-*)
236,13 → 245,18
# hw assembly test
echo "Compile ../tests/${AMBER_TEST_NAME}.S"
pushd ../tests > /dev/null
make TEST=${AMBER_TEST_NAME}
make --quiet TEST=${AMBER_TEST_NAME}
MAKE_STATUS=$?
if [ $SET_NC == 1 ]; then
rm add.mem
ln -s ${AMBER_TEST_NAME}.mem add.mem
fi
popd > /dev/null
BOOT_MEM_FILE="../tests/${AMBER_TEST_NAME}.mem"
BOOT_MEM_PARAMS_FILE="../tests/${AMBER_TEST_NAME}_memparams.v"
# Get timeout
AMBER_TIMEOUT=`../tools/get_timeout.sh ${AMBER_TEST_NAME}`
elif [ $TEST_TYPE == 2 ]; then
# sw Stand-alone C test
pushd ../../sw/${AMBER_TEST_NAME} > /dev/null
279,56 → 293,65
echo "Error unrecognized test type"
fi
 
if [ $MAKE_STATUS != 0 ]; then
echo "Failed " $AMBER_TEST_NAME " compile error" >> $AMBER_LOG_FILE
exit
fi
 
 
# Set timeout and testname in the .mem file
if [ $SET_TO == 0 ]; then
AMBER_TIMEOUT=`../tools/get_timeout.sh ${AMBER_TEST_NAME}`
fi
printf '@00001fec %08x\n' $AMBER_TIMEOUT >> ${BOOT_MEM_FILE}
echo ${AMBER_TEST_NAME} | ../../sw/tools/amber-ascii-mem 1ff0 >> ${BOOT_MEM_FILE}
 
 
#--------------------------------------------------------
# Modelsim
#--------------------------------------------------------
if [ $MAKE_STATUS == 0 ]; then
if [ ! -d work ]; then
vlib work
fi
if [ ! -d work ]; then
vlib work
if [ $? != 0 ]; then exit; fi
fi
 
if [ $? == 0 ]; then
vlog +libext+.v \
+incdir+../vlog/amber23+../vlog/amber25+../vlog/system+../vlog/tb+../vlog/ethmac \
+incdir+../vlog/lib+../vlog/xs6_ddr3+../vlog/xv6_ddr3 \
-y ../vlog/amber23 -y ../vlog/amber25 -y ../vlog/system -y ../vlog/tb -y ../vlog/ethmac \
-y ../vlog/lib -y ../vlog/xs6_ddr3 -y ../vlog/xv6_ddr3 \
-y $XILINX/verilog/src/unisims \
-y $XILINX/verilog/src \
../vlog/tb/tb.v \
$XILINX/verilog/src/glbl.v \
+define+BOOT_MEM_FILE=\"$BOOT_MEM_FILE\" \
+define+BOOT_MEM_PARAMS_FILE=\"$BOOT_MEM_PARAMS_FILE\" \
+define+MAIN_MEM_FILE=\"$MAIN_MEM_FILE\" \
+define+AMBER_LOG_FILE=\"$AMBER_LOG_FILE\" \
+define+AMBER_TEST_NAME=\"$AMBER_TEST_NAME\" \
+define+AMBER_SIM_CTRL=$TEST_TYPE \
+define+AMBER_TIMEOUT=$AMBER_TIMEOUT \
${FPGA} \
$AMBER_CORE \
$AMBER_DUMP_VCD \
$AMBER_TERMINATE \
$AMBER_LOAD_MAIN_MEM
if [ $? == 0 ]; then
vsim -voptargs="+acc=rnpc" tb ${RUN_OPTIONS}
# Set a timeout value for the test if it passed
if [ $TEST_TYPE == 1 ]; then
tail -1 < ${AMBER_LOG_FILE} | grep Passed > /dev/null
if [ $? == 0 ]; then
TICKS=`tail -1 < ${AMBER_LOG_FILE} | awk '{print $3}'`
TOTICKS=$(( $TICKS * 4 + 1000 ))
../tools/set_timeout.sh ${AMBER_TEST_NAME} $TOTICKS
fi
fi
fi
fi
 
else
echo "Failed " $AMBER_TEST_NAME " compile error" >> $AMBER_LOG_FILE
if [ $SET_NC == 0 ]; then
vlog +libext+.v \
+incdir+../vlog/amber23+../vlog/amber25+../vlog/system+../vlog/tb+../vlog/ethmac \
+incdir+../vlog/lib+../vlog/xs6_ddr3+../vlog/xv6_ddr3 \
-y ../vlog/amber23 -y ../vlog/amber25 -y ../vlog/system -y ../vlog/tb -y ../vlog/ethmac \
-y ../vlog/lib -y ../vlog/xs6_ddr3 -y ../vlog/xv6_ddr3 \
-y $XILINX/verilog/src/unisims \
-y $XILINX/verilog/src \
../vlog/tb/tb.v \
$XILINX/verilog/src/glbl.v \
+define+BOOT_MEM_FILE=\"$BOOT_MEM_FILE\" \
+define+BOOT_MEM_PARAMS_FILE=\"$BOOT_MEM_PARAMS_FILE\" \
+define+MAIN_MEM_FILE=\"$MAIN_MEM_FILE\" \
+define+AMBER_LOG_FILE=\"$AMBER_LOG_FILE\" \
+define+AMBER_TEST_NAME=\"$AMBER_TEST_NAME\" \
+define+AMBER_SIM_CTRL=$TEST_TYPE \
+define+AMBER_TIMEOUT=$AMBER_TIMEOUT \
${FPGA} \
$AMBER_CORE \
$AMBER_DUMP_VCD \
$AMBER_TERMINATE \
$AMBER_LOAD_MAIN_MEM
if [ $? != 0 ]; then exit; fi
fi
vsim -voptargs="+acc=rnpc" tb ${RUN_OPTIONS}
if [ $? != 0 ]; then exit; fi
# Set a timeout value for the test if it passed
if [ $TEST_TYPE == 1 ]; then
tail -1 < ${AMBER_LOG_FILE} | grep Passed > /dev/null
if [ $? == 0 ]; then
TICKS=`tail -1 < ${AMBER_LOG_FILE} | awk '{print $3}'`
TOTICKS=$(( $TICKS * 4 + 1000 ))
../tools/set_timeout.sh ${AMBER_TEST_NAME} $TOTICKS
fi
fi
 
 
 
/amber/trunk/hw/tests/cache1.S
67,11 → 67,11
add r5, r5, #9
subs r3, r3, #1
bne loop
 
continue:
@ setup loop2
ldr r9, WriteLocation
mov r3, #9
mov r8, #4
loop2:
 
mov r6, #0
607,6 → 607,8
add r6, r6,#8
add r6, r6,#8
 
str r3, [r9]
add r6, r6,#9
add r6, r6,#9
add r6, r6,#9
803,9 → 805,9
/* Write 17 to this address to generate a Test Passed message */
AdrTestStatus: .word ADR_AMBER_TEST_STATUS
Result: .word 3300
WriteLocation: .word 0xffc
 
 
 
/* ========================================================================= */
/* ========================================================================= */
/amber/trunk/hw/tests/cache2.S
6,7 → 6,7
// http://www.opencores.org/project,amber //
// //
// Description //
// Tests simple interactin between cached data and uncached //
// Tests simple interaction between cached data and uncached //
// instruction accesses. //
// //
// Author(s): //
/amber/trunk/hw/tests/timeouts.txt
1,60 → 1,60
flow4 3936
tmp 3376
add 1704
adc 1368
sub 1500
sbc 2484
barrel_shift 1524
barrel_shift_rs 1368
change_sbits 2184
change_mode 1656
bl 1548
bcc 1188
ldr 4000
ldr_str_pc 1564
strb 2120
ldm1 2544
tmp 2756
add 1716
adc 1440
sub 1536
sbc 2676
barrel_shift 1536
barrel_shift_rs 1380
change_sbits 2232
change_mode 1680
bl 1572
bcc 1200
ldr 4276
ldr_str_pc 1576
strb 2300
ldm1 2556
ldm2 2016
ldm3 1832
ldm4 1820
stm1 7024
stm2 2296
ldm_stm_onetwo 4748
stm_stream 49188
mul 177660
mla 365076
swp 2004
irq 97644
firq 28764
swi 1596
undefined_ins 2616
addr_ex 1724
irq_stm 9812
cache1 16296
cache2 1456
cache3 98884
cache_swap 66196
cacheable_area 5580
cache_flush 17572
flow1 2972
flow2 4800
flow3 3292
hiboot_mem 1376
ddr31 96676
ddr32 193584
ddr33 20820
ethmac_reg 4596
ethmac_mem 75708
ethmac_tx 16692
uart_reg 1800
uart_tx 137764
uart_rx 132024
uart_rxint 125032
bic_bug 1512
movs_bug 1532
flow_bug 1428
mlas_bug 1948
inflate_bug 1360
swp_lock_bug 1320
cache_swap_bug 29504
conflict_rd 2552
ldm4 1808
stm1 7012
stm2 2332
ldm_stm_onetwo 5284
stm_stream 52924
mul 180768
mla 383544
swp 2040
irq 101116
firq 29568
swi 1620
undefined_ins 2676
addr_ex 1772
irq_stm 12332
cache1 16408
cache2 1484
cache3 122460
cache_swap 85704
cacheable_area 6348
cache_flush 19460
flow1 3072
flow2 5748
flow3 3396
conflict_rd 2832
hiboot_mem 1436
ddr31 99868
ddr32 205836
ddr33 24684
ethmac_reg 4740
ethmac_mem 79896
ethmac_tx 20364
uart_reg 2028
uart_tx 134116
uart_rx 132420
uart_rxint 127120
bic_bug 1524
movs_bug 1616
flow_bug 1452
mlas_bug 1972
inflate_bug 1408
swp_lock_bug 1356
cache_swap_bug 32656
/amber/trunk/hw/tests/flow1.S
67,7 → 67,7
ldm r0, {r1-r5}
@ second stm will be to cached memory
stm r13, {r1-r5}
@ load it back from the cache to check thaat
@ load it back from the cache to check that
@ it was written to the cache correctly
ldm r13, {r6-r10}
cmp r1, r6
/amber/trunk/hw/tests/irq_stm.S
43,6 → 43,7
*****************************************************************/
 
#include "amber_registers.h"
#include "amber_macros.h"
 
.section .text
.globl main
130,9 → 131,7
@ sure it decrements correctly on each
@ iteration of the loop
sub r13, r13, #16
cmp r7, r13
movne r10, #100
bne testfail
compare r7, r13, __LINE__
subs r2, r2, #1
beq testpass
/amber/trunk/hw/tests/adc.S
39,6 → 39,7
*****************************************************************/
 
#include "amber_registers.h"
#include "amber_macros.h"
 
.section .text
.globl main
55,16 → 56,11
@ check that overflow flag has been set
mov r5, pc
and r5, r5, #0xf0000000 @ clear non-flag bits
cmp r5, #0x90000000 @ negative and overflow flags set
movne r10, #10
bne testfail
expect r5, 0x90000000, __LINE__
@ check the result
cmp r8, r4
movne r10, #20
bne testfail
@ fail if r4 not equal to r8
compare r8, r4, __LINE__
b testpass
/amber/trunk/hw/tests/add.S
39,6 → 39,7
*****************************************************************/
 
#include "amber_registers.h"
#include "amber_macros.h"
 
.section .text
.globl main
48,49 → 49,37
mov r1, #3
mov r2, #1
add r3, r1, r2
cmp r3, #4
movne r10, #10
bne testfail
expect r3, 4, __LINE__
/* 0 + 0 */
mov r4, #0
mov r5, #0
add r6, r5, r4
cmp r6, #0
movne r10, #20
bne testfail
expect r6, 0, __LINE__
/* 0 + -1 */
mov r7, #0
mov r8, #-1
add r9, r7, r8
cmp r9, #-1
movne r10, #30
bne testfail
expect r9, -1, __LINE__
/* -1 + 0 */
mov r1, #-1
mov r2, #0
add r3, r1, r2
cmp r3, #-1
movne r10, #40
bne testfail
expect r3, -1, __LINE__
/* -1 + -1 */
mov r4, #-1
mov r5, #-1
add r6, r4, r5
cmp r6, #-2
movne r10, #50
bne testfail
expect r6, -2, __LINE__
 
/* -1 + -255 */
mov r7, #-1
mov r8, #-255
add r9, r7, r8
cmp r9, #-256
movne r10, #60
bne testfail
expect r9, -256, __LINE__
 
/* 1 + 0x7fffffff */
ldr r1, MaxPos
100,9 → 89,8
/* so if the V flag is Clear then fail */
bvc testfail
ldr r0, MaxNeg
cmp r0, r3
movne r10, #70
bne testfail
compare r0, r3, __LINE__
 
b testpass
 
testfail:
/amber/trunk/hw/tests/ethmac_tx.S
86,6 → 86,23
str r1, [r0]
 
 
/* Check register values */
ldr r0, AdrEthMacModer
ldr r1, EthMacModerValue
ldr r2, [r0]
cmp r1, r2
movne r10, #200
bne testfail
ldr r0, AdrEthMacMemBase
ldr r1, TxBufferW0
orr r1, r1, #0x8000
ldr r2, [r0]
cmp r1, r2
movne r10, #220
bne testfail
 
/* Wait until receive complete - Wait for Empty bit to go low */
2: ldr r1, [r0, #0x200]
ands r1, r1, #0x8000
92,7 → 109,7
bne 2b
 
/* Wait a bit */
mov r0, #20
mov r0, #80
3: subs r0, r0, #1
bne 3b
161,10 → 178,10
/* [31:16] = length in bytes, Bit[15] = empty, Bit [13] = wrap bit */
RxBufferW0: .word 0x0000a800
 
/* Buffer Pointer */
TxBufferW1: .word 0x28001000
RxBufferW1: .word 0x28001200
 
/* Buffer Pointer in Main Memory */
TxBufferW1: .word 0x00011000
RxBufferW1: .word 0x00011200
 
 
/*
/amber/trunk/hw/vlog/system/uart.v
58,14 → 58,17
`define AMBER_UART_BAUD 230400
`endif
 
module uart (
module uart #(
parameter WB_DWIDTH = 32,
parameter WB_SWIDTH = 4
)(
input i_clk,
 
input [31:0] i_wb_adr,
input [3:0] i_wb_sel,
input [WB_SWIDTH-1:0] i_wb_sel,
input i_wb_we,
output [31:0] o_wb_dat,
input [31:0] i_wb_dat,
output [WB_DWIDTH-1:0] o_wb_dat,
input [WB_DWIDTH-1:0] i_wb_dat,
input i_wb_cyc,
input i_wb_stb,
output o_wb_ack,
206,10 → 209,11
reg [7:0] uart_cr_reg = 'd0; // Control Register
 
// Wishbone interface
reg [31:0] wb_rdata = 'd0;
reg [31:0] wb_rdata32 = 'd0;
wire wb_start_write;
wire wb_start_read;
reg wb_start_read_d1 = 'd0;
wire [31:0] wb_wdata32;
 
integer i;
 
219,17 → 223,32
 
// Can't start a write while a read is completing. The ack for the read cycle
// needs to be sent first
assign wb_start_write = i_wb_stb && i_wb_we && !wb_start_read_d1;
assign wb_start_write = i_wb_stb && i_wb_we && !wb_start_read_d1;
assign wb_start_read = i_wb_stb && !i_wb_we && !o_wb_ack;
 
always @( posedge i_clk )
wb_start_read_d1 <= wb_start_read;
 
assign o_wb_dat = wb_rdata;
 
assign o_wb_err = 1'd0;
assign o_wb_ack = i_wb_stb && ( wb_start_write || wb_start_read_d1 );
 
generate
if (WB_DWIDTH == 128)
begin : wb128
assign wb_wdata32 = i_wb_adr[3:2] == 2'd3 ? i_wb_dat[127:96] :
i_wb_adr[3:2] == 2'd2 ? i_wb_dat[ 95:64] :
i_wb_adr[3:2] == 2'd1 ? i_wb_dat[ 63:32] :
i_wb_dat[ 31: 0] ;
assign o_wb_dat = {4{wb_rdata32}};
end
else
begin : wb32
assign wb_wdata32 = i_wb_dat;
assign o_wb_dat = wb_rdata32;
end
endgenerate
 
// ======================================================
// UART 0 Receive FIFO
358,7 → 377,7
// Push
if ( tx_fifo_push_not_full )
begin
tx_fifo[tx_fifo_wp[3:0]] <= i_wb_dat[7:0];
tx_fifo[tx_fifo_wp[3:0]] <= wb_wdata32[7:0];
tx_fifo_wp <= tx_fifo_wp + 1'd1;
end
387,7 → 406,7
// Push
if ( tx_fifo_push_not_full )
begin
tx_fifo[0] <= i_wb_dat[7:0];
tx_fifo[0] <= wb_wdata32[7:0];
tx_fifo_full_flag <= 1'd1;
end
// Pop
702,15 → 721,15
if ( wb_start_write )
case ( i_wb_adr[15:0] )
// Receive status, (Write) Error Clear
AMBER_UART_RSR: uart_rsr_reg <= i_wb_dat[7:0];
AMBER_UART_RSR: uart_rsr_reg <= wb_wdata32[7:0];
// Line Control High Byte
AMBER_UART_LCRH: uart_lcrh_reg <= i_wb_dat[7:0];
AMBER_UART_LCRH: uart_lcrh_reg <= wb_wdata32[7:0];
// Line Control Middle Byte
AMBER_UART_LCRM: uart_lcrm_reg <= i_wb_dat[7:0];
AMBER_UART_LCRM: uart_lcrm_reg <= wb_wdata32[7:0];
// Line Control Low Byte
AMBER_UART_LCRL: uart_lcrl_reg <= i_wb_dat[7:0];
AMBER_UART_LCRL: uart_lcrl_reg <= wb_wdata32[7:0];
// Control Register
AMBER_UART_CR: uart_cr_reg <= i_wb_dat[7:0];
AMBER_UART_CR: uart_cr_reg <= wb_wdata32[7:0];
endcase
 
 
721,29 → 740,29
if ( wb_start_read )
case ( i_wb_adr[15:0] )
AMBER_UART_CID0: wb_rdata <= 32'h0d;
AMBER_UART_CID1: wb_rdata <= 32'hf0;
AMBER_UART_CID2: wb_rdata <= 32'h05;
AMBER_UART_CID3: wb_rdata <= 32'hb1;
AMBER_UART_PID0: wb_rdata <= 32'h10;
AMBER_UART_PID1: wb_rdata <= 32'h10;
AMBER_UART_PID2: wb_rdata <= 32'h04;
AMBER_UART_PID3: wb_rdata <= 32'h00;
AMBER_UART_CID0: wb_rdata32 <= 32'h0d;
AMBER_UART_CID1: wb_rdata32 <= 32'hf0;
AMBER_UART_CID2: wb_rdata32 <= 32'h05;
AMBER_UART_CID3: wb_rdata32 <= 32'hb1;
AMBER_UART_PID0: wb_rdata32 <= 32'h10;
AMBER_UART_PID1: wb_rdata32 <= 32'h10;
AMBER_UART_PID2: wb_rdata32 <= 32'h04;
AMBER_UART_PID3: wb_rdata32 <= 32'h00;
AMBER_UART_DR: // Rx data
if ( fifo_enable )
wb_rdata <= {24'd0, rx_fifo[rx_fifo_rp[3:0]]};
wb_rdata32 <= {24'd0, rx_fifo[rx_fifo_rp[3:0]]};
else
wb_rdata <= {24'd0, rx_fifo[0]};
wb_rdata32 <= {24'd0, rx_fifo[0]};
AMBER_UART_RSR: wb_rdata <= uart_rsr_reg; // Receive status, (Write) Error Clear
AMBER_UART_LCRH: wb_rdata <= uart_lcrh_reg; // Line Control High Byte
AMBER_UART_LCRM: wb_rdata <= uart_lcrm_reg; // Line Control Middle Byte
AMBER_UART_LCRL: wb_rdata <= uart_lcrl_reg; // Line Control Low Byte
AMBER_UART_CR: wb_rdata <= uart_cr_reg; // Control Register
AMBER_UART_RSR: wb_rdata32 <= uart_rsr_reg; // Receive status, (Write) Error Clear
AMBER_UART_LCRH: wb_rdata32 <= uart_lcrh_reg; // Line Control High Byte
AMBER_UART_LCRM: wb_rdata32 <= uart_lcrm_reg; // Line Control Middle Byte
AMBER_UART_LCRL: wb_rdata32 <= uart_lcrl_reg; // Line Control Low Byte
AMBER_UART_CR: wb_rdata32 <= uart_cr_reg; // Control Register
// UART Tx/Rx Status
AMBER_UART_FR: wb_rdata <= {tx_fifo_empty, // tx fifo empty
AMBER_UART_FR: wb_rdata32 <= {tx_fifo_empty, // tx fifo empty
rx_fifo_full, // rx fifo full
tx_fifo_full, // tx fifo full
rx_fifo_empty, // rx fifo empty
754,7 → 773,7
}; // Flag Register
// Interrupt Status
AMBER_UART_IIR: wb_rdata <= {5'd0,
AMBER_UART_IIR: wb_rdata32 <= {5'd0,
1'd0, // RTIS - receive timeout interrupt
tx_interrupt, // TIS - transmit interrupt status
rx_interrupt, // RIS - receive interrupt status
761,7 → 780,7
1'd0 // Modem interrupt status
}; // (Write) Clear Int
default: wb_rdata <= 32'h00c0ffee;
default: wb_rdata32 <= 32'h00c0ffee;
endcase
 
867,7 → 886,7
`TB_DEBUG_MESSAGE
if ( wb_start_write )
$write("Write 0x%08x to ", i_wb_dat);
$write("Write 0x%08x to ", wb_wdata32);
else
$write("Read 0x%08x from ", o_wb_dat);
880,7 → 899,7
AMBER_UART_CID1: $write("UART CID1 register");
AMBER_UART_CID2: $write("UART CID2 register");
AMBER_UART_CID3: $write("UART CID3 register");
AMBER_UART_DR: $write("UART Tx/Rx char %c", wb_start_write ? i_wb_dat[7:0] : o_wb_dat[7:0] );
AMBER_UART_DR: $write("UART Tx/Rx char %c", wb_start_write ? wb_wdata32[7:0] : o_wb_dat[7:0] );
AMBER_UART_RSR: $write("UART (Read) Receive status, (Write) Error Clear");
AMBER_UART_LCRH: $write("UART Line Control High Byte");
AMBER_UART_LCRM: $write("UART Line Control Middle Byte");
920,7 → 939,7
if ( tx_fifo_push && tx_fifo_full )
begin
`TB_WARNING_MESSAGE
$display("UART tx FIFO overflow - char = %c", i_wb_dat[7:0]);
$display("UART tx FIFO overflow - char = %c", wb_wdata32[7:0]);
end
end
 
/amber/trunk/hw/vlog/system/system_functions.v
0,0 → 1,61
//////////////////////////////////////////////////////////////////
// //
// Functions for Amber 2 System //
// //
// This file is part of the Amber project //
// http://www.opencores.org/project,amber //
// //
// Description //
// Functions used in more than one module //
// //
// Author(s): //
// - Conor Santifort, csantifort.amber@gmail.com //
// //
//////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2010 Authors and OPENCORES.ORG //
// //
// This source file may be used and distributed without //
// restriction provided that this copyright statement is not //
// removed from the file and that any derivative work contains //
// the original copyright notice and the associated disclaimer. //
// //
// This source file is free software; you can redistribute it //
// and/or modify it under the terms of the GNU Lesser General //
// Public License as published by the Free Software Foundation; //
// either version 2.1 of the License, or (at your option) any //
// later version. //
// //
// This source is distributed in the hope that it will be //
// useful, but WITHOUT ANY WARRANTY; without even the implied //
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
// PURPOSE. See the GNU Lesser General Public License for more //
// details. //
// //
// You should have received a copy of the GNU Lesser General //
// Public License along with this source; if not, download it //
// from http://www.opencores.org/lgpl.shtml //
// //
//////////////////////////////////////////////////////////////////
 
 
// ========================================================
// 32-bit Endian switch
// ========================================================
function [31:0] endian_x32;
input [31:0] data;
begin
endian_x32 = {data[7:0], data[15:8], data[23:16], data[31:24]};
end
endfunction
 
 
// ========================================================
// 4-bit Endian switch
// ========================================================
function [3:0] endian_x4;
input [3:0] data;
begin
endian_x4 = {data[0], data[1], data[2], data[3]};
end
endfunction
/amber/trunk/hw/vlog/system/main_mem.v
43,16 → 43,18
//////////////////////////////////////////////////////////////////
 
 
module main_mem
(
module main_mem#(
parameter WB_DWIDTH = 32,
parameter WB_SWIDTH = 4
)(
input i_clk,
input i_mem_ctrl, // 0=128MB, 1=32MB
// Wishbone Bus
input [31:0] i_wb_adr,
input [3:0] i_wb_sel,
input [WB_SWIDTH-1:0] i_wb_sel,
input i_wb_we,
output reg [31:0] o_wb_dat = 'd0,
input [31:0] i_wb_dat,
output [WB_DWIDTH-1:0] o_wb_dat,
input [WB_DWIDTH-1:0] i_wb_dat,
input i_wb_cyc,
input i_wb_stb,
output o_wb_ack,
85,54 → 87,100
assign o_wb_err = 'd0;
 
 
// ------------------------------------------------------
// Write
// ------------------------------------------------------
always @( posedge i_clk )
begin
wr_en <= start_write;
wr_mask <= i_wb_adr[3:2] == 2'd0 ? { 12'hfff, ~i_wb_sel } :
i_wb_adr[3:2] == 2'd1 ? { 8'hff, ~i_wb_sel, 4'hf } :
i_wb_adr[3:2] == 2'd2 ? { 4'hf, ~i_wb_sel, 8'hff } :
{ ~i_wb_sel, 12'hfff } ;
wr_data <= {4{i_wb_dat}};
generate
if (WB_DWIDTH == 128)
begin : wb128
reg [127:0] wb_rdata128 = 'd0;
 
// Wrap the address at 32 MB, or full width
addr_d1 <= i_mem_ctrl ? {5'd0, i_wb_adr[24:2]} : i_wb_adr[29:2];
if ( wr_en )
ram [addr_d1[27:2]] <= masked_wdata;
end
// ------------------------------------------------------
// Write for 32-bit wishbone
// ------------------------------------------------------
always @( posedge i_clk )
begin
wr_en <= start_write;
wr_mask <= ~ i_wb_sel;
wr_data <= i_wb_dat;
 
// Wrap the address at 32 MB, or full width
addr_d1 <= i_mem_ctrl ? {5'd0, i_wb_adr[24:2]} : i_wb_adr[29:2];
if ( wr_en )
ram [addr_d1[27:2]] <= masked_wdata;
end
 
generate
for (i=0;i<16;i=i+1) begin : masked
assign masked_wdata[8*i+7:8*i] = wr_mask[i] ? rd_data[8*i+7:8*i] : wr_data[8*i+7:8*i];
end
endgenerate
 
for (i=0;i<16;i=i+1) begin : masked
assign masked_wdata[8*i+7:8*i] = wr_mask[i] ? rd_data[8*i+7:8*i] : wr_data[8*i+7:8*i];
end
 
// ------------------------------------------------------
// Read
// ------------------------------------------------------
assign rd_data = ram [addr_d1[27:2]];
// ------------------------------------------------------
// Read for 32-bit wishbone
// ------------------------------------------------------
assign rd_data = ram [addr_d1[27:2]];
 
always @( posedge i_clk )
begin
start_read_d1 <= start_read;
start_read_d2 <= start_read_d1;
if ( start_read_d1 )
begin
wb_rdata128 <= rd_data;
end
end
assign o_wb_dat = wb_rdata128 ;
assign o_wb_ack = i_wb_stb && ( start_write || start_read_d2 );
 
always @( posedge i_clk )
begin
start_read_d1 <= start_read;
start_read_d2 <= start_read_d1;
if ( start_read_d1 )
end
else
begin : wb32
reg [31:0] wb_rdata32 = 'd0;
 
// ------------------------------------------------------
// Write for 32-bit wishbone
// ------------------------------------------------------
always @( posedge i_clk )
begin
o_wb_dat <= addr_d1[1:0] == 2'd0 ? rd_data[ 31: 0] :
addr_d1[1:0] == 2'd1 ? rd_data[ 63:32] :
addr_d1[1:0] == 2'd2 ? rd_data[ 95:64] :
rd_data[127:96] ;
wr_en <= start_write;
wr_mask <= i_wb_adr[3:2] == 2'd0 ? { 12'hfff, ~i_wb_sel } :
i_wb_adr[3:2] == 2'd1 ? { 8'hff, ~i_wb_sel, 4'hf } :
i_wb_adr[3:2] == 2'd2 ? { 4'hf, ~i_wb_sel, 8'hff } :
{ ~i_wb_sel, 12'hfff } ;
wr_data <= {4{i_wb_dat}};
 
// Wrap the address at 32 MB, or full width
addr_d1 <= i_mem_ctrl ? {5'd0, i_wb_adr[24:2]} : i_wb_adr[29:2];
if ( wr_en )
ram [addr_d1[27:2]] <= masked_wdata;
end
 
 
for (i=0;i<16;i=i+1) begin : masked
assign masked_wdata[8*i+7:8*i] = wr_mask[i] ? rd_data[8*i+7:8*i] : wr_data[8*i+7:8*i];
end
// ------------------------------------------------------
// Read for 32-bit wishbone
// ------------------------------------------------------
assign rd_data = ram [addr_d1[27:2]];
 
always @( posedge i_clk )
begin
start_read_d1 <= start_read;
start_read_d2 <= start_read_d1;
if ( start_read_d1 )
begin
wb_rdata32 <= addr_d1[1:0] == 2'd0 ? rd_data[ 31: 0] :
addr_d1[1:0] == 2'd1 ? rd_data[ 63:32] :
addr_d1[1:0] == 2'd2 ? rd_data[ 95:64] :
rd_data[127:96] ;
end
end
assign o_wb_dat = wb_rdata32 ;
assign o_wb_ack = i_wb_stb && ( start_write || start_read_d2 );
end
assign o_wb_ack = i_wb_stb && ( start_write || start_read_d2 );
endgenerate
 
 
endmodule
/amber/trunk/hw/vlog/system/system.v
157,13 → 157,21
localparam WB_MASTERS = 2;
localparam WB_SLAVES = 9;
 
`ifdef AMBER_A25_CORE
localparam WB_DWIDTH = 128;
localparam WB_SWIDTH = 16;
`else
localparam WB_DWIDTH = 32;
localparam WB_SWIDTH = 4;
`endif
 
 
// Wishbone Master Buses
wire [31:0] m_wb_adr [WB_MASTERS-1:0];
wire [3:0] m_wb_sel [WB_MASTERS-1:0];
wire [WB_SWIDTH-1:0] m_wb_sel [WB_MASTERS-1:0];
wire [WB_MASTERS-1:0] m_wb_we ;
wire [31:0] m_wb_dat_w [WB_MASTERS-1:0];
wire [31:0] m_wb_dat_r [WB_MASTERS-1:0];
wire [WB_DWIDTH-1:0] m_wb_dat_w [WB_MASTERS-1:0];
wire [WB_DWIDTH-1:0] m_wb_dat_r [WB_MASTERS-1:0];
wire [WB_MASTERS-1:0] m_wb_cyc ;
wire [WB_MASTERS-1:0] m_wb_stb ;
wire [WB_MASTERS-1:0] m_wb_ack ;
172,16 → 180,36
 
// Wishbone Slave Buses
wire [31:0] s_wb_adr [WB_SLAVES-1:0];
wire [3:0] s_wb_sel [WB_SLAVES-1:0];
wire [WB_SWIDTH-1:0] s_wb_sel [WB_SLAVES-1:0];
wire [WB_SLAVES-1:0] s_wb_we ;
wire [31:0] s_wb_dat_w [WB_SLAVES-1:0];
wire [31:0] s_wb_dat_r [WB_SLAVES-1:0];
wire [WB_DWIDTH-1:0] s_wb_dat_w [WB_SLAVES-1:0];
wire [WB_DWIDTH-1:0] s_wb_dat_r [WB_SLAVES-1:0];
wire [WB_SLAVES-1:0] s_wb_cyc ;
wire [WB_SLAVES-1:0] s_wb_stb ;
wire [WB_SLAVES-1:0] s_wb_ack ;
wire [WB_SLAVES-1:0] s_wb_err ;
 
wire [31:0] emm_wb_adr;
wire [3:0] emm_wb_sel;
wire emm_wb_we;
wire [31:0] emm_wb_rdat;
wire [31:0] emm_wb_wdat;
wire emm_wb_cyc;
wire emm_wb_stb;
wire emm_wb_ack;
wire emm_wb_err;
 
wire [31:0] ems_wb_adr;
wire [3:0] ems_wb_sel;
wire ems_wb_we;
wire [31:0] ems_wb_rdat;
wire [31:0] ems_wb_wdat;
wire ems_wb_cyc;
wire ems_wb_stb;
wire ems_wb_ack;
wire ems_wb_err;
 
 
// ======================================
// Interrupts
// ======================================
239,32 → 267,32
// -------------------------------------------------------------
// Instantiate B100 Ethernet MAC
// -------------------------------------------------------------
 
eth_top u_eth_top (
.wb_clk_i ( sys_clk ),
.wb_rst_i ( sys_rst ),
 
// WISHBONE slave
.wb_adr_i ( s_wb_adr [0][11:2] ),
.wb_sel_i ( s_wb_sel [0] ),
.wb_we_i ( s_wb_we [0] ),
.wb_cyc_i ( s_wb_cyc [0] ),
.wb_stb_i ( s_wb_stb [0] ),
.wb_ack_o ( s_wb_ack [0] ),
.wb_dat_i ( s_wb_dat_w [0] ),
.wb_dat_o ( s_wb_dat_r [0] ),
.wb_err_o ( s_wb_err [0] ),
.wb_adr_i ( ems_wb_adr [11:2] ),
.wb_sel_i ( ems_wb_sel ),
.wb_we_i ( ems_wb_we ),
.wb_cyc_i ( ems_wb_cyc ),
.wb_stb_i ( ems_wb_stb ),
.wb_ack_o ( ems_wb_ack ),
.wb_dat_i ( ems_wb_wdat ),
.wb_dat_o ( ems_wb_rdat ),
.wb_err_o ( ems_wb_err ),
 
// WISHBONE master
.m_wb_adr_o ( m_wb_adr [0] ),
.m_wb_sel_o ( m_wb_sel [0] ),
.m_wb_we_o ( m_wb_we [0] ),
.m_wb_dat_i ( m_wb_dat_r [0] ),
.m_wb_dat_o ( m_wb_dat_w [0] ),
.m_wb_cyc_o ( m_wb_cyc [0] ),
.m_wb_stb_o ( m_wb_stb [0] ),
.m_wb_ack_i ( m_wb_ack [0] ),
.m_wb_err_i ( m_wb_err [0] ),
.m_wb_adr_o ( emm_wb_adr ),
.m_wb_sel_o ( emm_wb_sel ),
.m_wb_we_o ( emm_wb_we ),
.m_wb_dat_i ( emm_wb_rdat ),
.m_wb_dat_o ( emm_wb_wdat ),
.m_wb_cyc_o ( emm_wb_cyc ),
.m_wb_stb_o ( emm_wb_stb ),
.m_wb_ack_i ( emm_wb_ack ),
.m_wb_err_i ( emm_wb_err ),
 
// MAC to PHY I/F
.mtx_clk_pad_i ( mtx_clk_pad_i ),
287,7 → 315,6
);
 
 
 
// -------------------------------------------------------------
// Instantiate Ethernet Control Interface tri-state buffer
// -------------------------------------------------------------
312,7 → 339,11
// -------------------------------------------------------------
// Instantiate Boot Memory - 8KBytes of Embedded SRAM
// -------------------------------------------------------------
boot_mem u_boot_mem (
boot_mem #(
.WB_DWIDTH ( WB_DWIDTH ),
.WB_SWIDTH ( WB_SWIDTH )
)
u_boot_mem (
.i_wb_clk ( sys_clk ),
 
.i_wb_adr ( s_wb_adr [1] ),
327,11 → 358,14
);
 
 
 
// -------------------------------------------------------------
// Instantiate UART0
// -------------------------------------------------------------
uart u_uart0 (
uart #(
.WB_DWIDTH ( WB_DWIDTH ),
.WB_SWIDTH ( WB_SWIDTH )
)
u_uart0 (
.i_clk ( sys_clk ),
 
.o_uart_int ( uart0_int ),
356,7 → 390,11
// -------------------------------------------------------------
// Instantiate UART1
// -------------------------------------------------------------
uart u_uart1 (
uart #(
.WB_DWIDTH ( WB_DWIDTH ),
.WB_SWIDTH ( WB_SWIDTH )
)
u_uart1 (
.i_clk ( sys_clk ),
 
.o_uart_int ( uart1_int ),
384,7 → 422,11
// Instantiate Test Module
// - includes register used to terminate tests
// -------------------------------------------------------------
test_module u_test_module (
test_module #(
.WB_DWIDTH ( WB_DWIDTH ),
.WB_SWIDTH ( WB_SWIDTH )
)
u_test_module (
.i_clk ( sys_clk ),
.o_irq ( test_reg_irq ),
405,7 → 447,11
// -------------------------------------------------------------
// Instantiate Timer Module
// -------------------------------------------------------------
timer_module u_timer_module (
timer_module #(
.WB_DWIDTH ( WB_DWIDTH ),
.WB_SWIDTH ( WB_SWIDTH )
)
u_timer_module (
.i_clk ( sys_clk ),
// Interrupt outputs
427,7 → 473,11
// -------------------------------------------------------------
// Instantiate Interrupt Controller Module
// -------------------------------------------------------------
interrupt_controller u_interrupt_controller (
interrupt_controller #(
.WB_DWIDTH ( WB_DWIDTH ),
.WB_SWIDTH ( WB_SWIDTH )
)
u_interrupt_controller (
.i_clk ( sys_clk ),
// Interrupt outputs
464,7 → 514,11
assign phy_init_done = 1'd1;
main_mem u_main_mem (
main_mem #(
.WB_DWIDTH ( WB_DWIDTH ),
.WB_SWIDTH ( WB_SWIDTH )
)
u_main_mem (
.i_clk ( sys_clk ),
.i_mem_ctrl ( test_mem_ctrl ),
.i_wb_adr ( s_wb_adr [2] ),
676,7 → 730,11
// -------------------------------------------------------------
// Instantiate Wishbone Arbiter
// -------------------------------------------------------------
wishbone_arbiter u_wishbone_arbiter (
wishbone_arbiter #(
.WB_DWIDTH ( WB_DWIDTH ),
.WB_SWIDTH ( WB_SWIDTH )
)
u_wishbone_arbiter (
.i_wb_clk ( sys_clk ),
 
// WISHBONE master 0 - Ethmac
800,6 → 858,59
);
 
 
ethmac_wb #(
.WB_DWIDTH ( WB_DWIDTH ),
.WB_SWIDTH ( WB_SWIDTH )
)
u_ethmac_wb (
// Wishbone arbiter side
.o_m_wb_adr ( m_wb_adr [0] ),
.o_m_wb_sel ( m_wb_sel [0] ),
.o_m_wb_we ( m_wb_we [0] ),
.i_m_wb_rdat ( m_wb_dat_r [0] ),
.o_m_wb_wdat ( m_wb_dat_w [0] ),
.o_m_wb_cyc ( m_wb_cyc [0] ),
.o_m_wb_stb ( m_wb_stb [0] ),
.i_m_wb_ack ( m_wb_ack [0] ),
.i_m_wb_err ( m_wb_err [0] ),
 
// Wishbone arbiter side
.i_s_wb_adr ( s_wb_adr [0] ),
.i_s_wb_sel ( s_wb_sel [0] ),
.i_s_wb_we ( s_wb_we [0] ),
.i_s_wb_cyc ( s_wb_cyc [0] ),
.i_s_wb_stb ( s_wb_stb [0] ),
.o_s_wb_ack ( s_wb_ack [0] ),
.i_s_wb_wdat ( s_wb_dat_w [0] ),
.o_s_wb_rdat ( s_wb_dat_r [0] ),
.o_s_wb_err ( s_wb_err [0] ),
 
// Ethmac side
.i_m_wb_adr ( emm_wb_adr ),
.i_m_wb_sel ( emm_wb_sel ),
.i_m_wb_we ( emm_wb_we ),
.o_m_wb_rdat ( emm_wb_rdat ),
.i_m_wb_wdat ( emm_wb_wdat ),
.i_m_wb_cyc ( emm_wb_cyc ),
.i_m_wb_stb ( emm_wb_stb ),
.o_m_wb_ack ( emm_wb_ack ),
.o_m_wb_err ( emm_wb_err ),
 
// Ethmac side
.o_s_wb_adr ( ems_wb_adr ),
.o_s_wb_sel ( ems_wb_sel ),
.o_s_wb_we ( ems_wb_we ),
.i_s_wb_rdat ( ems_wb_rdat ),
.o_s_wb_wdat ( ems_wb_wdat ),
.o_s_wb_cyc ( ems_wb_cyc ),
.o_s_wb_stb ( ems_wb_stb ),
.i_s_wb_ack ( ems_wb_ack ),
.i_s_wb_err ( ems_wb_err )
);
 
 
 
 
endmodule
 
 
/amber/trunk/hw/vlog/system/test_module.v
41,7 → 41,10
//////////////////////////////////////////////////////////////////
 
 
module test_module (
module test_module #(
parameter WB_DWIDTH = 32,
parameter WB_SWIDTH = 4
)(
input i_clk,
 
output o_irq,
48,10 → 51,10
output o_firq,
output o_mem_ctrl, // 0=128MB, 1=32MB
input [31:0] i_wb_adr,
input [3:0] i_wb_sel,
input [WB_SWIDTH-1:0] i_wb_sel,
input i_wb_we,
output [31:0] o_wb_dat,
input [31:0] i_wb_dat,
output [WB_DWIDTH-1:0] o_wb_dat,
input [WB_DWIDTH-1:0] i_wb_dat,
input i_wb_cyc,
input i_wb_stb,
output o_wb_ack,
83,7 → 86,8
wire wb_start_write;
wire wb_start_read;
reg wb_start_read_d1 = 'd0;
reg [31:0] wb_rdata = 'd0;
reg [31:0] wb_rdata32 = 'd0;
wire [31:0] wb_wdata32;
 
// Can't start a write while a read is completing. The ack for the read cycle
// needs to be sent first
95,9 → 99,26
 
assign o_wb_ack = i_wb_stb && ( wb_start_write || wb_start_read_d1 );
assign o_wb_err = 1'd0;
assign o_wb_dat = wb_rdata;
assign o_mem_ctrl = mem_ctrl_reg;
 
 
generate
if (WB_DWIDTH == 128)
begin : wb128
assign wb_wdata32 = i_wb_adr[3:2] == 2'd3 ? i_wb_dat[127:96] :
i_wb_adr[3:2] == 2'd2 ? i_wb_dat[ 95:64] :
i_wb_adr[3:2] == 2'd1 ? i_wb_dat[ 63:32] :
i_wb_dat[ 31: 0] ;
assign o_wb_dat = {4{wb_rdata32}};
end
else
begin : wb32
assign wb_wdata32 = i_wb_dat;
assign o_wb_dat = wb_rdata32;
end
endgenerate
 
// ========================================================
// Register Reads
// ========================================================
104,42 → 125,42
always @( posedge i_clk )
if ( wb_start_read )
case ( i_wb_adr[15:0] )
AMBER_TEST_STATUS: wb_rdata <= test_status_reg;
AMBER_TEST_FIRQ_TIMER: wb_rdata <= {24'd0, firq_timer};
AMBER_TEST_IRQ_TIMER: wb_rdata <= {24'd0, irq_timer};
AMBER_TEST_RANDOM_NUM: wb_rdata <= {24'd0, random_num};
AMBER_TEST_STATUS: wb_rdata32 <= test_status_reg;
AMBER_TEST_FIRQ_TIMER: wb_rdata32 <= {24'd0, firq_timer};
AMBER_TEST_IRQ_TIMER: wb_rdata32 <= {24'd0, irq_timer};
AMBER_TEST_RANDOM_NUM: wb_rdata32 <= {24'd0, random_num};
/* Allow access to the random register over
a 16-word address range to load a series
of random numbers using lmd instruction. */
AMBER_TEST_RANDOM_NUM00: wb_rdata <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM01: wb_rdata <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM02: wb_rdata <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM03: wb_rdata <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM04: wb_rdata <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM05: wb_rdata <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM06: wb_rdata <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM07: wb_rdata <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM08: wb_rdata <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM09: wb_rdata <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM10: wb_rdata <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM11: wb_rdata <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM12: wb_rdata <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM13: wb_rdata <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM14: wb_rdata <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM15: wb_rdata <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM00: wb_rdata32 <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM01: wb_rdata32 <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM02: wb_rdata32 <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM03: wb_rdata32 <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM04: wb_rdata32 <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM05: wb_rdata32 <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM06: wb_rdata32 <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM07: wb_rdata32 <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM08: wb_rdata32 <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM09: wb_rdata32 <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM10: wb_rdata32 <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM11: wb_rdata32 <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM12: wb_rdata32 <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM13: wb_rdata32 <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM14: wb_rdata32 <= {24'd0, random_num};
AMBER_TEST_RANDOM_NUM15: wb_rdata32 <= {24'd0, random_num};
//synopsys translate_off
AMBER_TEST_UART_CONTROL: wb_rdata <= {30'd0, tb_uart_control_reg};
AMBER_TEST_UART_STATUS: wb_rdata <= {30'd0, tb_uart_status_reg};
AMBER_TEST_UART_TXD: wb_rdata <= {24'd0, tb_uart_txd_reg};
AMBER_TEST_UART_CONTROL: wb_rdata32 <= {30'd0, tb_uart_control_reg};
AMBER_TEST_UART_STATUS: wb_rdata32 <= {30'd0, tb_uart_status_reg};
AMBER_TEST_UART_TXD: wb_rdata32 <= {24'd0, tb_uart_txd_reg};
//synopsys translate_on
AMBER_TEST_SIM_CTRL: wb_rdata <= {29'd0, sim_ctrl_reg};
AMBER_TEST_MEM_CTRL: wb_rdata <= {31'd0, mem_ctrl_reg};
AMBER_TEST_SIM_CTRL: wb_rdata32 <= {29'd0, sim_ctrl_reg};
AMBER_TEST_MEM_CTRL: wb_rdata32 <= {31'd0, mem_ctrl_reg};
AMBER_TEST_CYCLES: wb_rdata <= cycles_reg;
default: wb_rdata <= 32'haabbccdd;
AMBER_TEST_CYCLES: wb_rdata32 <= cycles_reg;
default: wb_rdata32 <= 32'haabbccdd;
endcase
 
178,7 → 199,7
// Write 0 to clear it
always @( posedge i_clk )
if ( wb_start_write && i_wb_adr[15:0] == AMBER_TEST_FIRQ_TIMER )
firq_timer <= i_wb_dat[7:0];
firq_timer <= wb_wdata32[7:0];
else if ( firq_timer > 8'd1 )
firq_timer <= firq_timer - 1'd1;
 
190,7 → 211,7
// Write 0 to clear it
always @( posedge i_clk )
if ( wb_start_write && i_wb_adr[15:0] == AMBER_TEST_IRQ_TIMER )
irq_timer <= i_wb_dat[7:0];
irq_timer <= wb_wdata32[7:0];
else if ( irq_timer > 8'd1 )
irq_timer <= irq_timer - 1'd1;
 
203,7 → 224,7
always @( posedge i_clk )
begin
if ( wb_start_write && i_wb_adr[15:8] == AMBER_TEST_RANDOM_NUM[15:8] )
random_num <= i_wb_dat[7:0];
random_num <= wb_wdata32[7:0];
// generate a new random number on every read access
else if ( wb_start_read && i_wb_adr[15:8] == AMBER_TEST_RANDOM_NUM[15:8] )
224,7 → 245,7
// ======================================
always @( posedge i_clk )
if ( wb_start_write && i_wb_adr[15:0] == AMBER_TEST_STATUS )
test_status_reg <= i_wb_dat;
test_status_reg <= wb_wdata32;
 
// ======================================
234,7 → 255,6
if ( wb_start_write && i_wb_adr[15:0] == AMBER_TEST_STATUS )
test_status_set <= 1'd1;
 
 
// ======================================
// Cycles counter
// ======================================
241,13 → 261,12
always @( posedge i_clk )
cycles_reg <= cycles_reg + 1'd1;
 
// ======================================
// Memory Configuration Register Write
// ======================================
always @( posedge i_clk )
if ( wb_start_write && i_wb_adr[15:0] == AMBER_TEST_MEM_CTRL )
mem_ctrl_reg <= i_wb_dat[0];
mem_ctrl_reg <= wb_wdata32[0];
 
 
// ======================================
260,11 → 279,11
always @( posedge i_clk )
begin
if ( wb_start_write && i_wb_adr[15:0] == AMBER_TEST_UART_CONTROL )
tb_uart_control_reg <= i_wb_dat[1:0];
tb_uart_control_reg <= wb_wdata32[1:0];
if ( wb_start_write && i_wb_adr[15:0] == AMBER_TEST_UART_TXD )
begin
tb_uart_txd_reg <= i_wb_dat[7:0];
tb_uart_txd_reg <= wb_wdata32[7:0];
tb_uart_push <= !tb_uart_push;
end
end
/amber/trunk/hw/vlog/system/timer_module.v
40,14 → 40,17
//////////////////////////////////////////////////////////////////
 
 
module timer_module (
module timer_module #(
parameter WB_DWIDTH = 32,
parameter WB_SWIDTH = 4
)(
input i_clk,
 
input [31:0] i_wb_adr,
input [3:0] i_wb_sel,
input [WB_SWIDTH-1:0] i_wb_sel,
input i_wb_we,
output [31:0] o_wb_dat,
input [31:0] i_wb_dat,
output [WB_DWIDTH-1:0] o_wb_dat,
input [WB_DWIDTH-1:0] i_wb_dat,
input i_wb_cyc,
input i_wb_stb,
output o_wb_ack,
75,10 → 78,11
reg timer2_int_reg = 'd0; // interrupt flag
 
// Wishbone interface
reg [31:0] wb_rdata = 'd0;
reg [31:0] wb_rdata32 = 'd0;
wire wb_start_write;
wire wb_start_read;
reg wb_start_read_d1 = 'd0;
wire [31:0] wb_wdata32;
 
 
// ======================================================
93,11 → 97,26
always @( posedge i_clk )
wb_start_read_d1 <= wb_start_read;
 
assign o_wb_dat = wb_rdata;
 
assign o_wb_err = 1'd0;
assign o_wb_ack = i_wb_stb && ( wb_start_write || wb_start_read_d1 );
 
generate
if (WB_DWIDTH == 128)
begin : wb128
assign wb_wdata32 = i_wb_adr[3:2] == 2'd3 ? i_wb_dat[127:96] :
i_wb_adr[3:2] == 2'd2 ? i_wb_dat[ 95:64] :
i_wb_adr[3:2] == 2'd1 ? i_wb_dat[ 63:32] :
i_wb_dat[ 31: 0] ;
assign o_wb_dat = {4{wb_rdata32}};
end
else
begin : wb32
assign wb_wdata32 = i_wb_dat;
assign o_wb_dat = wb_rdata32;
end
endgenerate
 
// ========================================================
// Timer Interrupt Outputs
253,32 → 272,32
always @( posedge i_clk )
if ( wb_start_read )
case ( i_wb_adr[15:0] )
AMBER_TM_TIMER0_LOAD: wb_rdata <= {16'd0, timer0_load_reg};
AMBER_TM_TIMER1_LOAD: wb_rdata <= {16'd0, timer1_load_reg};
AMBER_TM_TIMER2_LOAD: wb_rdata <= {16'd0, timer2_load_reg};
AMBER_TM_TIMER0_CTRL: wb_rdata <= {24'd0,
AMBER_TM_TIMER0_LOAD: wb_rdata32 <= {16'd0, timer0_load_reg};
AMBER_TM_TIMER1_LOAD: wb_rdata32 <= {16'd0, timer1_load_reg};
AMBER_TM_TIMER2_LOAD: wb_rdata32 <= {16'd0, timer2_load_reg};
AMBER_TM_TIMER0_CTRL: wb_rdata32 <= {24'd0,
timer0_ctrl_reg[7:6],
2'd0,
timer0_ctrl_reg[3:2],
2'd0
};
AMBER_TM_TIMER1_CTRL: wb_rdata <= {24'd0,
AMBER_TM_TIMER1_CTRL: wb_rdata32 <= {24'd0,
timer1_ctrl_reg[7:6],
2'd0,
timer1_ctrl_reg[3:2],
2'd0
};
AMBER_TM_TIMER2_CTRL: wb_rdata <= {24'd0,
AMBER_TM_TIMER2_CTRL: wb_rdata32 <= {24'd0,
timer2_ctrl_reg[7:6],
2'd0,
timer2_ctrl_reg[3:2],
2'd0
};
AMBER_TM_TIMER0_VALUE: wb_rdata <= {16'd0, timer0_value_reg[23:8]};
AMBER_TM_TIMER1_VALUE: wb_rdata <= {16'd0, timer1_value_reg[23:8]};
AMBER_TM_TIMER2_VALUE: wb_rdata <= {16'd0, timer2_value_reg[23:8]};
AMBER_TM_TIMER0_VALUE: wb_rdata32 <= {16'd0, timer0_value_reg[23:8]};
AMBER_TM_TIMER1_VALUE: wb_rdata32 <= {16'd0, timer1_value_reg[23:8]};
AMBER_TM_TIMER2_VALUE: wb_rdata32 <= {16'd0, timer2_value_reg[23:8]};
default: wb_rdata <= 32'h66778899;
default: wb_rdata32 <= 32'h66778899;
endcase
 
/amber/trunk/hw/vlog/system/wishbone_arbiter.v
40,135 → 40,140
// //
//////////////////////////////////////////////////////////////////
 
// TODO add module to switch endianess of ethmac i/f
 
module wishbone_arbiter (
input i_wb_clk, // WISHBONE clock
module wishbone_arbiter #(
parameter WB_DWIDTH = 32,
parameter WB_SWIDTH = 4
)(
 
input i_wb_clk, // WISHBONE clock
 
// WISHBONE master 0 - Amber
input [31:0] i_m0_wb_adr,
input [3:0] i_m0_wb_sel,
input i_m0_wb_we,
output [31:0] o_m0_wb_dat,
input [31:0] i_m0_wb_dat,
input i_m0_wb_cyc,
input i_m0_wb_stb,
output o_m0_wb_ack,
output o_m0_wb_err,
input [31:0] i_m0_wb_adr,
input [WB_SWIDTH-1:0] i_m0_wb_sel,
input i_m0_wb_we,
output [WB_DWIDTH-1:0] o_m0_wb_dat,
input [WB_DWIDTH-1:0] i_m0_wb_dat,
input i_m0_wb_cyc,
input i_m0_wb_stb,
output o_m0_wb_ack,
output o_m0_wb_err,
 
 
// WISHBONE master 1 - Ethmac
input [31:0] i_m1_wb_adr,
input [3:0] i_m1_wb_sel,
input i_m1_wb_we,
output [31:0] o_m1_wb_dat,
input [31:0] i_m1_wb_dat,
input i_m1_wb_cyc,
input i_m1_wb_stb,
output o_m1_wb_ack,
output o_m1_wb_err,
input [31:0] i_m1_wb_adr,
input [WB_SWIDTH-1:0] i_m1_wb_sel,
input i_m1_wb_we,
output [WB_DWIDTH-1:0] o_m1_wb_dat,
input [WB_DWIDTH-1:0] i_m1_wb_dat,
input i_m1_wb_cyc,
input i_m1_wb_stb,
output o_m1_wb_ack,
output o_m1_wb_err,
 
 
// WISHBONE slave 0 - Ethmac
output [31:0] o_s0_wb_adr,
output [3:0] o_s0_wb_sel,
output o_s0_wb_we,
input [31:0] i_s0_wb_dat,
output [31:0] o_s0_wb_dat,
output o_s0_wb_cyc,
output o_s0_wb_stb,
input i_s0_wb_ack,
input i_s0_wb_err,
output [31:0] o_s0_wb_adr,
output [WB_SWIDTH-1:0] o_s0_wb_sel,
output o_s0_wb_we,
input [WB_DWIDTH-1:0] i_s0_wb_dat,
output [WB_DWIDTH-1:0] o_s0_wb_dat,
output o_s0_wb_cyc,
output o_s0_wb_stb,
input i_s0_wb_ack,
input i_s0_wb_err,
 
 
// WISHBONE slave 1 - Boot Memory
output [31:0] o_s1_wb_adr,
output [3:0] o_s1_wb_sel,
output o_s1_wb_we,
input [31:0] i_s1_wb_dat,
output [31:0] o_s1_wb_dat,
output o_s1_wb_cyc,
output o_s1_wb_stb,
input i_s1_wb_ack,
input i_s1_wb_err,
output [31:0] o_s1_wb_adr,
output [WB_SWIDTH-1:0] o_s1_wb_sel,
output o_s1_wb_we,
input [WB_DWIDTH-1:0] i_s1_wb_dat,
output [WB_DWIDTH-1:0] o_s1_wb_dat,
output o_s1_wb_cyc,
output o_s1_wb_stb,
input i_s1_wb_ack,
input i_s1_wb_err,
 
 
// WISHBONE slave 2 - Main Memory
output [31:0] o_s2_wb_adr,
output [3:0] o_s2_wb_sel,
output o_s2_wb_we,
input [31:0] i_s2_wb_dat,
output [31:0] o_s2_wb_dat,
output o_s2_wb_cyc,
output o_s2_wb_stb,
input i_s2_wb_ack,
input i_s2_wb_err,
output [31:0] o_s2_wb_adr,
output [WB_SWIDTH-1:0] o_s2_wb_sel,
output o_s2_wb_we,
input [WB_DWIDTH-1:0] i_s2_wb_dat,
output [WB_DWIDTH-1:0] o_s2_wb_dat,
output o_s2_wb_cyc,
output o_s2_wb_stb,
input i_s2_wb_ack,
input i_s2_wb_err,
 
 
// WISHBONE slave 3 - UART 0
output [31:0] o_s3_wb_adr,
output [3:0] o_s3_wb_sel,
output o_s3_wb_we,
input [31:0] i_s3_wb_dat,
output [31:0] o_s3_wb_dat,
output o_s3_wb_cyc,
output o_s3_wb_stb,
input i_s3_wb_ack,
input i_s3_wb_err,
output [31:0] o_s3_wb_adr,
output [WB_SWIDTH-1:0] o_s3_wb_sel,
output o_s3_wb_we,
input [WB_DWIDTH-1:0] i_s3_wb_dat,
output [WB_DWIDTH-1:0] o_s3_wb_dat,
output o_s3_wb_cyc,
output o_s3_wb_stb,
input i_s3_wb_ack,
input i_s3_wb_err,
 
 
// WISHBONE slave 4 - UART 1
output [31:0] o_s4_wb_adr,
output [3:0] o_s4_wb_sel,
output o_s4_wb_we,
input [31:0] i_s4_wb_dat,
output [31:0] o_s4_wb_dat,
output o_s4_wb_cyc,
output o_s4_wb_stb,
input i_s4_wb_ack,
input i_s4_wb_err,
output [31:0] o_s4_wb_adr,
output [WB_SWIDTH-1:0] o_s4_wb_sel,
output o_s4_wb_we,
input [WB_DWIDTH-1:0] i_s4_wb_dat,
output [WB_DWIDTH-1:0] o_s4_wb_dat,
output o_s4_wb_cyc,
output o_s4_wb_stb,
input i_s4_wb_ack,
input i_s4_wb_err,
 
 
// WISHBONE slave 5 - Test Module
output [31:0] o_s5_wb_adr,
output [3:0] o_s5_wb_sel,
output o_s5_wb_we,
input [31:0] i_s5_wb_dat,
output [31:0] o_s5_wb_dat,
output o_s5_wb_cyc,
output o_s5_wb_stb,
input i_s5_wb_ack,
input i_s5_wb_err,
output [31:0] o_s5_wb_adr,
output [WB_SWIDTH-1:0] o_s5_wb_sel,
output o_s5_wb_we,
input [WB_DWIDTH-1:0] i_s5_wb_dat,
output [WB_DWIDTH-1:0] o_s5_wb_dat,
output o_s5_wb_cyc,
output o_s5_wb_stb,
input i_s5_wb_ack,
input i_s5_wb_err,
 
 
// WISHBONE slave 6 - Timer Module
output [31:0] o_s6_wb_adr,
output [3:0] o_s6_wb_sel,
output o_s6_wb_we,
input [31:0] i_s6_wb_dat,
output [31:0] o_s6_wb_dat,
output o_s6_wb_cyc,
output o_s6_wb_stb,
input i_s6_wb_ack,
input i_s6_wb_err,
output [31:0] o_s6_wb_adr,
output [WB_SWIDTH-1:0] o_s6_wb_sel,
output o_s6_wb_we,
input [WB_DWIDTH-1:0] i_s6_wb_dat,
output [WB_DWIDTH-1:0] o_s6_wb_dat,
output o_s6_wb_cyc,
output o_s6_wb_stb,
input i_s6_wb_ack,
input i_s6_wb_err,
 
 
// WISHBONE slave 7 - Interrupt Controller
output [31:0] o_s7_wb_adr,
output [3:0] o_s7_wb_sel,
output o_s7_wb_we,
input [31:0] i_s7_wb_dat,
output [31:0] o_s7_wb_dat,
output o_s7_wb_cyc,
output o_s7_wb_stb,
input i_s7_wb_ack,
input i_s7_wb_err
output [31:0] o_s7_wb_adr,
output [WB_SWIDTH-1:0] o_s7_wb_sel,
output o_s7_wb_we,
input [WB_DWIDTH-1:0] i_s7_wb_dat,
output [WB_DWIDTH-1:0] o_s7_wb_dat,
output o_s7_wb_cyc,
output o_s7_wb_stb,
input i_s7_wb_ack,
input i_s7_wb_err
);
 
`include "memory_configuration.v"
reg m0_wb_cyc_r = 'd0;
reg m1_wb_cyc_r = 'd0;
wire m0_in_cycle;
wire m1_in_cycle;
reg m0_wb_hold_r = 'd0;
reg m1_wb_hold_r = 'd0;
// wire m0_in_cycle;
// wire m1_in_cycle;
wire current_master;
reg current_master_r = 'd0;
wire next_master;
175,26 → 180,27
wire select_master;
wire [3:0] current_slave;
 
wire [31:0] master_adr;
wire [3:0] master_sel;
wire master_we;
wire [31:0] master_wdat;
wire master_cyc;
wire master_stb;
wire [31:0] master_rdat;
wire master_ack;
wire master_err;
wire [31:0] master_adr;
wire [WB_SWIDTH-1:0] master_sel;
wire master_we;
wire [WB_DWIDTH-1:0] master_wdat;
wire master_cyc;
wire master_stb;
wire [WB_DWIDTH-1:0] master_rdat;
wire master_ack;
wire master_err;
// Arbitrate between m0 and m1. Ethmac (m0) always gets priority
assign next_master = i_m0_wb_cyc ? 1'd0 : 1'd1;
 
// Use cyc signal for arbitration so block accesses are not split up
assign m0_in_cycle = m0_wb_cyc_r && i_m0_wb_cyc;
assign m1_in_cycle = m1_wb_cyc_r && i_m1_wb_cyc;
// assign m0_in_cycle = m0_wb_hold_r && !master_ack;
// assign m1_in_cycle = m1_wb_hold_r && !master_ack;
 
// only select a new bus master when the current bus master
// de-asserts the cyc signal
assign select_master = current_master_r ? !m1_in_cycle : !m0_in_cycle;
// daccess ends
assign select_master = current_master_r ? !m1_wb_hold_r : !m0_wb_hold_r;
assign current_master = select_master ? next_master : current_master_r;
 
 
201,8 → 207,8
always @( posedge i_wb_clk )
begin
current_master_r <= current_master;
m0_wb_cyc_r <= i_m0_wb_cyc;
m1_wb_cyc_r <= i_m1_wb_cyc;
m0_wb_hold_r <= i_m0_wb_stb && !o_m0_wb_ack;
m1_wb_hold_r <= i_m1_wb_stb && !o_m1_wb_ack;
end
 
 
219,11 → 225,8
 
 
assign master_adr = current_master ? i_m1_wb_adr : i_m0_wb_adr ;
// Switch endianess of ethmac Master
assign master_sel = current_master ? i_m1_wb_sel : {i_m0_wb_sel[0], i_m0_wb_sel[1],
i_m0_wb_sel[2], i_m0_wb_sel[3]};
assign master_wdat = current_master ? i_m1_wb_dat : {i_m0_wb_dat[7:0], i_m0_wb_dat[15:8],
i_m0_wb_dat[23:16],i_m0_wb_dat[31:24]} ;
assign master_sel = current_master ? i_m1_wb_sel : i_m0_wb_sel ;
assign master_wdat = current_master ? i_m1_wb_dat : i_m0_wb_dat ;
assign master_we = current_master ? i_m1_wb_we : i_m0_wb_we ;
assign master_cyc = current_master ? i_m1_wb_cyc : i_m0_wb_cyc ;
assign master_stb = current_master ? i_m1_wb_stb : i_m0_wb_stb ;
329,9 → 332,7
 
 
// Ethmac Master Outputs
// Switch endianess of ethmac Master
assign o_m0_wb_dat = {master_rdat[7:0], master_rdat[15:8],
master_rdat[23:16],master_rdat[31:24]};
assign o_m0_wb_dat = master_rdat;
assign o_m0_wb_ack = current_master ? 1'd0 : master_ack ;
assign o_m0_wb_err = current_master ? 1'd0 : master_err ;
 
/amber/trunk/hw/vlog/system/ethmac_wb.v
0,0 → 1,172
//////////////////////////////////////////////////////////////////
// //
// Ethmac module Wishbone bus width and endian switch //
// //
// This file is part of the Amber project //
// http://www.opencores.org/project,amber //
// //
// Description //
// Arbitrates between two wishbone masters and 13 wishbone //
// slave modules. The ethernet MAC wishbone master is given //
// priority over the Amber core. //
// //
// Author(s): //
// - Conor Santifort, csantifort.amber@gmail.com //
// //
//////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2010 Authors and OPENCORES.ORG //
// //
// This source file may be used and distributed without //
// restriction provided that this copyright statement is not //
// removed from the file and that any derivative work contains //
// the original copyright notice and the associated disclaimer. //
// //
// This source file is free software; you can redistribute it //
// and/or modify it under the terms of the GNU Lesser General //
// Public License as published by the Free Software Foundation; //
// either version 2.1 of the License, or (at your option) any //
// later version. //
// //
// This source is distributed in the hope that it will be //
// useful, but WITHOUT ANY WARRANTY; without even the implied //
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
// PURPOSE. See the GNU Lesser General Public License for more //
// details. //
// //
// You should have received a copy of the GNU Lesser General //
// Public License along with this source; if not, download it //
// from http://www.opencores.org/lgpl.shtml //
// //
//////////////////////////////////////////////////////////////////
 
 
module ethmac_wb #(
parameter WB_DWIDTH = 32,
parameter WB_SWIDTH = 4
)(
 
// Ethmac side
input [31:0] i_m_wb_adr,
input [3:0] i_m_wb_sel,
input i_m_wb_we,
output [31:0] o_m_wb_rdat,
input [31:0] i_m_wb_wdat,
input i_m_wb_cyc,
input i_m_wb_stb,
output o_m_wb_ack,
output o_m_wb_err,
 
// Wishbone arbiter side
output [31:0] o_m_wb_adr,
output [WB_SWIDTH-1:0] o_m_wb_sel,
output o_m_wb_we,
input [WB_DWIDTH-1:0] i_m_wb_rdat,
output [WB_DWIDTH-1:0] o_m_wb_wdat,
output o_m_wb_cyc,
output o_m_wb_stb,
input i_m_wb_ack,
input i_m_wb_err,
 
// Wishbone arbiter side
input [31:0] i_s_wb_adr,
input [WB_SWIDTH-1:0] i_s_wb_sel,
input i_s_wb_we,
output [WB_DWIDTH-1:0] o_s_wb_rdat,
input [WB_DWIDTH-1:0] i_s_wb_wdat,
input i_s_wb_cyc,
input i_s_wb_stb,
output o_s_wb_ack,
output o_s_wb_err,
 
// Ethmac side
output [31:0] o_s_wb_adr,
output [3:0] o_s_wb_sel,
output o_s_wb_we,
input [31:0] i_s_wb_rdat,
output [31:0] o_s_wb_wdat,
output o_s_wb_cyc,
output o_s_wb_stb,
input i_s_wb_ack,
input i_s_wb_err
 
);
 
`include "system_functions.v"
 
 
// =========================
// Master interface - with endian conversion
// =========================
generate
if (WB_DWIDTH == 128)
begin : wbm128
assign o_m_wb_rdat = i_m_wb_adr[3:2] == 2'd3 ? endian_x32(i_m_wb_rdat[127:96]) :
i_m_wb_adr[3:2] == 2'd2 ? endian_x32(i_m_wb_rdat[ 95:64]) :
i_m_wb_adr[3:2] == 2'd1 ? endian_x32(i_m_wb_rdat[ 63:32]) :
endian_x32(i_m_wb_rdat[ 31: 0]) ;
assign o_m_wb_sel = i_m_wb_adr[3:2] == 2'd3 ? { endian_x4(i_m_wb_sel), 12'd0} :
i_m_wb_adr[3:2] == 2'd2 ? { 4'd0, endian_x4(i_m_wb_sel), 8'd0} :
i_m_wb_adr[3:2] == 2'd1 ? { 8'd0, endian_x4(i_m_wb_sel), 4'd0} :
{12'd0, endian_x4(i_m_wb_sel) } ;
assign o_m_wb_wdat = i_m_wb_adr[3:2] == 2'd3 ? { endian_x32(i_m_wb_wdat), 96'd0} :
i_m_wb_adr[3:2] == 2'd2 ? {32'd0, endian_x32(i_m_wb_wdat), 64'd0} :
i_m_wb_adr[3:2] == 2'd1 ? {64'd0, endian_x32(i_m_wb_wdat), 32'd0} :
{96'd0, endian_x32(i_m_wb_wdat) } ;
end
else
begin : wbm32
assign o_m_wb_rdat = endian_x32(i_m_wb_rdat);
assign o_m_wb_sel = endian_x4 (i_m_wb_sel);
assign o_m_wb_wdat = endian_x32(i_m_wb_wdat);
end
endgenerate
 
assign o_m_wb_ack = i_m_wb_ack;
assign o_m_wb_err = i_m_wb_err;
assign o_m_wb_adr = i_m_wb_adr;
assign o_m_wb_we = i_m_wb_we ;
assign o_m_wb_cyc = i_m_wb_cyc;
assign o_m_wb_stb = i_m_wb_stb;
 
 
// =========================
// Slave interface - no endian conversion
// =========================
generate
if (WB_DWIDTH == 128)
begin : wbs128
assign o_s_wb_wdat = i_s_wb_adr[3:2] == 2'd3 ? i_s_wb_wdat[127:96] :
i_s_wb_adr[3:2] == 2'd2 ? i_s_wb_wdat[ 95:64] :
i_s_wb_adr[3:2] == 2'd1 ? i_s_wb_wdat[ 63:32] :
i_s_wb_wdat[ 31: 0] ;
assign o_s_wb_sel = i_s_wb_adr[3:2] == 2'd3 ? i_s_wb_sel[15:12] :
i_s_wb_adr[3:2] == 2'd2 ? i_s_wb_sel[11: 8] :
i_s_wb_adr[3:2] == 2'd1 ? i_s_wb_sel[ 7: 4] :
i_s_wb_sel[ 3: 0] ;
assign o_s_wb_rdat = i_s_wb_adr[3:2] == 2'd3 ? { i_s_wb_rdat, 96'd0} :
i_s_wb_adr[3:2] == 2'd2 ? {32'd0, i_s_wb_rdat, 64'd0} :
i_s_wb_adr[3:2] == 2'd1 ? {64'd0, i_s_wb_rdat, 32'd0} :
{96'd0, i_s_wb_rdat } ;
end
else
begin : wbs32
assign o_s_wb_wdat = i_s_wb_wdat;
assign o_s_wb_sel = i_s_wb_sel;
assign o_s_wb_rdat = i_s_wb_rdat;
end
endgenerate
 
assign o_s_wb_ack = i_s_wb_ack;
assign o_s_wb_err = i_s_wb_err;
assign o_s_wb_adr = i_s_wb_adr;
assign o_s_wb_we = i_s_wb_we ;
assign o_s_wb_cyc = i_s_wb_cyc;
assign o_s_wb_stb = i_s_wb_stb;
 
endmodule
 
/amber/trunk/hw/vlog/system/interrupt_controller.v
40,14 → 40,17
//////////////////////////////////////////////////////////////////
 
 
module interrupt_controller (
module interrupt_controller #(
parameter WB_DWIDTH = 32,
parameter WB_SWIDTH = 4
)(
input i_clk,
 
input [31:0] i_wb_adr,
input [3:0] i_wb_sel,
input [WB_SWIDTH-1:0] i_wb_sel,
input i_wb_we,
output [31:0] o_wb_dat,
input [31:0] i_wb_dat,
output [WB_DWIDTH-1:0] o_wb_dat,
input [WB_DWIDTH-1:0] i_wb_dat,
input i_wb_cyc,
input i_wb_stb,
output o_wb_ack,
89,10 → 92,11
wire firq_1;
 
// Wishbone interface
reg [31:0] wb_rdata = 'd0;
reg [31:0] wb_rdata32 = 'd0;
wire wb_start_write;
wire wb_start_read;
reg wb_start_read_d1 = 'd0;
wire [31:0] wb_wdata32;
 
 
// ======================================================
107,12 → 111,28
always @( posedge i_clk )
wb_start_read_d1 <= wb_start_read;
 
assign o_wb_dat = wb_rdata;
 
assign o_wb_err = 1'd0;
assign o_wb_ack = i_wb_stb && ( wb_start_write || wb_start_read_d1 );
 
generate
if (WB_DWIDTH == 128)
begin : wb128
assign wb_wdata32 = i_wb_adr[3:2] == 2'd3 ? i_wb_dat[127:96] :
i_wb_adr[3:2] == 2'd2 ? i_wb_dat[ 95:64] :
i_wb_adr[3:2] == 2'd1 ? i_wb_dat[ 63:32] :
i_wb_dat[ 31: 0] ;
assign o_wb_dat = {4{wb_rdata32}};
end
else
begin : wb32
assign wb_wdata32 = i_wb_dat;
assign o_wb_dat = wb_rdata32;
end
endgenerate
 
 
// ======================================
// Interrupts
// ======================================
174,27 → 194,27
if ( wb_start_read )
case ( i_wb_adr[15:0] )
AMBER_IC_IRQ0_ENABLESET: wb_rdata <= irq0_enable_reg;
AMBER_IC_FIRQ0_ENABLESET: wb_rdata <= firq0_enable_reg;
AMBER_IC_IRQ0_RAWSTAT: wb_rdata <= raw_interrupts;
AMBER_IC_IRQ0_STATUS: wb_rdata <= irq0_interrupts;
AMBER_IC_FIRQ0_RAWSTAT: wb_rdata <= raw_interrupts;
AMBER_IC_FIRQ0_STATUS: wb_rdata <= firq0_interrupts;
AMBER_IC_IRQ0_ENABLESET: wb_rdata32 <= irq0_enable_reg;
AMBER_IC_FIRQ0_ENABLESET: wb_rdata32 <= firq0_enable_reg;
AMBER_IC_IRQ0_RAWSTAT: wb_rdata32 <= raw_interrupts;
AMBER_IC_IRQ0_STATUS: wb_rdata32 <= irq0_interrupts;
AMBER_IC_FIRQ0_RAWSTAT: wb_rdata32 <= raw_interrupts;
AMBER_IC_FIRQ0_STATUS: wb_rdata32 <= firq0_interrupts;
 
AMBER_IC_INT_SOFTSET_0: wb_rdata <= {31'd0, softint_0_reg};
AMBER_IC_INT_SOFTCLEAR_0: wb_rdata <= {31'd0, softint_0_reg};
AMBER_IC_INT_SOFTSET_0: wb_rdata32 <= {31'd0, softint_0_reg};
AMBER_IC_INT_SOFTCLEAR_0: wb_rdata32 <= {31'd0, softint_0_reg};
 
AMBER_IC_IRQ1_ENABLESET: wb_rdata <= irq1_enable_reg;
AMBER_IC_FIRQ1_ENABLESET: wb_rdata <= firq1_enable_reg;
AMBER_IC_IRQ1_RAWSTAT: wb_rdata <= raw_interrupts;
AMBER_IC_IRQ1_STATUS: wb_rdata <= irq1_interrupts;
AMBER_IC_FIRQ1_RAWSTAT: wb_rdata <= raw_interrupts;
AMBER_IC_FIRQ1_STATUS: wb_rdata <= firq1_interrupts;
AMBER_IC_IRQ1_ENABLESET: wb_rdata32 <= irq1_enable_reg;
AMBER_IC_FIRQ1_ENABLESET: wb_rdata32 <= firq1_enable_reg;
AMBER_IC_IRQ1_RAWSTAT: wb_rdata32 <= raw_interrupts;
AMBER_IC_IRQ1_STATUS: wb_rdata32 <= irq1_interrupts;
AMBER_IC_FIRQ1_RAWSTAT: wb_rdata32 <= raw_interrupts;
AMBER_IC_FIRQ1_STATUS: wb_rdata32 <= firq1_interrupts;
 
AMBER_IC_INT_SOFTSET_1: wb_rdata <= {31'd0, softint_1_reg};
AMBER_IC_INT_SOFTCLEAR_1: wb_rdata <= {31'd0, softint_1_reg};
AMBER_IC_INT_SOFTSET_1: wb_rdata32 <= {31'd0, softint_1_reg};
AMBER_IC_INT_SOFTCLEAR_1: wb_rdata32 <= {31'd0, softint_1_reg};
default: wb_rdata <= 32'h22334455;
default: wb_rdata32 <= 32'h22334455;
endcase
 
/amber/trunk/hw/vlog/system/boot_mem.v
42,15 → 42,17
//////////////////////////////////////////////////////////////////
 
 
module boot_mem
(
module boot_mem #(
parameter WB_DWIDTH = 32,
parameter WB_SWIDTH = 4
)(
input i_wb_clk, // WISHBONE clock
 
input [31:0] i_wb_adr,
input [3:0] i_wb_sel,
input [WB_SWIDTH-1:0] i_wb_sel,
input i_wb_we,
output [31:0] o_wb_dat,
input [31:0] i_wb_dat,
output [WB_DWIDTH-1:0] o_wb_dat,
input [WB_DWIDTH-1:0] i_wb_dat,
input i_wb_cyc,
input i_wb_stb,
output o_wb_ack,
60,7 → 62,12
 
wire start_write, start_read;
reg start_read_d1 = 'd0;
wire [31:0] read_data;
wire [31:0] write_data;
wire [3:0] byte_enable;
wire [10:0] address;
 
 
// Can't start a write while a read is completing. The ack for the read cycle
// needs to be sent first
assign start_write = i_wb_stb && i_wb_we && !start_read_d1;
70,9 → 77,70
always @( posedge i_wb_clk )
start_read_d1 <= start_read;
 
assign o_wb_ack = i_wb_stb && ( start_write || start_read_d1 );
assign o_wb_err = 1'd0;
 
 
generate
if (WB_DWIDTH == 128)
begin : wb128
reg [31:0] read_data_r1 = 'd0;
reg [31:0] read_data_r2 = 'd0;
reg [31:0] read_data_r3 = 'd0;
reg [2:0] access_r = 'd0;
reg idle_r = 1'd1;
assign write_data = i_wb_adr[3:2] == 2'd3 ? i_wb_dat[127:96] :
i_wb_adr[3:2] == 2'd2 ? i_wb_dat[ 95:64] :
i_wb_adr[3:2] == 2'd1 ? i_wb_dat[ 63:32] :
i_wb_dat[ 31: 0] ;
assign byte_enable = i_wb_adr[3:2] == 2'd3 ? i_wb_sel[15:12] :
i_wb_adr[3:2] == 2'd2 ? i_wb_sel[11: 8] :
i_wb_adr[3:2] == 2'd1 ? i_wb_sel[ 7: 4] :
i_wb_sel[ 3: 0] ;
assign o_wb_dat = {read_data, read_data_r1, read_data_r2, read_data_r3};
 
// 4-Word burst accesses
always @(posedge i_wb_clk)
begin
read_data_r1 <= read_data;
read_data_r2 <= read_data_r1;
read_data_r3 <= read_data_r2;
if (idle_r)
begin
// start read of 4
if (i_wb_stb && !i_wb_we)
begin
idle_r <= 1'd0;
access_r <= access_r + 1'd1;
end
end
else if (access_r == 3'd4)
begin
access_r <= 3'd0;
idle_r <= 1'd1;
end
else
access_r <= access_r + 1'd1;
end
 
assign address = start_write ? i_wb_adr[12:2] : {i_wb_adr[12:4],2'd0} + access_r;
assign o_wb_ack = access_r == 3'd4 || start_write;
end
else
begin : wb32
assign write_data = i_wb_dat;
assign byte_enable = i_wb_sel;
assign o_wb_dat = read_data;
assign address = i_wb_adr[12:2];
assign o_wb_ack = i_wb_stb && ( start_write || start_read_d1 );
end
endgenerate
 
 
 
// ------------------------------------------------------
// Instantiate SRAMs
// ------------------------------------------------------
112,10 → 180,10
u_mem (
.i_clk ( i_wb_clk ),
.i_write_enable ( start_write ),
.i_byte_enable ( i_wb_sel ),
.i_address ( i_wb_adr[12:2] ), // 2048 words, 32 bits
.o_read_data ( o_wb_dat ),
.i_write_data ( i_wb_dat )
.i_byte_enable ( byte_enable ),
.i_address ( address ), // 2048 words, 32 bits
.o_read_data ( read_data ),
.i_write_data ( write_data )
);
 
 
/amber/trunk/hw/vlog/tb/tb.v
47,6 → 47,7
module tb();
 
`include "debug_functions.v"
`include "system_functions.v"
 
reg sysrst;
`ifdef XILINX_VIRTEX6_FPGA
74,6 → 75,8
integer fgets_return;
reg [120*8-1:0] line;
reg [120*8-1:0] aligned_line;
reg [8*16-1:0] test_name;
integer timeout = 0;
 
wire [12:0] ddr3_addr;
wire [2:0] ddr3_ba;
266,17 → 269,6
clk_count <= clk_count + 1'd1;
 
 
// ======================================
// Test Name
// ======================================
initial
begin
$display("Test %s, log file %s",`AMBER_TEST_NAME, `AMBER_LOG_FILE);
log_file = $fopen(`AMBER_LOG_FILE, "a");
end
 
 
// ======================================
// Initialize Boot Memory
330,6 → 322,15
$display("Read in %1d lines", boot_mem_line_count);
end
// Grab the test name from memory
timeout = tb.u_system.u_boot_mem.u_mem.mem [11'h7fb];
test_name = { endian_x32(tb.u_system.u_boot_mem.u_mem.mem [11'h7fc]),
endian_x32(tb.u_system.u_boot_mem.u_mem.mem [11'h7fd]),
endian_x32(tb.u_system.u_boot_mem.u_mem.mem [11'h7fe]),
endian_x32(tb.u_system.u_boot_mem.u_mem.mem [11'h7ff])};
$display("log file %s, timeout %0d, test name %0s ", `AMBER_LOG_FILE, timeout, test_name);
log_file = $fopen(`AMBER_LOG_FILE, "a");
end
`endif
442,12 → 443,14
`include "a23_functions.v"
`endif
 
reg testfail;
wire test_status_set;
wire [31:0] test_status_reg;
reg testfail;
wire test_status_set;
wire [31:0] test_status_reg;
 
initial
testfail = 1'd0;
begin
testfail = 1'd0;
end
assign test_status_set = `U_TEST_MODULE.test_status_set;
assign test_status_reg = `U_TEST_MODULE.test_status_reg;
460,9 → 463,9
begin
display_registers;
$display("++++++++++++++++++++");
$write("Passed %s %0d ticks\n", `AMBER_TEST_NAME, `U_TB.clk_count);
$write("Passed %s %0d ticks\n", test_name, `U_TB.clk_count);
$display("++++++++++++++++++++");
$fwrite(`U_TB.log_file,"Passed %s %0d ticks\n", `AMBER_TEST_NAME, `U_TB.clk_count);
$fwrite(`U_TB.log_file,"Passed %s %0d ticks\n", test_name, `U_TB.clk_count);
$finish;
end
else
471,9 → 474,9
if ( testfail )
begin
$display("++++++++++++++++++++");
$write("Failed %s\n", `AMBER_TEST_NAME);
$write("Failed %s\n", test_name);
$display("++++++++++++++++++++");
$fwrite(`U_TB.log_file,"Failed %s\n", `AMBER_TEST_NAME);
$fwrite(`U_TB.log_file,"Failed %s\n", test_name);
$finish;
end
else
480,14 → 483,14
begin
$display("++++++++++++++++++++");
if (test_status_reg >= 32'h8000)
$write("Failed %s - with error 0x%08x\n", `AMBER_TEST_NAME, test_status_reg);
$write("Failed %s - with error 0x%08x\n", test_name, test_status_reg);
else
$write("Failed %s - with error %1d\n", `AMBER_TEST_NAME, test_status_reg);
$write("Failed %s - with error on line %1d\n", test_name, test_status_reg);
$display("++++++++++++++++++++");
if (test_status_reg >= 32'h8000)
$fwrite(`U_TB.log_file,"Failed %s - with error 0x%08h\n", `AMBER_TEST_NAME, test_status_reg);
$fwrite(`U_TB.log_file,"Failed %s - with error 0x%08h\n", test_name, test_status_reg);
else
$fwrite(`U_TB.log_file,"Failed %s - with error %1d\n", `AMBER_TEST_NAME, test_status_reg);
$fwrite(`U_TB.log_file,"Failed %s - with error on line %1d\n", test_name, test_status_reg);
$finish;
end
end
499,8 → 502,8
// Timeout
// ======================================
always @ ( posedge `U_SYSTEM.sys_clk )
if ( `AMBER_TIMEOUT != 0 )
if (`U_TB.clk_count >= `AMBER_TIMEOUT)
if ( timeout != 0 )
if (`U_TB.clk_count >= timeout)
begin
`TB_ERROR_MESSAGE
$display("Timeout Error");
/amber/trunk/hw/vlog/amber25/a25_shifter.v
0,0 → 1,310
//////////////////////////////////////////////////////////////////
// //
// Barrel Shifter for Amber 25 Core //
// //
// This file is part of the Amber project //
// http://www.opencores.org/project,amber //
// //
// Description //
// Provides 32-bit shifts LSL, LSR, ASR and ROR //
// //
// Author(s): //
// - Conor Santifort, csantifort.amber@gmail.com //
// //
//////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2011 Authors and OPENCORES.ORG //
// //
// This source file may be used and distributed without //
// restriction provided that this copyright statement is not //
// removed from the file and that any derivative work contains //
// the original copyright notice and the associated disclaimer. //
// //
// This source file is free software; you can redistribute it //
// and/or modify it under the terms of the GNU Lesser General //
// Public License as published by the Free Software Foundation; //
// either version 2.1 of the License, or (at your option) any //
// later version. //
// //
// This source is distributed in the hope that it will be //
// useful, but WITHOUT ANY WARRANTY; without even the implied //
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
// PURPOSE. See the GNU Lesser General Public License for more //
// details. //
// //
// You should have received a copy of the GNU Lesser General //
// Public License along with this source; if not, download it //
// from http://www.opencores.org/lgpl.shtml //
// //
//////////////////////////////////////////////////////////////////
 
 
module a25_shifter #(
parameter FULL_BARREL = 1
)(
 
input [31:0] i_in,
input i_carry_in,
input [7:0] i_shift_amount, // uses 8 LSBs of Rs, or a 5 bit immediate constant
input i_shift_imm_zero, // high when immediate shift value of zero selected
input [1:0] i_function,
 
output [31:0] o_out,
output o_carry_out
 
);
 
`include "a25_localparams.v"
 
// MSB is carry out
wire [32:0] lsl_out;
wire [32:0] lsr_out;
wire [32:0] asr_out;
wire [32:0] ror_out;
 
 
// Logical shift right zero is redundant as it is the same as logical shift left zero, so
// the assembler will convert LSR #0 (and ASR #0 and ROR #0) into LSL #0, and allow
// lsr #32 to be specified.
 
// lsl #0 is a special case, where the shifter carry out is the old value of the status flags
// C flag. The contents of Rm are used directly as the second operand.
 
generate
if (FULL_BARREL == 1) begin : full_lsl
 
assign lsl_out = i_shift_imm_zero ? {i_carry_in, i_in } : // fall through case
 
i_shift_amount == 8'd 0 ? {i_carry_in, i_in } : // fall through case
i_shift_amount == 8'd 1 ? {i_in[31], i_in[30: 0], 1'd0} :
i_shift_amount == 8'd 2 ? {i_in[30], i_in[29: 0], 2'd0} :
i_shift_amount == 8'd 3 ? {i_in[29], i_in[28: 0], 3'd0} :
i_shift_amount == 8'd 4 ? {i_in[28], i_in[27: 0], 4'd0} :
i_shift_amount == 8'd 5 ? {i_in[27], i_in[26: 0], 5'd0} :
i_shift_amount == 8'd 6 ? {i_in[26], i_in[25: 0], 6'd0} :
i_shift_amount == 8'd 7 ? {i_in[25], i_in[24: 0], 7'd0} :
i_shift_amount == 8'd 8 ? {i_in[24], i_in[23: 0], 8'd0} :
i_shift_amount == 8'd 9 ? {i_in[23], i_in[22: 0], 9'd0} :
i_shift_amount == 8'd10 ? {i_in[22], i_in[21: 0], 10'd0} :
i_shift_amount == 8'd11 ? {i_in[21], i_in[20: 0], 11'd0} :
i_shift_amount == 8'd12 ? {i_in[20], i_in[19: 0], 12'd0} :
i_shift_amount == 8'd13 ? {i_in[19], i_in[18: 0], 13'd0} :
i_shift_amount == 8'd14 ? {i_in[18], i_in[17: 0], 14'd0} :
i_shift_amount == 8'd15 ? {i_in[17], i_in[16: 0], 15'd0} :
i_shift_amount == 8'd16 ? {i_in[16], i_in[15: 0], 16'd0} :
i_shift_amount == 8'd17 ? {i_in[15], i_in[14: 0], 17'd0} :
i_shift_amount == 8'd18 ? {i_in[14], i_in[13: 0], 18'd0} :
i_shift_amount == 8'd19 ? {i_in[13], i_in[12: 0], 19'd0} :
i_shift_amount == 8'd20 ? {i_in[12], i_in[11: 0], 20'd0} :
i_shift_amount == 8'd21 ? {i_in[11], i_in[10: 0], 21'd0} :
 
i_shift_amount == 8'd22 ? {i_in[10], i_in[ 9: 0], 22'd0} :
i_shift_amount == 8'd23 ? {i_in[ 9], i_in[ 8: 0], 23'd0} :
i_shift_amount == 8'd24 ? {i_in[ 8], i_in[ 7: 0], 24'd0} :
i_shift_amount == 8'd25 ? {i_in[ 7], i_in[ 6: 0], 25'd0} :
i_shift_amount == 8'd26 ? {i_in[ 6], i_in[ 5: 0], 26'd0} :
i_shift_amount == 8'd27 ? {i_in[ 5], i_in[ 4: 0], 27'd0} :
i_shift_amount == 8'd28 ? {i_in[ 4], i_in[ 3: 0], 28'd0} :
i_shift_amount == 8'd29 ? {i_in[ 3], i_in[ 2: 0], 29'd0} :
i_shift_amount == 8'd30 ? {i_in[ 2], i_in[ 1: 0], 30'd0} :
i_shift_amount == 8'd31 ? {i_in[ 1], i_in[ 0: 0], 31'd0} :
i_shift_amount == 8'd32 ? {i_in[ 0], 32'd0 } : // 32
{1'd0, 32'd0 } ; // > 32
end
else begin : quick_lsl
 
// only gives the correct result if the shift value is < 4
assign lsl_out = i_shift_imm_zero ? {i_carry_in, i_in } : // fall through case
i_shift_amount == 2'd0 ? {i_carry_in, i_in } : // fall through case
i_shift_amount == 2'd1 ? {i_in[31], i_in[30: 0], 1'd0} :
i_shift_amount == 2'd2 ? {i_in[30], i_in[29: 0], 2'd0} :
{i_in[29], i_in[28: 0], 3'd0} ; // 3
 
end
endgenerate
 
 
// The form of the shift field which might be expected to correspond to LSR #0 is used
// to encode LSR #32, which has a zero result with bit 31 of Rm as the carry output.
generate
if (FULL_BARREL == 1) begin : full_lsr
 
// carry out, < -------- out ---------->
assign lsr_out = i_shift_imm_zero ? {i_in[31], 32'd0 } :
i_shift_amount == 8'd 0 ? {i_carry_in, i_in } : // fall through case
i_shift_amount == 8'd 1 ? {i_in[ 0], 1'd0, i_in[31: 1]} :
i_shift_amount == 8'd 2 ? {i_in[ 1], 2'd0, i_in[31: 2]} :
i_shift_amount == 8'd 3 ? {i_in[ 2], 3'd0, i_in[31: 3]} :
i_shift_amount == 8'd 4 ? {i_in[ 3], 4'd0, i_in[31: 4]} :
i_shift_amount == 8'd 5 ? {i_in[ 4], 5'd0, i_in[31: 5]} :
i_shift_amount == 8'd 6 ? {i_in[ 5], 6'd0, i_in[31: 6]} :
i_shift_amount == 8'd 7 ? {i_in[ 6], 7'd0, i_in[31: 7]} :
i_shift_amount == 8'd 8 ? {i_in[ 7], 8'd0, i_in[31: 8]} :
i_shift_amount == 8'd 9 ? {i_in[ 8], 9'd0, i_in[31: 9]} :
i_shift_amount == 8'd10 ? {i_in[ 9], 10'd0, i_in[31:10]} :
i_shift_amount == 8'd11 ? {i_in[10], 11'd0, i_in[31:11]} :
i_shift_amount == 8'd12 ? {i_in[11], 12'd0, i_in[31:12]} :
i_shift_amount == 8'd13 ? {i_in[12], 13'd0, i_in[31:13]} :
i_shift_amount == 8'd14 ? {i_in[13], 14'd0, i_in[31:14]} :
i_shift_amount == 8'd15 ? {i_in[14], 15'd0, i_in[31:15]} :
i_shift_amount == 8'd16 ? {i_in[15], 16'd0, i_in[31:16]} :
i_shift_amount == 8'd17 ? {i_in[16], 17'd0, i_in[31:17]} :
i_shift_amount == 8'd18 ? {i_in[17], 18'd0, i_in[31:18]} :
i_shift_amount == 8'd19 ? {i_in[18], 19'd0, i_in[31:19]} :
 
i_shift_amount == 8'd20 ? {i_in[19], 20'd0, i_in[31:20]} :
i_shift_amount == 8'd21 ? {i_in[20], 21'd0, i_in[31:21]} :
i_shift_amount == 8'd22 ? {i_in[21], 22'd0, i_in[31:22]} :
i_shift_amount == 8'd23 ? {i_in[22], 23'd0, i_in[31:23]} :
i_shift_amount == 8'd24 ? {i_in[23], 24'd0, i_in[31:24]} :
i_shift_amount == 8'd25 ? {i_in[24], 25'd0, i_in[31:25]} :
i_shift_amount == 8'd26 ? {i_in[25], 26'd0, i_in[31:26]} :
i_shift_amount == 8'd27 ? {i_in[26], 27'd0, i_in[31:27]} :
i_shift_amount == 8'd28 ? {i_in[27], 28'd0, i_in[31:28]} :
i_shift_amount == 8'd29 ? {i_in[28], 29'd0, i_in[31:29]} :
 
i_shift_amount == 8'd30 ? {i_in[29], 30'd0, i_in[31:30]} :
i_shift_amount == 8'd31 ? {i_in[30], 31'd0, i_in[31 ]} :
i_shift_amount == 8'd32 ? {i_in[31], 32'd0 } :
{1'd0, 32'd0 } ; // > 32
 
end
else begin : quick_lsr
 
// only gives the correct result if the shift value is < 4
assign lsr_out = i_shift_imm_zero ? {i_in[31], 32'd0 } :
i_shift_amount[1:0] == 2'd0 ? {i_carry_in, i_in } : // fall through case
i_shift_amount[1:0] == 2'd1 ? {i_in[ 0], 1'd0, i_in[31: 1]} :
i_shift_amount[1:0] == 2'd2 ? {i_in[ 1], 2'd0, i_in[31: 2]} :
{i_in[ 2], 3'd0, i_in[31: 3]} ; // 3
 
end
endgenerate
 
// The form of the shift field which might be expected to give ASR #0 is used to encode
// ASR #32. Bit 31 of Rm is again used as the carry output, and each bit of operand 2 is
// also equal to bit 31 of Rm. The result is therefore all ones or all zeros, according to
// the value of bit 31 of Rm.
 
generate
if (FULL_BARREL == 1) begin : full_asr
 
// carry out, < -------- out ---------->
assign asr_out = i_shift_imm_zero ? {i_in[31], {32{i_in[31]}} } :
i_shift_amount == 8'd 0 ? {i_carry_in, i_in } : // fall through case
i_shift_amount == 8'd 1 ? {i_in[ 0], { 2{i_in[31]}}, i_in[30: 1]} :
i_shift_amount == 8'd 2 ? {i_in[ 1], { 3{i_in[31]}}, i_in[30: 2]} :
i_shift_amount == 8'd 3 ? {i_in[ 2], { 4{i_in[31]}}, i_in[30: 3]} :
i_shift_amount == 8'd 4 ? {i_in[ 3], { 5{i_in[31]}}, i_in[30: 4]} :
i_shift_amount == 8'd 5 ? {i_in[ 4], { 6{i_in[31]}}, i_in[30: 5]} :
i_shift_amount == 8'd 6 ? {i_in[ 5], { 7{i_in[31]}}, i_in[30: 6]} :
i_shift_amount == 8'd 7 ? {i_in[ 6], { 8{i_in[31]}}, i_in[30: 7]} :
i_shift_amount == 8'd 8 ? {i_in[ 7], { 9{i_in[31]}}, i_in[30: 8]} :
i_shift_amount == 8'd 9 ? {i_in[ 8], {10{i_in[31]}}, i_in[30: 9]} :
i_shift_amount == 8'd10 ? {i_in[ 9], {11{i_in[31]}}, i_in[30:10]} :
i_shift_amount == 8'd11 ? {i_in[10], {12{i_in[31]}}, i_in[30:11]} :
i_shift_amount == 8'd12 ? {i_in[11], {13{i_in[31]}}, i_in[30:12]} :
i_shift_amount == 8'd13 ? {i_in[12], {14{i_in[31]}}, i_in[30:13]} :
i_shift_amount == 8'd14 ? {i_in[13], {15{i_in[31]}}, i_in[30:14]} :
i_shift_amount == 8'd15 ? {i_in[14], {16{i_in[31]}}, i_in[30:15]} :
i_shift_amount == 8'd16 ? {i_in[15], {17{i_in[31]}}, i_in[30:16]} :
i_shift_amount == 8'd17 ? {i_in[16], {18{i_in[31]}}, i_in[30:17]} :
i_shift_amount == 8'd18 ? {i_in[17], {19{i_in[31]}}, i_in[30:18]} :
i_shift_amount == 8'd19 ? {i_in[18], {20{i_in[31]}}, i_in[30:19]} :
 
i_shift_amount == 8'd20 ? {i_in[19], {21{i_in[31]}}, i_in[30:20]} :
i_shift_amount == 8'd21 ? {i_in[20], {22{i_in[31]}}, i_in[30:21]} :
i_shift_amount == 8'd22 ? {i_in[21], {23{i_in[31]}}, i_in[30:22]} :
i_shift_amount == 8'd23 ? {i_in[22], {24{i_in[31]}}, i_in[30:23]} :
i_shift_amount == 8'd24 ? {i_in[23], {25{i_in[31]}}, i_in[30:24]} :
i_shift_amount == 8'd25 ? {i_in[24], {26{i_in[31]}}, i_in[30:25]} :
i_shift_amount == 8'd26 ? {i_in[25], {27{i_in[31]}}, i_in[30:26]} :
i_shift_amount == 8'd27 ? {i_in[26], {28{i_in[31]}}, i_in[30:27]} :
i_shift_amount == 8'd28 ? {i_in[27], {29{i_in[31]}}, i_in[30:28]} :
i_shift_amount == 8'd29 ? {i_in[28], {30{i_in[31]}}, i_in[30:29]} :
i_shift_amount == 8'd30 ? {i_in[29], {31{i_in[31]}}, i_in[30 ]} :
i_shift_amount == 8'd31 ? {i_in[30], {32{i_in[31]}} } :
{i_in[31], {32{i_in[31]}} } ; // >= 32
 
end
else begin : quick_asr
 
// only gives the correct result if the shift value is < 4
assign asr_out = i_shift_imm_zero ? {i_in[31], {32{i_in[31]}} } :
i_shift_amount[1:0] == 2'd0 ? {i_carry_in, i_in } : // fall through case
i_shift_amount[1:0] == 2'd1 ? {i_in[ 0], { 2{i_in[31]}}, i_in[30: 1]} :
i_shift_amount[1:0] == 2'd2 ? {i_in[ 1], { 3{i_in[31]}}, i_in[30: 2]} :
{i_in[ 2], { 4{i_in[31]}}, i_in[30: 3]} ; // 3
 
end
endgenerate
 
 
generate
if (FULL_BARREL == 1) begin : full_ror
 
// carry out, < ------- out --------->
assign ror_out = i_shift_imm_zero ? {i_in[ 0], i_carry_in, i_in[31: 1]} : // RXR, (ROR w/ imm 0)
 
i_shift_amount[7:0] == 8'd 0 ? {i_carry_in, i_in } : // fall through case
i_shift_amount[4:0] == 5'd 0 ? {i_in[31], i_in } : // Rs > 31
i_shift_amount[4:0] == 5'd 1 ? {i_in[ 0], i_in[ 0], i_in[31: 1]} :
i_shift_amount[4:0] == 5'd 2 ? {i_in[ 1], i_in[ 1: 0], i_in[31: 2]} :
i_shift_amount[4:0] == 5'd 3 ? {i_in[ 2], i_in[ 2: 0], i_in[31: 3]} :
i_shift_amount[4:0] == 5'd 4 ? {i_in[ 3], i_in[ 3: 0], i_in[31: 4]} :
i_shift_amount[4:0] == 5'd 5 ? {i_in[ 4], i_in[ 4: 0], i_in[31: 5]} :
i_shift_amount[4:0] == 5'd 6 ? {i_in[ 5], i_in[ 5: 0], i_in[31: 6]} :
i_shift_amount[4:0] == 5'd 7 ? {i_in[ 6], i_in[ 6: 0], i_in[31: 7]} :
i_shift_amount[4:0] == 5'd 8 ? {i_in[ 7], i_in[ 7: 0], i_in[31: 8]} :
i_shift_amount[4:0] == 5'd 9 ? {i_in[ 8], i_in[ 8: 0], i_in[31: 9]} :
i_shift_amount[4:0] == 5'd10 ? {i_in[ 9], i_in[ 9: 0], i_in[31:10]} :
i_shift_amount[4:0] == 5'd11 ? {i_in[10], i_in[10: 0], i_in[31:11]} :
i_shift_amount[4:0] == 5'd12 ? {i_in[11], i_in[11: 0], i_in[31:12]} :
i_shift_amount[4:0] == 5'd13 ? {i_in[12], i_in[12: 0], i_in[31:13]} :
i_shift_amount[4:0] == 5'd14 ? {i_in[13], i_in[13: 0], i_in[31:14]} :
i_shift_amount[4:0] == 5'd15 ? {i_in[14], i_in[14: 0], i_in[31:15]} :
i_shift_amount[4:0] == 5'd16 ? {i_in[15], i_in[15: 0], i_in[31:16]} :
i_shift_amount[4:0] == 5'd17 ? {i_in[16], i_in[16: 0], i_in[31:17]} :
i_shift_amount[4:0] == 5'd18 ? {i_in[17], i_in[17: 0], i_in[31:18]} :
i_shift_amount[4:0] == 5'd19 ? {i_in[18], i_in[18: 0], i_in[31:19]} :
 
i_shift_amount[4:0] == 5'd20 ? {i_in[19], i_in[19: 0], i_in[31:20]} :
i_shift_amount[4:0] == 5'd21 ? {i_in[20], i_in[20: 0], i_in[31:21]} :
i_shift_amount[4:0] == 5'd22 ? {i_in[21], i_in[21: 0], i_in[31:22]} :
i_shift_amount[4:0] == 5'd23 ? {i_in[22], i_in[22: 0], i_in[31:23]} :
i_shift_amount[4:0] == 5'd24 ? {i_in[23], i_in[23: 0], i_in[31:24]} :
i_shift_amount[4:0] == 5'd25 ? {i_in[24], i_in[24: 0], i_in[31:25]} :
i_shift_amount[4:0] == 5'd26 ? {i_in[25], i_in[25: 0], i_in[31:26]} :
i_shift_amount[4:0] == 5'd27 ? {i_in[26], i_in[26: 0], i_in[31:27]} :
i_shift_amount[4:0] == 5'd28 ? {i_in[27], i_in[27: 0], i_in[31:28]} :
i_shift_amount[4:0] == 5'd29 ? {i_in[28], i_in[28: 0], i_in[31:29]} :
 
i_shift_amount[4:0] == 5'd30 ? {i_in[29], i_in[29: 0], i_in[31:30]} :
{i_in[30], i_in[30: 0], i_in[31:31]} ;
 
end
else begin : quick_ror
// only gives the correct result if the shift value is < 4
assign ror_out = i_shift_imm_zero ? {i_in[ 0], i_carry_in, i_in[31: 1]} : // RXR, (ROR w/ imm 0)
i_shift_amount[1:0] == 2'd0 ? {i_carry_in, i_in } : // fall through case
i_shift_amount[1:0] == 2'd1 ? {i_in[ 0], i_in[ 0], i_in[31: 1]} :
i_shift_amount[1:0] == 2'd2 ? {i_in[ 1], i_in[ 1: 0], i_in[31: 2]} :
{i_in[ 2], i_in[ 2: 0], i_in[31: 3]} ; // 3
 
end
endgenerate
assign {o_carry_out, o_out} = i_function == LSL ? lsl_out :
i_function == LSR ? lsr_out :
i_function == ASR ? asr_out :
ror_out ;
 
endmodule
 
 
/amber/trunk/hw/vlog/amber25/a25_barrel_shift.v
41,6 → 41,7
 
module a25_barrel_shift (
 
input i_clk,
input [31:0] i_in,
input i_carry_in,
input [7:0] i_shift_amount, // uses 8 LSBs of Rs, or a 5 bit immediate constant
48,204 → 49,66
input [1:0] i_function,
 
output [31:0] o_out,
output o_carry_out
output o_carry_out,
output o_stall
 
);
 
`include "a25_localparams.v"
 
// MSB is carry out
wire [32:0] lsl_out;
wire [32:0] lsr_out;
wire [32:0] asr_out;
wire [32:0] ror_out;
wire [31:0] quick_out;
wire quick_carry_out;
wire [31:0] full_out;
wire full_carry_out;
reg [31:0] full_out_r = 'd0;
reg full_carry_out_r = 'd0;
reg use_quick_r = 1'd1;
 
 
// Logical shift right zero is redundant as it is the same as logical shift left zero, so
// the assembler will convert LSR #0 (and ASR #0 and ROR #0) into LSL #0, and allow
// lsr #32 to be specified.
assign o_stall = (|i_shift_amount[7:2]) & use_quick_r;
assign o_out = use_quick_r ? quick_out : full_out_r;
assign o_carry_out = use_quick_r ? quick_carry_out : full_carry_out_r;
 
// lsl #0 is a special case, where the shifter carry out is the old value of the status flags
// C flag. The contents of Rm are used directly as the second operand.
assign lsl_out = i_shift_imm_zero ? {i_carry_in, i_in } : // fall through case
 
i_shift_amount == 8'd 0 ? {i_carry_in, i_in } : // fall through case
i_shift_amount == 8'd 1 ? {i_in[31], i_in[30: 0], 1'd0} :
i_shift_amount == 8'd 2 ? {i_in[30], i_in[29: 0], 2'd0} :
i_shift_amount == 8'd 3 ? {i_in[29], i_in[28: 0], 3'd0} :
i_shift_amount == 8'd 4 ? {i_in[28], i_in[27: 0], 4'd0} :
i_shift_amount == 8'd 5 ? {i_in[27], i_in[26: 0], 5'd0} :
i_shift_amount == 8'd 6 ? {i_in[26], i_in[25: 0], 6'd0} :
i_shift_amount == 8'd 7 ? {i_in[25], i_in[24: 0], 7'd0} :
i_shift_amount == 8'd 8 ? {i_in[24], i_in[23: 0], 8'd0} :
i_shift_amount == 8'd 9 ? {i_in[23], i_in[22: 0], 9'd0} :
i_shift_amount == 8'd10 ? {i_in[22], i_in[21: 0], 10'd0} :
i_shift_amount == 8'd11 ? {i_in[21], i_in[20: 0], 11'd0} :
i_shift_amount == 8'd12 ? {i_in[20], i_in[19: 0], 12'd0} :
i_shift_amount == 8'd13 ? {i_in[19], i_in[18: 0], 13'd0} :
i_shift_amount == 8'd14 ? {i_in[18], i_in[17: 0], 14'd0} :
i_shift_amount == 8'd15 ? {i_in[17], i_in[16: 0], 15'd0} :
i_shift_amount == 8'd16 ? {i_in[16], i_in[15: 0], 16'd0} :
i_shift_amount == 8'd17 ? {i_in[15], i_in[14: 0], 17'd0} :
i_shift_amount == 8'd18 ? {i_in[14], i_in[13: 0], 18'd0} :
i_shift_amount == 8'd19 ? {i_in[13], i_in[12: 0], 19'd0} :
i_shift_amount == 8'd20 ? {i_in[12], i_in[11: 0], 20'd0} :
i_shift_amount == 8'd21 ? {i_in[11], i_in[10: 0], 21'd0} :
// Capture the result from the full barrel shifter in case the
// quick shifter gives the wrong value
always @(posedge i_clk)
begin
full_out_r <= full_out;
full_carry_out_r <= full_carry_out;
use_quick_r <= !o_stall;
end
 
i_shift_amount == 8'd22 ? {i_in[10], i_in[ 9: 0], 22'd0} :
i_shift_amount == 8'd23 ? {i_in[ 9], i_in[ 8: 0], 23'd0} :
i_shift_amount == 8'd24 ? {i_in[ 8], i_in[ 7: 0], 24'd0} :
i_shift_amount == 8'd25 ? {i_in[ 7], i_in[ 6: 0], 25'd0} :
i_shift_amount == 8'd26 ? {i_in[ 6], i_in[ 5: 0], 26'd0} :
i_shift_amount == 8'd27 ? {i_in[ 5], i_in[ 4: 0], 27'd0} :
i_shift_amount == 8'd28 ? {i_in[ 4], i_in[ 3: 0], 28'd0} :
i_shift_amount == 8'd29 ? {i_in[ 3], i_in[ 2: 0], 29'd0} :
i_shift_amount == 8'd30 ? {i_in[ 2], i_in[ 1: 0], 30'd0} :
i_shift_amount == 8'd31 ? {i_in[ 1], i_in[ 0: 0], 31'd0} :
i_shift_amount == 8'd32 ? {i_in[ 0], 32'd0 } : // 32
{1'd0, 32'd0 } ; // > 32
 
// The form of the shift field which might be expected to correspond to LSR #0 is used
// to encode LSR #32, which has a zero result with bit 31 of Rm as the carry output.
// carry out, < -------- out ---------->
assign lsr_out = i_shift_imm_zero ? {i_in[31], 32'd0 } :
// Full barrel shifter
a25_shifter #(
.FULL_BARREL (1)
)
u_a25_shifter_full (
.i_in ( i_in ),
.i_carry_in ( i_carry_in ),
.i_shift_amount ( i_shift_amount ),
.i_shift_imm_zero ( i_shift_imm_zero ),
.i_function ( i_function ),
.o_out ( full_out ),
.o_carry_out ( full_carry_out )
);
 
i_shift_amount == 8'd 0 ? {i_carry_in, i_in } : // fall through case
i_shift_amount == 8'd 1 ? {i_in[ 0], 1'd0, i_in[31: 1]} :
i_shift_amount == 8'd 2 ? {i_in[ 1], 2'd0, i_in[31: 2]} :
i_shift_amount == 8'd 3 ? {i_in[ 2], 3'd0, i_in[31: 3]} :
i_shift_amount == 8'd 4 ? {i_in[ 3], 4'd0, i_in[31: 4]} :
i_shift_amount == 8'd 5 ? {i_in[ 4], 5'd0, i_in[31: 5]} :
i_shift_amount == 8'd 6 ? {i_in[ 5], 6'd0, i_in[31: 6]} :
i_shift_amount == 8'd 7 ? {i_in[ 6], 7'd0, i_in[31: 7]} :
i_shift_amount == 8'd 8 ? {i_in[ 7], 8'd0, i_in[31: 8]} :
i_shift_amount == 8'd 9 ? {i_in[ 8], 9'd0, i_in[31: 9]} :
i_shift_amount == 8'd10 ? {i_in[ 9], 10'd0, i_in[31:10]} :
i_shift_amount == 8'd11 ? {i_in[10], 11'd0, i_in[31:11]} :
i_shift_amount == 8'd12 ? {i_in[11], 12'd0, i_in[31:12]} :
i_shift_amount == 8'd13 ? {i_in[12], 13'd0, i_in[31:13]} :
i_shift_amount == 8'd14 ? {i_in[13], 14'd0, i_in[31:14]} :
i_shift_amount == 8'd15 ? {i_in[14], 15'd0, i_in[31:15]} :
i_shift_amount == 8'd16 ? {i_in[15], 16'd0, i_in[31:16]} :
i_shift_amount == 8'd17 ? {i_in[16], 17'd0, i_in[31:17]} :
i_shift_amount == 8'd18 ? {i_in[17], 18'd0, i_in[31:18]} :
i_shift_amount == 8'd19 ? {i_in[18], 19'd0, i_in[31:19]} :
 
i_shift_amount == 8'd20 ? {i_in[19], 20'd0, i_in[31:20]} :
i_shift_amount == 8'd21 ? {i_in[20], 21'd0, i_in[31:21]} :
i_shift_amount == 8'd22 ? {i_in[21], 22'd0, i_in[31:22]} :
i_shift_amount == 8'd23 ? {i_in[22], 23'd0, i_in[31:23]} :
i_shift_amount == 8'd24 ? {i_in[23], 24'd0, i_in[31:24]} :
i_shift_amount == 8'd25 ? {i_in[24], 25'd0, i_in[31:25]} :
i_shift_amount == 8'd26 ? {i_in[25], 26'd0, i_in[31:26]} :
i_shift_amount == 8'd27 ? {i_in[26], 27'd0, i_in[31:27]} :
i_shift_amount == 8'd28 ? {i_in[27], 28'd0, i_in[31:28]} :
i_shift_amount == 8'd29 ? {i_in[28], 29'd0, i_in[31:29]} :
 
i_shift_amount == 8'd30 ? {i_in[29], 30'd0, i_in[31:30]} :
i_shift_amount == 8'd31 ? {i_in[30], 31'd0, i_in[31 ]} :
i_shift_amount == 8'd32 ? {i_in[31], 32'd0 } :
{1'd0, 32'd0 } ; // > 32
// Quick barrel shifter
a25_shifter #(
.FULL_BARREL ( 0 )
)
u_a25_shifter_quick (
.i_in ( i_in ),
.i_carry_in ( i_carry_in ),
.i_shift_amount ( i_shift_amount ),
.i_shift_imm_zero ( i_shift_imm_zero ),
.i_function ( i_function ),
.o_out ( quick_out ),
.o_carry_out ( quick_carry_out )
);
 
 
// The form of the shift field which might be expected to give ASR #0 is used to encode
// ASR #32. Bit 31 of Rm is again used as the carry output, and each bit of operand 2 is
// also equal to bit 31 of Rm. The result is therefore all ones or all zeros, according to
// the value of bit 31 of Rm.
 
// carry out, < -------- out ---------->
assign asr_out = i_shift_imm_zero ? {i_in[31], {32{i_in[31]}} } :
 
i_shift_amount == 8'd 0 ? {i_carry_in, i_in } : // fall through case
i_shift_amount == 8'd 1 ? {i_in[ 0], { 2{i_in[31]}}, i_in[30: 1]} :
i_shift_amount == 8'd 2 ? {i_in[ 1], { 3{i_in[31]}}, i_in[30: 2]} :
i_shift_amount == 8'd 3 ? {i_in[ 2], { 4{i_in[31]}}, i_in[30: 3]} :
i_shift_amount == 8'd 4 ? {i_in[ 3], { 5{i_in[31]}}, i_in[30: 4]} :
i_shift_amount == 8'd 5 ? {i_in[ 4], { 6{i_in[31]}}, i_in[30: 5]} :
i_shift_amount == 8'd 6 ? {i_in[ 5], { 7{i_in[31]}}, i_in[30: 6]} :
i_shift_amount == 8'd 7 ? {i_in[ 6], { 8{i_in[31]}}, i_in[30: 7]} :
i_shift_amount == 8'd 8 ? {i_in[ 7], { 9{i_in[31]}}, i_in[30: 8]} :
i_shift_amount == 8'd 9 ? {i_in[ 8], {10{i_in[31]}}, i_in[30: 9]} :
i_shift_amount == 8'd10 ? {i_in[ 9], {11{i_in[31]}}, i_in[30:10]} :
i_shift_amount == 8'd11 ? {i_in[10], {12{i_in[31]}}, i_in[30:11]} :
i_shift_amount == 8'd12 ? {i_in[11], {13{i_in[31]}}, i_in[30:12]} :
i_shift_amount == 8'd13 ? {i_in[12], {14{i_in[31]}}, i_in[30:13]} :
i_shift_amount == 8'd14 ? {i_in[13], {15{i_in[31]}}, i_in[30:14]} :
i_shift_amount == 8'd15 ? {i_in[14], {16{i_in[31]}}, i_in[30:15]} :
i_shift_amount == 8'd16 ? {i_in[15], {17{i_in[31]}}, i_in[30:16]} :
i_shift_amount == 8'd17 ? {i_in[16], {18{i_in[31]}}, i_in[30:17]} :
i_shift_amount == 8'd18 ? {i_in[17], {19{i_in[31]}}, i_in[30:18]} :
i_shift_amount == 8'd19 ? {i_in[18], {20{i_in[31]}}, i_in[30:19]} :
 
i_shift_amount == 8'd20 ? {i_in[19], {21{i_in[31]}}, i_in[30:20]} :
i_shift_amount == 8'd21 ? {i_in[20], {22{i_in[31]}}, i_in[30:21]} :
i_shift_amount == 8'd22 ? {i_in[21], {23{i_in[31]}}, i_in[30:22]} :
i_shift_amount == 8'd23 ? {i_in[22], {24{i_in[31]}}, i_in[30:23]} :
i_shift_amount == 8'd24 ? {i_in[23], {25{i_in[31]}}, i_in[30:24]} :
i_shift_amount == 8'd25 ? {i_in[24], {26{i_in[31]}}, i_in[30:25]} :
i_shift_amount == 8'd26 ? {i_in[25], {27{i_in[31]}}, i_in[30:26]} :
i_shift_amount == 8'd27 ? {i_in[26], {28{i_in[31]}}, i_in[30:27]} :
i_shift_amount == 8'd28 ? {i_in[27], {29{i_in[31]}}, i_in[30:28]} :
i_shift_amount == 8'd29 ? {i_in[28], {30{i_in[31]}}, i_in[30:29]} :
 
i_shift_amount == 8'd30 ? {i_in[29], {31{i_in[31]}}, i_in[30 ]} :
i_shift_amount == 8'd31 ? {i_in[30], {32{i_in[31]}} } :
{i_in[31], {32{i_in[31]}} } ; // >= 32
 
// carry out, < ------- out --------->
assign ror_out = i_shift_imm_zero ? {i_in[ 0], i_carry_in, i_in[31: 1]} : // RXR, (ROR w/ imm 0)
 
i_shift_amount[7:0] == 8'd 0 ? {i_carry_in, i_in } : // fall through case
i_shift_amount[4:0] == 5'd 0 ? {i_in[31], i_in } : // Rs > 31
i_shift_amount[4:0] == 5'd 1 ? {i_in[ 0], i_in[ 0], i_in[31: 1]} :
i_shift_amount[4:0] == 5'd 2 ? {i_in[ 1], i_in[ 1: 0], i_in[31: 2]} :
i_shift_amount[4:0] == 5'd 3 ? {i_in[ 2], i_in[ 2: 0], i_in[31: 3]} :
i_shift_amount[4:0] == 5'd 4 ? {i_in[ 3], i_in[ 3: 0], i_in[31: 4]} :
i_shift_amount[4:0] == 5'd 5 ? {i_in[ 4], i_in[ 4: 0], i_in[31: 5]} :
i_shift_amount[4:0] == 5'd 6 ? {i_in[ 5], i_in[ 5: 0], i_in[31: 6]} :
i_shift_amount[4:0] == 5'd 7 ? {i_in[ 6], i_in[ 6: 0], i_in[31: 7]} :
i_shift_amount[4:0] == 5'd 8 ? {i_in[ 7], i_in[ 7: 0], i_in[31: 8]} :
i_shift_amount[4:0] == 5'd 9 ? {i_in[ 8], i_in[ 8: 0], i_in[31: 9]} :
i_shift_amount[4:0] == 5'd10 ? {i_in[ 9], i_in[ 9: 0], i_in[31:10]} :
i_shift_amount[4:0] == 5'd11 ? {i_in[10], i_in[10: 0], i_in[31:11]} :
i_shift_amount[4:0] == 5'd12 ? {i_in[11], i_in[11: 0], i_in[31:12]} :
i_shift_amount[4:0] == 5'd13 ? {i_in[12], i_in[12: 0], i_in[31:13]} :
i_shift_amount[4:0] == 5'd14 ? {i_in[13], i_in[13: 0], i_in[31:14]} :
i_shift_amount[4:0] == 5'd15 ? {i_in[14], i_in[14: 0], i_in[31:15]} :
i_shift_amount[4:0] == 5'd16 ? {i_in[15], i_in[15: 0], i_in[31:16]} :
i_shift_amount[4:0] == 5'd17 ? {i_in[16], i_in[16: 0], i_in[31:17]} :
i_shift_amount[4:0] == 5'd18 ? {i_in[17], i_in[17: 0], i_in[31:18]} :
i_shift_amount[4:0] == 5'd19 ? {i_in[18], i_in[18: 0], i_in[31:19]} :
 
i_shift_amount[4:0] == 5'd20 ? {i_in[19], i_in[19: 0], i_in[31:20]} :
i_shift_amount[4:0] == 5'd21 ? {i_in[20], i_in[20: 0], i_in[31:21]} :
i_shift_amount[4:0] == 5'd22 ? {i_in[21], i_in[21: 0], i_in[31:22]} :
i_shift_amount[4:0] == 5'd23 ? {i_in[22], i_in[22: 0], i_in[31:23]} :
i_shift_amount[4:0] == 5'd24 ? {i_in[23], i_in[23: 0], i_in[31:24]} :
i_shift_amount[4:0] == 5'd25 ? {i_in[24], i_in[24: 0], i_in[31:25]} :
i_shift_amount[4:0] == 5'd26 ? {i_in[25], i_in[25: 0], i_in[31:26]} :
i_shift_amount[4:0] == 5'd27 ? {i_in[26], i_in[26: 0], i_in[31:27]} :
i_shift_amount[4:0] == 5'd28 ? {i_in[27], i_in[27: 0], i_in[31:28]} :
i_shift_amount[4:0] == 5'd29 ? {i_in[28], i_in[28: 0], i_in[31:29]} :
 
i_shift_amount[4:0] == 5'd30 ? {i_in[29], i_in[29: 0], i_in[31:30]} :
{i_in[30], i_in[30: 0], i_in[31:31]} ;
 
assign {o_carry_out, o_out} = i_function == LSL ? lsl_out :
i_function == LSR ? lsr_out :
i_function == ASR ? asr_out :
ror_out ;
 
endmodule
 
 
/amber/trunk/hw/vlog/amber25/a25_dcache.v
96,12 → 96,13
 
output [31:0] o_read_data,
input i_fetch_stall,
input i_exec_stall,
output o_stall,
 
// WB Read Request
output o_wb_req, // Read Request
input [31:0] i_wb_read_data, // wb bus
input i_wb_ready // wb_stb && !wb_ack
output o_wb_cached_req, // Read Request
input [127:0] i_wb_cached_rdata, // wb bus
input i_wb_cached_ready // wb_stb && !wb_ack
);
 
`include "a25_localparams.v"
169,7 → 170,7
wire read_stall;
wire write_stall;
wire cache_busy_stall;
wire access_stall;
wire core_stall;
wire write_state;
 
wire request_pulse;
189,7 → 190,7
reg [31:0] wb_address = 'd0;
wire rbuf_hit = 'd0;
wire wb_hit;
 
wire [127:0] read_data128;
genvar i;
 
// ======================================
198,20 → 199,22
// If currently stalled then the address for the next
// cycle will be the same as it is in the current cycle
//
assign access_stall = i_fetch_stall || o_stall;
assign core_stall = i_fetch_stall || i_exec_stall || o_stall;
 
assign address = access_stall ? i_address [CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] :
i_address_nxt[CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] ;
assign address = core_stall ? i_address [CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] :
i_address_nxt[CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] ;
 
// ======================================
// Outputs
// ======================================
assign o_read_data = wb_hit ? i_wb_read_data :
i_address[WORD_SEL_MSB:WORD_SEL_LSB] == 2'd0 ? hit_rdata [31:0] :
i_address[WORD_SEL_MSB:WORD_SEL_LSB] == 2'd1 ? hit_rdata [63:32] :
i_address[WORD_SEL_MSB:WORD_SEL_LSB] == 2'd2 ? hit_rdata [95:64] :
hit_rdata [127:96] ;
 
assign read_data128 = wb_hit ? i_wb_cached_rdata : hit_rdata;
 
assign o_read_data = i_address[WORD_SEL_MSB:WORD_SEL_LSB] == 2'd0 ? read_data128 [31:0] :
i_address[WORD_SEL_MSB:WORD_SEL_LSB] == 2'd1 ? read_data128 [63:32] :
i_address[WORD_SEL_MSB:WORD_SEL_LSB] == 2'd2 ? read_data128 [95:64] :
read_data128 [127:96] ;
 
// Don't allow the cache to stall the wb i/f for an exclusive access
// The cache needs a couple of cycles to flush a potential copy of the exclusive
// address, but the wb can do the access in parallel. So there is no
219,7 → 222,7
// This works fine as long as the wb is stalling the core
assign o_stall = request_hold && ( read_stall || write_stall || cache_busy_stall || ex_read_cache_busy );
 
assign o_wb_req = ( (read_miss || write_miss || write_hit) && c_state == CS_IDLE ) || consecutive_write;
assign o_wb_cached_req = ( (read_miss || write_miss || write_hit) && c_state == CS_IDLE ) || consecutive_write;
 
// ======================================
263,43 → 266,23
source_sel <= 1'd1 << C_INVA;
end
else if ( read_miss )
c_state <= CS_FILL0;
c_state <= CS_FILL3;
else if ( write_hit )
begin
if ( i_wb_ready )
if ( i_wb_cached_ready )
c_state <= CS_WRITE_HIT1;
else
c_state <= CS_WRITE_HIT_WAIT_WB;
end
else if ( write_miss && !i_wb_ready )
else if ( write_miss && !i_wb_cached_ready )
c_state <= CS_WRITE_MISS_WAIT_WB;
end
CS_FILL0 :
// wb read request asserted, wait for ack
if ( i_wb_ready )
c_state <= CS_FILL1;
CS_FILL1 :
// first read of burst of 4
// wb read request asserted, wait for ack
if ( i_wb_ready )
c_state <= CS_FILL2;
 
 
CS_FILL2 :
// second read of burst of 4
// wb read request asserted, wait for ack
if ( i_wb_ready )
c_state <= CS_FILL3;
CS_FILL3 :
// third read of burst of 4
// wb read request asserted, wait for ack
if ( i_wb_ready )
if ( i_wb_cached_ready )
begin
c_state <= CS_FILL_COMPLETE;
source_sel <= 1'd1 << C_FILL;
353,13 → 336,13
 
CS_WRITE_HIT_WAIT_WB:
// wait for an ack on the wb bus to complete the write
if ( i_wb_ready )
if ( i_wb_cached_ready )
c_state <= CS_IDLE;
 
 
CS_WRITE_MISS_WAIT_WB:
// wait for an ack on the wb bus to complete the write
if ( i_wb_ready )
if ( i_wb_cached_ready )
c_state <= CS_IDLE;
endcase
369,8 → 352,8
// Capture WB Block Read - burst of 4 words
// ======================================
always @ ( posedge i_clk )
if ( i_wb_ready )
wb_rdata_burst <= {i_wb_read_data, wb_rdata_burst[127:32]};
if ( i_wb_cached_ready )
wb_rdata_burst <= i_wb_cached_rdata;
 
 
378,7 → 361,7
// Miss Address
// ======================================
always @ ( posedge i_clk )
if ( o_wb_req || write_hit )
if ( o_wb_cached_req || write_hit )
miss_address <= i_address;
 
always @ ( posedge i_clk )
400,13 → 383,13
 
 
always @(posedge i_clk)
if ( o_wb_req )
if ( o_wb_cached_req )
wb_address <= i_address;
else if ( i_wb_ready && fill_state )
else if ( i_wb_cached_ready && fill_state )
wb_address <= {wb_address[31:4], wb_address[3:2] + 1'd1, 2'd0};
assign fill_state = c_state == CS_FILL0 || c_state == CS_FILL1 || c_state == CS_FILL2 || c_state == CS_FILL3 ;
assign wb_hit = i_address == wb_address && i_wb_ready && fill_state;
assign wb_hit = i_address == wb_address && i_wb_cached_ready && fill_state;
 
 
// ======================================
472,10 → 455,7
consecutive_write ? consecutive_write_wdata :
read_miss_wdata ;
 
assign read_miss_wdata = miss_address[3:2] == 2'd0 ? wb_rdata_burst :
miss_address[3:2] == 2'd1 ? { wb_rdata_burst[95:0], wb_rdata_burst[127:96] }:
miss_address[3:2] == 2'd2 ? { wb_rdata_burst[63:0], wb_rdata_burst[127:64] }:
{ wb_rdata_burst[31:0], wb_rdata_burst[127:32] };
assign read_miss_wdata = wb_rdata_burst;
 
 
assign write_hit_wdata = i_address[3:2] == 2'd0 ? {hit_rdata[127:32], write_data_word } :
554,12 → 534,13
assign write_state = c_state == CS_IDLE || c_state == CS_WRITE_HIT1 ||
c_state == CS_WRITE_HIT_WAIT_WB || c_state == CS_WRITE_MISS_WAIT_WB;
assign write_stall = (write_miss && !(i_wb_ready && write_state)) || (write_hit && !i_wb_ready);
assign write_stall = (write_miss && !(i_wb_cached_ready && write_state)) || (write_hit && !i_wb_cached_ready);
 
assign read_stall = request_hold && !idle_hit && !rbuf_hit && !wb_hit && !i_write_enable;
 
assign cache_busy_stall = c_state == CS_FILL_COMPLETE || c_state == CS_TURN_AROUND || c_state == CS_INIT ||
(fill_state && !rbuf_hit && !wb_hit);
(fill_state && !rbuf_hit && !wb_hit) ||
(c_state == CS_WRITE_HIT1 && !consecutive_write);
 
 
// ======================================
/amber/trunk/hw/vlog/amber25/a25_functions.v
40,6 → 40,41
 
 
// ========================================================
// Instruction type decode
// ========================================================
function [3:0] instruction_type;
input [31:0] instruction;
begin
// Instruction Decode - Order is important!
casez ({instruction[27:20], instruction[7:4]})
12'b00010?001001 : instruction_type = SWAP;
12'b000000??1001 : instruction_type = MULT;
12'b00?????????? : instruction_type = REGOP;
12'b01?????????? : instruction_type = TRANS;
12'b100????????? : instruction_type = MTRANS;
12'b101????????? : instruction_type = BRANCH;
12'b110????????? : instruction_type = CODTRANS;
12'b1110???????0 : instruction_type = COREGOP;
12'b1110???????1 : instruction_type = CORTRANS;
default: instruction_type = SWI;
endcase
end
endfunction
 
 
// ========================================================
// Select 32 bits from a 128 bit bus based on a 2-bit address
// ========================================================
function [31:0] sel32_128;
input [1:0] select;
input [127:0] bus;
begin
sel32_128 = select==2'd0 ? bus[31:0] : select==2'd1 ? bus[63:32] : select==2'd2 ? bus[95:64] : bus[127:96];
end
endfunction
 
// ========================================================
// PC Filter - Remove the status bits
// ========================================================
function [31:0] pcf;
/amber/trunk/hw/vlog/amber25/a25_wishbone_buf.v
0,0 → 1,132
//////////////////////////////////////////////////////////////////
// //
// Wishbone master interface port buffer //
// //
// This file is part of the Amber project //
// http://www.opencores.org/project,amber //
// //
// Description //
// This is a sub-module of the Amber wishbone master //
// interface. The wishbone master interface connects a number //
// of internal amber ports to the wishbone bus. The ports //
// are; //
// instruction cache read accesses //
// data cache read and write accesses (cached) //
// data cache read and write accesses (uncached) //
// //
// The buffer module buffers a single port. For write //
// requests, this allows the processor core to continue //
// executing withont having to wait for the wishbone write //
// operation to complete. //
// //
// Author(s): //
// - Conor Santifort, csantifort.amber@gmail.com //
// //
//////////////////////////////////////////////////////////////////
// //
// Copyright (C) 2011 Authors and OPENCORES.ORG //
// //
// This source file may be used and distributed without //
// restriction provided that this copyright statement is not //
// removed from the file and that any derivative work contains //
// the original copyright notice and the associated disclaimer. //
// //
// This source file is free software; you can redistribute it //
// and/or modify it under the terms of the GNU Lesser General //
// Public License as published by the Free Software Foundation; //
// either version 2.1 of the License, or (at your option) any //
// later version. //
// //
// This source is distributed in the hope that it will be //
// useful, but WITHOUT ANY WARRANTY; without even the implied //
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //
// PURPOSE. See the GNU Lesser General Public License for more //
// details. //
// //
// You should have received a copy of the GNU Lesser General //
// Public License along with this source; if not, download it //
// from http://www.opencores.org/lgpl.shtml //
// //
//////////////////////////////////////////////////////////////////
 
module a25_wishbone_buf (
input i_clk,
 
// Core side
input i_req,
input i_write,
input [127:0] i_wdata,
input [15:0] i_be,
input [31:0] i_addr,
output [127:0] o_rdata,
output o_ready,
 
// Wishbone side
output o_valid,
input i_accepted,
output o_write,
output [127:0] o_wdata,
output [15:0] o_be,
output [31:0] o_addr,
input [127:0] i_rdata,
input i_rdata_valid
);
 
 
// ----------------------------------------------------
// Signals
// ----------------------------------------------------
reg wbuf_used_r = 'd0;
reg [127:0] wbuf_wdata_r;
reg [31:0] wbuf_addr_r;
reg [15:0] wbuf_be_r;
reg wbuf_write_r = 'd0;
wire in_wreq = i_req && i_write;
reg busy_reading_r = 'd0;
 
 
// ----------------------------------------------------
// Access Buffer
// ----------------------------------------------------
always @(posedge i_clk)
if (!wbuf_used_r && i_req)
begin
wbuf_used_r <= !i_accepted;
wbuf_wdata_r <= i_wdata;
wbuf_addr_r <= i_addr;
wbuf_be_r <= i_write ? i_be : 16'hffff;
wbuf_write_r <= i_write;
end
else if (o_valid && i_accepted && wbuf_write_r)
wbuf_used_r <= 1'd0;
else if (i_rdata_valid && !wbuf_write_r)
wbuf_used_r <= 1'd0;
 
 
// ----------------------------------------------------
// Output logic
// ----------------------------------------------------
assign o_wdata = wbuf_used_r ? wbuf_wdata_r : i_wdata;
assign o_write = wbuf_used_r ? wbuf_write_r : i_write;
assign o_addr = wbuf_used_r ? wbuf_addr_r : i_addr;
assign o_be = wbuf_used_r ? wbuf_be_r : i_write ? i_be : 16'hffff;
 
assign o_valid = (wbuf_used_r || i_req) && !busy_reading_r;
 
assign o_rdata = i_rdata;
assign o_ready = in_wreq ? (!wbuf_used_r || i_accepted) : i_rdata_valid;
 
 
always@(posedge i_clk)
if (o_valid && !o_write && i_accepted)
busy_reading_r <= 1'd1;
else if (i_rdata_valid)
busy_reading_r <= 1'd0;
 
 
 
endmodule
 
 
 
 
/amber/trunk/hw/vlog/amber25/a25_write_back.v
46,11 → 46,11
 
input [31:0] i_mem_read_data, // data reads
input i_mem_read_data_valid, // read data is valid
input [9:0] i_mem_load_rd, // Rd for data reads
input [10:0] i_mem_load_rd, // Rd for data reads
 
output [31:0] o_wb_read_data, // data reads
output o_wb_read_data_valid, // read data is valid
output [9:0] o_wb_load_rd, // Rd for data reads
output [10:0] o_wb_load_rd, // Rd for data reads
 
input [31:0] i_daddress,
input i_daddress_valid
58,7 → 58,7
 
reg [31:0] mem_read_data_r = 'd0; // Register read data from Data Cache
reg mem_read_data_valid_r = 'd0; // Register read data from Data Cache
reg [9:0] mem_load_rd_r = 'd0; // Register the Rd value for loads
reg [10:0] mem_load_rd_r = 'd0; // Register the Rd value for loads
reg [31:0] daddress_r = 'd0; // Register read data from Data Cache
 
assign o_wb_read_data = mem_read_data_r;
/amber/trunk/hw/vlog/amber25/a25_icache.v
90,11 → 90,11
input i_cache_enable, // from co-processor 15 configuration register
input i_cache_flush, // from co-processor 15 register
 
output [31:0] o_read_data,
output [127:0] o_read_data,
 
// WB Read Request
output o_wb_req, // Read Request
input [31:0] i_wb_read_data,
input [127:0] i_wb_read_data,
input i_wb_ready
);
 
140,7 → 140,6
wire [TAG_WIDTH-1:0] tag_wdata;
wire tag_wenable;
 
wire [CACHE_LINE_WIDTH-1:0] data_wdata;
wire [CACHE_ADDR_WIDTH-1:0] data_address;
wire [31:0] write_data_word;
 
161,12 → 160,12
wire [31:0] address_c;
reg [31:0] address_r = 'd0;
 
reg [CACHE_LINE_WIDTH-1:0] wb_rdata_burst_r = 'd0;
wire [CACHE_LINE_WIDTH-1:0] wb_rdata_burst;
 
reg [31:0] wb_address = 'd0;
wire rbuf_hit = 'd0;
wire wb_hit;
wire read_buf_hit;
reg [127:0] read_buf_data_r;
reg [31:0] read_buf_addr_r;
reg read_buf_valid_r;
genvar i;
 
// ======================================
175,20 → 174,20
// If currently stalled then the address for the next
// cycle will be the same as it is in the current cycle
//
assign address_c = i_core_stall ? i_address : //[CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] :
i_address_nxt; //[CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] ;
assign address_c = i_core_stall ? i_address :
i_address_nxt;
 
assign address = address_c[CACHE_ADDR32_MSB:CACHE_ADDR32_LSB];
 
 
// ======================================
// Outputs
// ======================================
assign o_read_data = wb_hit ? i_wb_read_data :
i_address[WORD_SEL_MSB:WORD_SEL_LSB] == 2'd0 ? hit_rdata [31:0] :
i_address[WORD_SEL_MSB:WORD_SEL_LSB] == 2'd1 ? hit_rdata [63:32] :
i_address[WORD_SEL_MSB:WORD_SEL_LSB] == 2'd2 ? hit_rdata [95:64] :
hit_rdata [127:96] ;
assign o_read_data = wb_hit ? i_wb_read_data :
read_buf_hit ? read_buf_data_r :
hit_rdata ;
 
 
// Don't allow the cache to stall the wb i/f for an exclusive access
// The cache needs a couple of cycles to flush a potential copy of the exclusive
// address, but the wb can do the access in parallel. So there is no
198,6 → 197,24
 
assign o_wb_req = read_miss && c_state == CS_IDLE;
 
 
// ======================================
// Read Buffer
// ======================================
always@(posedge i_clk)
if ( i_cache_flush )
read_buf_valid_r <= 1'd0;
else if (i_wb_ready && c_state == CS_FILL3)
begin
read_buf_data_r <= i_wb_read_data;
read_buf_addr_r <= miss_address;
read_buf_valid_r <= 1'd1;
end
else if (o_wb_req)
read_buf_valid_r <= 1'd0;
assign read_buf_hit = read_buf_valid_r && i_address[31:4] == read_buf_addr_r[31:4];
// ======================================
// Cache State Machine
234,33 → 251,15
source_sel <= 1'd1 << C_CORE;
if ( read_miss )
c_state <= CS_FILL0;
c_state <= CS_FILL3;
end
CS_FILL0 :
begin
// wb read request asserted, wait for ack
if ( i_wb_ready )
c_state <= CS_FILL1;
end
CS_FILL1 :
begin
// wb read request asserted, wait for ack
if ( i_wb_ready )
c_state <= CS_FILL2;
end
CS_FILL2 :
// first read of burst of 4
// wb read request asserted, wait for ack
if ( i_wb_ready )
c_state <= CS_FILL3;
 
CS_FILL3 :
begin
// Pick a way to write the cache update into
// Either pick one of the invalid caches, or if all are valid, then pick
// one randomly
select_way <= next_way;
random_num <= {random_num[2], random_num[1], random_num[0],
random_num[3]^random_num[2]};
270,11 → 269,6
if ( i_wb_ready )
begin
c_state <= CS_FILL_COMPLETE;
// Pick a way to write the cache update into
// Either pick one of the invalid caches, or if all are valid, then pick
// one randomly
end
end
302,15 → 296,6
 
 
// ======================================
// Capture WB Block Read - burst of 4 words
// ======================================
assign wb_rdata_burst = {i_wb_read_data, wb_rdata_burst_r[127:32]};
always @ ( posedge i_clk )
if ( i_wb_ready )
wb_rdata_burst_r <= wb_rdata_burst;
 
 
// ======================================
// Miss Address
// ======================================
always @ ( posedge i_clk )
330,7 → 315,7
else if ( i_wb_ready && fill_state )
wb_address <= {wb_address[31:4], wb_address[3:2] + 1'd1, 2'd0};
assign fill_state = c_state == CS_FILL0 || c_state == CS_FILL1 || c_state == CS_FILL2 || c_state == CS_FILL3 ;
assign fill_state = c_state == CS_FILL3;
assign wb_hit = i_address == wb_address && i_wb_ready && fill_state;
 
assign tag_address = read_miss_fill ? miss_address [CACHE_ADDR32_MSB:CACHE_ADDR32_LSB] :
346,13 → 331,6
{TAG_WIDTH{1'd0}} ;
 
 
// Data comes in off the WB bus in wrap4 with the missed data word first
assign data_wdata = miss_address[3:2] == 2'd0 ? { wb_rdata_burst[127:0] }:
miss_address[3:2] == 2'd1 ? { wb_rdata_burst[95:0], wb_rdata_burst[127:96] }:
miss_address[3:2] == 2'd2 ? { wb_rdata_burst[63:0], wb_rdata_burst[127:64] }:
{ wb_rdata_burst[31:0], wb_rdata_burst[127:32] };
 
 
assign read_miss_fill = c_state == CS_FILL3 && i_wb_ready;
 
371,9 → 349,9
 
assign read_miss = enable && !idle_hit && !invalid_read;
 
assign read_stall = enable && !idle_hit && !rbuf_hit && !wb_hit;
assign read_stall = enable && !idle_hit && !wb_hit && !read_buf_hit;
 
assign cache_busy_stall = (c_state == CS_TURN_AROUND && enable) || c_state == CS_INIT;
assign cache_busy_stall = (c_state == CS_TURN_AROUND && enable && !read_buf_hit) || c_state == CS_INIT;
 
 
// ======================================
427,7 → 405,7
.ADDRESS_WIDTH ( CACHE_ADDR_WIDTH) )
u_data (
.i_clk ( i_clk ),
.i_write_data ( data_wdata ),
.i_write_data ( i_wb_read_data ),
.i_write_enable ( data_wenable_way[i] ),
.i_address ( data_address ),
.i_byte_enable ( {CACHE_LINE_WIDTH/8{1'd1}} ),
/amber/trunk/hw/vlog/amber25/a25_wishbone.v
55,401 → 55,203
//////////////////////////////////////////////////////////////////
 
 
// TODO add support for exclusive accesses
 
module a25_wishbone
(
input i_clk,
 
// Instruction Cache Accesses
input i_icache_req,
input i_icache_qword,
input [31:0] i_icache_address,
output [31:0] o_icache_read_data,
output o_icache_ready,
 
// Data Cache Accesses
input i_exclusive, // high for read part of swap access
input i_dcache_cached_req,
input i_dcache_uncached_req,
input i_dcache_qword,
input i_dcache_write,
input [31:0] i_dcache_write_data,
input [3:0] i_dcache_byte_enable, // valid for writes only
input [31:0] i_dcache_address,
output [31:0] o_dcache_read_data,
output o_dcache_cached_ready,
output o_dcache_uncached_ready,
// Port 0 - dcache uncached
input i_port0_req,
input i_port0_write,
input [127:0] i_port0_wdata,
input [15:0] i_port0_be,
input [31:0] i_port0_addr,
output [127:0] o_port0_rdata,
output o_port0_ready,
 
// Wishbone Bus
// Port 1 - dcache cached
input i_port1_req,
input i_port1_write,
input [127:0] i_port1_wdata,
input [15:0] i_port1_be,
input [31:0] i_port1_addr,
output [127:0] o_port1_rdata,
output o_port1_ready,
 
// Port 2 - instruction cache accesses, read only
input i_port2_req,
input i_port2_write,
input [127:0] i_port2_wdata,
input [15:0] i_port2_be,
input [31:0] i_port2_addr,
output [127:0] o_port2_rdata,
output o_port2_ready,
 
 
// 128-bit Wishbone Bus
output reg [31:0] o_wb_adr = 'd0,
output reg [3:0] o_wb_sel = 'd0,
output reg [15:0] o_wb_sel = 'd0,
output reg o_wb_we = 'd0,
input [31:0] i_wb_dat,
output reg [31:0] o_wb_dat = 'd0,
output reg [127:0] o_wb_dat = 'd0,
output reg o_wb_cyc = 'd0,
output reg o_wb_stb = 'd0,
input [127:0] i_wb_dat,
input i_wb_ack,
input i_wb_err
 
);
 
 
localparam [3:0] WB_IDLE = 3'd0,
WB_BURST1 = 3'd1,
WB_BURST2 = 3'd2,
WB_BURST3 = 3'd3,
WB_WAIT_ACK = 3'd4;
// ----------------------------------------------------
// Parameters
// ----------------------------------------------------
localparam WBUF = 3;
 
reg [2:0] wishbone_st = WB_IDLE;
 
wire icache_read_req_c;
wire icache_read_qword_c;
wire [31:0] icache_read_addr_c;
wire dcache_read_qword_c;
// ----------------------------------------------------
// Signals
// ----------------------------------------------------
wire [0:0] wbuf_valid [WBUF-1:0];
wire [0:0] wbuf_accepted [WBUF-1:0];
wire [0:0] wbuf_write [WBUF-1:0];
wire [127:0] wbuf_wdata [WBUF-1:0];
wire [15:0] wbuf_be [WBUF-1:0];
wire [31:0] wbuf_addr [WBUF-1:0];
wire [0:0] wbuf_rdata_valid [WBUF-1:0];
wire new_access;
reg [WBUF-1:0] serving_port = 'd0;
 
wire dcache_req_c;
wire write_req_c;
wire dcache_cached_rreq_c;
wire dcache_cached_wreq_c;
wire dcache_uncached_rreq_c;
wire dcache_uncached_wreq_c;
 
wire dcache_cached_rreq_in;
wire dcache_cached_wreq_in;
wire dcache_uncached_rreq_in;
wire dcache_uncached_wreq_in;
// ----------------------------------------------------
// Instantiate the write buffers
// ----------------------------------------------------
a25_wishbone_buf u_a25_wishbone_buf_p0 (
.i_clk ( i_clk ),
 
reg dcache_cached_rreq_r = 'd0;
reg dcache_cached_wreq_r = 'd0;
reg dcache_uncached_rreq_r = 'd0;
reg dcache_uncached_wreq_r = 'd0;
.i_req ( i_port0_req ),
.i_write ( i_port0_write ),
.i_wdata ( i_port0_wdata ),
.i_be ( i_port0_be ),
.i_addr ( i_port0_addr ),
.o_rdata ( o_port0_rdata ),
.o_ready ( o_port0_ready ),
 
wire dcache_cached_wready;
wire dcache_uncached_wready;
wire dcache_cached_rready;
wire dcache_uncached_rready;
.o_valid ( wbuf_valid [0] ),
.i_accepted ( wbuf_accepted [0] ),
.o_write ( wbuf_write [0] ),
.o_wdata ( wbuf_wdata [0] ),
.o_be ( wbuf_be [0] ),
.o_addr ( wbuf_addr [0] ),
.i_rdata ( i_wb_dat ),
.i_rdata_valid ( wbuf_rdata_valid [0] )
);
 
wire start_access;
wire [3:0] byte_enable;
reg exclusive_access = 'd0;
wire read_ack;
wire wait_write_ack;
reg icache_read_req_r = 'd0;
reg icache_read_qword_r = 'd0;
reg [31:0] icache_read_addr_r = 'd0;
reg dcache_read_qword_r = 'd0;
wire icache_read_req_in;
wire icache_read_ready;
reg servicing_dcache_cached_read_r = 'd0;
reg servicing_dcache_uncached_read_r = 'd0;
reg servicing_dcache_cached_write_r = 'd0;
reg servicing_dcache_uncached_write_r = 'd0;
reg servicing_icache_r = 'd0;
wire buffer_write;
reg buffer_write_r = 'd0;
reg [31:0] buffer_write_data_r;
reg [31:0] buffer_write_address_r;
reg [3:0] buffer_write_be_r;
wire write_ack;
 
a25_wishbone_buf u_a25_wishbone_buf_p1 (
.i_clk ( i_clk ),
 
assign read_ack = !o_wb_we && i_wb_ack;
.i_req ( i_port1_req ),
.i_write ( i_port1_write ),
.i_wdata ( i_port1_wdata ),
.i_be ( i_port1_be ),
.i_addr ( i_port1_addr ),
.o_rdata ( o_port1_rdata ),
.o_ready ( o_port1_ready ),
 
assign dcache_cached_rready = dcache_cached_rreq_r && servicing_dcache_cached_read_r && read_ack;
assign dcache_uncached_rready = dcache_uncached_rreq_r && servicing_dcache_uncached_read_r && read_ack;
.o_valid ( wbuf_valid [1] ),
.i_accepted ( wbuf_accepted [1] ),
.o_write ( wbuf_write [1] ),
.o_wdata ( wbuf_wdata [1] ),
.o_be ( wbuf_be [1] ),
.o_addr ( wbuf_addr [1] ),
.i_rdata ( i_wb_dat ),
.i_rdata_valid ( wbuf_rdata_valid [1] )
);
 
assign dcache_cached_wready = (dcache_cached_wreq_c && wishbone_st == WB_IDLE && !dcache_cached_rreq_c) ||
(servicing_dcache_cached_write_r && i_wb_ack && wishbone_st == WB_WAIT_ACK && !dcache_cached_rreq_c);
assign dcache_uncached_wready = (dcache_uncached_wreq_c && wishbone_st == WB_IDLE && !dcache_uncached_rreq_c) ||
(servicing_dcache_uncached_write_r && i_wb_ack && wishbone_st == WB_WAIT_ACK && !dcache_uncached_rreq_c);
a25_wishbone_buf u_a25_wishbone_buf_p2 (
.i_clk ( i_clk ),
 
assign o_dcache_cached_ready = dcache_cached_rready || dcache_cached_wready;
assign o_dcache_uncached_ready = dcache_uncached_rready || dcache_uncached_wready;
assign o_dcache_read_data = i_wb_dat;
assign icache_read_ready = servicing_icache_r && read_ack;
assign o_icache_ready = icache_read_ready;
assign o_icache_read_data = i_wb_dat;
.i_req ( i_port2_req ),
.i_write ( i_port2_write ),
.i_wdata ( i_port2_wdata ),
.i_be ( i_port2_be ),
.i_addr ( i_port2_addr ),
.o_rdata ( o_port2_rdata ),
.o_ready ( o_port2_ready ),
 
assign dcache_cached_rreq_in = i_dcache_cached_req && !i_dcache_write;
assign dcache_cached_wreq_in = i_dcache_cached_req && i_dcache_write;
assign dcache_uncached_rreq_in = i_dcache_uncached_req && !i_dcache_write;
assign dcache_uncached_wreq_in = i_dcache_uncached_req && i_dcache_write;
assign icache_read_req_in = i_icache_req && !o_icache_ready;
.o_valid ( wbuf_valid [2] ),
.i_accepted ( wbuf_accepted [2] ),
.o_write ( wbuf_write [2] ),
.o_wdata ( wbuf_wdata [2] ),
.o_be ( wbuf_be [2] ),
.o_addr ( wbuf_addr [2] ),
.i_rdata ( i_wb_dat ),
.i_rdata_valid ( wbuf_rdata_valid [2] )
);
 
assign dcache_cached_rreq_c = ( dcache_cached_rreq_in || dcache_cached_rreq_r ) && !(servicing_dcache_cached_read_r && read_ack);
assign dcache_uncached_rreq_c = ( dcache_uncached_rreq_in || dcache_uncached_rreq_r ) && !(servicing_dcache_uncached_read_r && read_ack);
 
assign dcache_read_qword_c = ( i_dcache_qword || dcache_read_qword_r ) && !(servicing_dcache_cached_read_r && read_ack);
assign new_access = !o_wb_stb || i_wb_ack;
assign wbuf_accepted[0] = new_access && wbuf_valid[0];
assign wbuf_accepted[1] = new_access && !wbuf_valid[0] && wbuf_valid[1];
assign wbuf_accepted[2] = new_access && !wbuf_valid[0] && !wbuf_valid[1] && wbuf_valid[2];
 
assign icache_read_req_c = ( icache_read_req_in || icache_read_req_r ) && !(servicing_icache_r && read_ack);
assign icache_read_qword_c = ( i_icache_qword || icache_read_qword_r ) && !(servicing_icache_r && read_ack);
assign icache_read_addr_c = i_icache_req ? i_icache_address : icache_read_addr_r;
 
assign dcache_req_c = dcache_cached_rreq_c || dcache_cached_wreq_c || dcache_uncached_rreq_c || dcache_uncached_wreq_c;
assign write_req_c = dcache_cached_wreq_c || dcache_uncached_wreq_c;
 
assign start_access = !wait_write_ack && (dcache_req_c || icache_read_req_c);
 
// For writes the byte enable is always 4'hf
assign byte_enable = write_req_c ? i_dcache_byte_enable : 4'hf;
assign dcache_cached_wreq_c = dcache_cached_wreq_in || dcache_cached_wreq_r;
assign dcache_uncached_wreq_c = dcache_uncached_wreq_in || dcache_uncached_wreq_r;
 
 
// ======================================
// Register Accesses
// ======================================
 
assign buffer_write = dcache_cached_wreq_in || dcache_uncached_wreq_in;
assign write_buffered = dcache_uncached_wreq_r || dcache_uncached_wreq_r;
 
 
 
always @( posedge i_clk )
always @(posedge i_clk)
begin
icache_read_req_r <= icache_read_req_in || icache_read_req_c;
icache_read_qword_r <= i_icache_qword || icache_read_qword_c;
if ( i_icache_req ) icache_read_addr_r <= i_icache_address;
dcache_read_qword_r <= i_dcache_qword || dcache_read_qword_c;
 
// Buffer Write requests
case (wishbone_st)
WB_WAIT_ACK :
if (new_access)
begin
if (wbuf_valid[0])
begin
if (servicing_dcache_uncached_write_r && i_wb_ack && !buffer_write)
dcache_uncached_wreq_r <= 1'd0;
else
dcache_uncached_wreq_r <= dcache_uncached_wreq_c;
if (servicing_dcache_cached_write_r && i_wb_ack && !buffer_write)
dcache_cached_wreq_r <= 1'd0;
else
dcache_cached_wreq_r <= dcache_cached_wreq_c;
o_wb_adr <= wbuf_addr [0];
o_wb_sel <= wbuf_be [0];
o_wb_we <= wbuf_write[0];
o_wb_dat <= wbuf_wdata[0];
o_wb_cyc <= 1'd1;
o_wb_stb <= 1'd1;
serving_port <= 3'b001;
end
WB_IDLE:
else if (wbuf_valid[1])
begin
if (dcache_uncached_wreq_c && o_wb_stb && !i_wb_ack)
dcache_uncached_wreq_r <= 1'd1;
else
dcache_uncached_wreq_r <= 1'd0;
if (dcache_cached_wreq_c && o_wb_stb && !i_wb_ack)
dcache_cached_wreq_r <= 1'd1;
else
dcache_cached_wreq_r <= 1'd0;
o_wb_adr <= wbuf_addr [1];
o_wb_sel <= wbuf_be [1];
o_wb_we <= wbuf_write[1];
o_wb_dat <= wbuf_wdata[1];
o_wb_cyc <= 1'd1;
o_wb_stb <= 1'd1;
serving_port <= 3'b010;
end
default:
else if (wbuf_valid[2])
begin
dcache_uncached_wreq_r <= dcache_uncached_wreq_c;
dcache_cached_wreq_r <= dcache_cached_wreq_c;
o_wb_adr <= wbuf_addr [2];
o_wb_sel <= wbuf_be [2];
o_wb_we <= wbuf_write[2];
o_wb_dat <= wbuf_wdata[2];
o_wb_cyc <= 1'd1;
o_wb_stb <= 1'd1;
serving_port <= 3'b100;
end
endcase
else
begin
o_wb_cyc <= 1'd0;
o_wb_stb <= 1'd0;
// A buffer to hold a second write while on is in progress
if ( buffer_write )
begin
buffer_write_data_r <= i_dcache_write_data;
buffer_write_address_r <= i_dcache_address;
buffer_write_be_r <= i_dcache_byte_enable;
// Don't need to change these values because they are ignored
// when stb is low, but it makes for a cleaner waveform, at the expense of a few gates
o_wb_we <= 1'd0;
o_wb_adr <= 'd0;
o_wb_dat <= 'd0;
serving_port <= 3'b000;
end
end
 
 
// The flag can be set during any state but only cleared during WB_IDLE or WB_WAIT_ACK
if ( dcache_cached_rreq_r )
begin
if ( wishbone_st == WB_IDLE || wishbone_st == WB_WAIT_ACK )
dcache_cached_rreq_r <= dcache_cached_rreq_c && !o_dcache_cached_ready;
end
else
dcache_cached_rreq_r <= dcache_cached_rreq_c && (!o_dcache_cached_ready || dcache_cached_wreq_r);
if ( dcache_uncached_rreq_r )
begin
if ( wishbone_st == WB_IDLE || wishbone_st == WB_WAIT_ACK )
dcache_uncached_rreq_r <= dcache_uncached_rreq_c && !o_dcache_uncached_ready;
end
else
dcache_uncached_rreq_r <= dcache_uncached_rreq_c && (!o_dcache_uncached_ready || dcache_uncached_wreq_r);
end
assign wait_write_ack = o_wb_stb && o_wb_we && !i_wb_ack;
assign write_ack = o_wb_stb && o_wb_we && i_wb_ack;
 
 
always @( posedge i_clk )
case ( wishbone_st )
WB_IDLE :
begin
if ( start_access )
begin
o_wb_stb <= 1'd1;
o_wb_cyc <= 1'd1;
o_wb_sel <= byte_enable;
o_wb_dat <= write_buffered ? buffer_write_data_r : i_dcache_write_data;
end
else if ( !wait_write_ack )
begin
o_wb_stb <= 1'd0;
// Hold cyc high after an exclusive access
// to hold ownership of the wishbone bus
o_wb_cyc <= exclusive_access;
end
assign {wbuf_rdata_valid[2], wbuf_rdata_valid[1], wbuf_rdata_valid[0]} = {3{i_wb_ack & ~ o_wb_we}} & serving_port;
 
if ( wait_write_ack )
begin
// still waiting for last (write) access to complete
wishbone_st <= WB_WAIT_ACK;
servicing_dcache_cached_read_r <= dcache_cached_rreq_c;
servicing_dcache_uncached_read_r <= dcache_uncached_rreq_c;
servicing_dcache_cached_write_r <= dcache_cached_wreq_c;
servicing_dcache_uncached_write_r <= dcache_uncached_wreq_c;
end
// dcache accesses have priority over icache
else if ( dcache_cached_rreq_c || dcache_uncached_rreq_c )
begin
if ( dcache_cached_rreq_c )
servicing_dcache_cached_read_r <= 1'd1;
else if ( dcache_uncached_rreq_c )
servicing_dcache_uncached_read_r <= 1'd1;
if ( dcache_read_qword_c )
wishbone_st <= WB_BURST1;
else
wishbone_st <= WB_WAIT_ACK;
exclusive_access <= i_exclusive;
end
// The core does not currently issue exclusive write requests
// but there's no reason why this might not be added some
// time in the future so allow for it here
else if ( write_req_c )
begin
exclusive_access <= i_exclusive;
end
// do a burst of 4 read to fill a cache line
else if ( icache_read_req_c && icache_read_qword_c )
begin
wishbone_st <= WB_BURST1;
exclusive_access <= 1'd0;
servicing_icache_r <= 1'd1;
end
// single word read request from fetch stage
else if ( icache_read_req_c )
begin
wishbone_st <= WB_WAIT_ACK;
exclusive_access <= 1'd0;
servicing_icache_r <= 1'd1;
end
 
if ( start_access )
begin
if ( dcache_req_c )
begin
o_wb_we <= write_req_c;
// only update these on new wb access to make debug easier
o_wb_adr[31:2] <= i_dcache_address[31:2];
o_wb_adr[1:0] <= byte_enable == 4'b0001 ? 2'd0 :
byte_enable == 4'b0010 ? 2'd1 :
byte_enable == 4'b0100 ? 2'd2 :
byte_enable == 4'b1000 ? 2'd3 :
byte_enable == 4'b0011 ? 2'd0 :
byte_enable == 4'b1100 ? 2'd2 :
2'd0 ;
end
else
begin
o_wb_we <= 1'd0;
o_wb_adr[31:0] <= {icache_read_addr_c[31:2], 2'd0};
end
end
end
 
// Read burst, wait for first ack
WB_BURST1:
if ( i_wb_ack )
begin
// burst of 4 that wraps
o_wb_adr[3:2] <= o_wb_adr[3:2] + 1'd1;
wishbone_st <= WB_BURST2;
end
// Read burst, wait for second ack
WB_BURST2:
if ( i_wb_ack )
begin
// burst of 4 that wraps
o_wb_adr[3:2] <= o_wb_adr[3:2] + 1'd1;
wishbone_st <= WB_BURST3;
end
// Read burst, wait for third ack
WB_BURST3:
if ( i_wb_ack )
begin
// burst of 4 that wraps
o_wb_adr[3:2] <= o_wb_adr[3:2] + 1'd1;
wishbone_st <= WB_WAIT_ACK;
end
 
 
// Wait for the wishbone ack to be asserted
WB_WAIT_ACK:
if ( i_wb_ack )
begin
servicing_dcache_cached_read_r <= 1'd0;
servicing_dcache_uncached_read_r <= 1'd0;
servicing_dcache_cached_write_r <= 1'd0;
servicing_dcache_uncached_write_r <= 1'd0;
servicing_icache_r <= 1'd0;
// Another write that was acked and needs to be sent before returning to IDLE ?
if ( write_buffered )
begin
wishbone_st <= WB_IDLE;
o_wb_stb <= 1'd1;
o_wb_cyc <= exclusive_access;
o_wb_sel <= buffer_write_be_r;
o_wb_we <= 1'd1;
o_wb_adr[31:0] <= buffer_write_address_r;
o_wb_dat <= buffer_write_data_r;
end
else
begin
wishbone_st <= WB_IDLE;
o_wb_stb <= 1'd0;
o_wb_cyc <= exclusive_access;
o_wb_we <= 1'd0;
end
end
endcase
 
// ========================================================
// Debug Wishbone bus - not synthesizable
// ========================================================
//synopsys translate_off
wire [(14*8)-1:0] xWB_STATE;
 
 
assign xWB_STATE = wishbone_st == WB_IDLE ? "WB_IDLE" :
wishbone_st == WB_BURST1 ? "WB_BURST1" :
wishbone_st == WB_BURST2 ? "WB_BURST2" :
wishbone_st == WB_BURST3 ? "WB_BURST3" :
wishbone_st == WB_WAIT_ACK ? "WB_WAIT_ACK" :
"UNKNOWN" ;
 
//synopsys translate_on
endmodule
 
 
/amber/trunk/hw/vlog/amber25/a25_mem.v
46,6 → 46,7
(
input i_clk,
input i_fetch_stall, // Fetch stage asserting stall
input i_exec_stall, // Execute stage asserting stall
output o_mem_stall, // Mem stage asserting stall
 
input [31:0] i_daddress,
55,7 → 56,7
input i_write_enable,
input i_exclusive, // high for read part of swap access
input [3:0] i_byte_enable,
input [7:0] i_exec_load_rd, // The destination register for a load instruction
input [8:0] i_exec_load_rd, // The destination register for a load instruction
input i_cache_enable, // cache enable
input i_cache_flush, // cache flush
input [31:0] i_cacheable_area, // each bit corresponds to 2MB address space
62,7 → 63,7
 
output [31:0] o_mem_read_data,
output o_mem_read_data_valid,
output [9:0] o_mem_load_rd, // The destination register for a load instruction
output [10:0] o_mem_load_rd, // The destination register for a load instruction
 
// Wishbone accesses
output o_wb_cached_req, // Cached Request
69,10 → 70,11
output o_wb_uncached_req, // Unached Request
output o_wb_qword, // High for a quad-word read request
output o_wb_write, // Read=0, Write=1
output [3:0] o_wb_byte_enable, // byte eable
output [31:0] o_wb_write_data,
output [15:0] o_wb_byte_enable, // byte eable
output [127:0] o_wb_write_data,
output [31:0] o_wb_address, // wb bus
input [31:0] i_wb_read_data, // wb bus
input [127:0] i_wb_uncached_rdata, // wb bus
input [127:0] i_wb_cached_rdata, // wb bus
input i_wb_cached_ready, // wishbone access complete and read data valid
input i_wb_uncached_ready // wishbone access complete and read data valid
);
94,9 → 96,9
wire daddress_valid_p; // pulse
reg [31:0] mem_read_data_r = 'd0;
reg mem_read_data_valid_r = 'd0;
reg [9:0] mem_load_rd_r = 'd0;
wire [9:0] mem_load_rd_c;
wire [31:0] mem_read_data_c;
reg [10:0] mem_load_rd_r = 'd0;
wire [10:0] mem_load_rd_c;
wire [31:0] mem_read_data_c;
wire mem_read_data_valid_c;
reg mem_stall_r = 'd0;
wire use_mem_reg;
105,8 → 107,8
wire void_output;
wire wb_stop;
reg daddress_valid_stop_r = 'd0;
wire [31:0] wb_rdata32;
 
 
// ======================================
// Memory Decode
// ======================================
123,9 → 125,15
 
 
// Return read data either from the wishbone bus or the cache
assign wb_rdata32 = i_daddress[3:2] == 2'd0 ? i_wb_uncached_rdata[ 31: 0] :
i_daddress[3:2] == 2'd1 ? i_wb_uncached_rdata[ 63:32] :
i_daddress[3:2] == 2'd2 ? i_wb_uncached_rdata[ 95:64] :
i_wb_uncached_rdata[127:96] ;
assign mem_read_data_c = sel_cache ? cache_read_data :
uncached_data_access ? i_wb_read_data :
uncached_data_access ? wb_rdata32 :
32'h76543210 ;
assign mem_load_rd_c = {i_daddress[1:0], i_exec_load_rd};
assign mem_read_data_valid_c = i_daddress_valid && !i_write_enable && !o_mem_stall;
 
132,10 → 140,14
assign o_mem_stall = uncached_wb_wait || cache_stall;
 
// Request wishbone access
assign o_wb_byte_enable = i_byte_enable;
assign o_wb_byte_enable = i_daddress[3:2] == 2'd0 ? {12'd0, i_byte_enable } :
i_daddress[3:2] == 2'd1 ? { 8'd0, i_byte_enable, 4'd0} :
i_daddress[3:2] == 2'd2 ? { 4'd0, i_byte_enable, 8'd0} :
{ i_byte_enable, 12'd0} ;
 
assign o_wb_write = i_write_enable;
assign o_wb_address = {i_daddress[31:2], 2'd0};
assign o_wb_write_data = i_write_data;
assign o_wb_write_data = {4{i_write_data}};
assign o_wb_cached_req = !cached_wb_stop_r && cached_wb_req;
assign o_wb_uncached_req = !uncached_wb_stop_r && uncached_data_access_p;
assign o_wb_qword = !cached_wb_stop_r && cached_wb_req && !i_write_enable;
185,6 → 197,7
a25_dcache u_dcache (
.i_clk ( i_clk ),
.i_fetch_stall ( i_fetch_stall ),
.i_exec_stall ( i_exec_stall ),
.o_stall ( cache_stall ),
.i_request ( sel_cache_p ),
199,9 → 212,9
.i_cache_flush ( i_cache_flush ),
.o_read_data ( cache_read_data ),
.o_wb_req ( cached_wb_req ),
.i_wb_read_data ( i_wb_read_data ),
.i_wb_ready ( i_wb_cached_ready )
.o_wb_cached_req ( cached_wb_req ),
.i_wb_cached_rdata ( i_wb_cached_rdata ),
.i_wb_cached_ready ( i_wb_cached_ready )
);
 
 
/amber/trunk/hw/vlog/amber25/a25_multiply.v
55,7 → 55,7
 
module a25_multiply (
input i_clk,
input i_access_stall,
input i_core_stall,
 
input [31:0] i_a_in, // Rds
input [31:0] i_b_in, // Rm
188,7 → 188,7
 
 
always @ ( posedge i_clk )
if ( !i_access_stall )
if ( !i_core_stall )
begin
count <= i_execute ? count_nxt : count;
product <= i_execute ? product_nxt : product;
/amber/trunk/hw/vlog/amber25/a25_register_bank.v
44,7 → 44,7
module a25_register_bank (
 
input i_clk,
input i_access_stall,
input i_core_stall,
input i_mem_stall,
 
input [1:0] i_mode_idec, // user, supervisor, irq_idec, firq_idec etc.
67,7 → 67,7
input [31:0] i_wb_read_data,
input i_wb_read_data_valid,
input [3:0] i_wb_read_data_rd,
input i_wb_user_mode,
input [1:0] i_wb_mode,
 
input [3:0] i_status_bits_flags,
input i_status_bits_irq_mask,
178,8 → 178,8
 
assign read_data_wen = {15{i_wb_read_data_valid & ~i_mem_stall}} & decode (i_wb_read_data_rd);
 
assign reg_bank_wen_c = {15{~i_access_stall}} & i_reg_bank_wen;
assign pc_wen_c = ~i_access_stall & i_pc_wen;
assign reg_bank_wen_c = {15{~i_core_stall}} & i_reg_bank_wen;
assign pc_wen_c = ~i_core_stall & i_pc_wen;
assign pc_dmem_wen = i_wb_read_data_valid & ~i_mem_stall & i_wb_read_data_rd == 4'd15;
 
 
188,40 → 188,48
// ========================================================
always @ ( posedge i_clk )
begin
r0 <= reg_bank_wen_c[0 ] ? i_reg : read_data_wen[0 ] ? i_wb_read_data : r0;
r1 <= reg_bank_wen_c[1 ] ? i_reg : read_data_wen[1 ] ? i_wb_read_data : r1;
r2 <= reg_bank_wen_c[2 ] ? i_reg : read_data_wen[2 ] ? i_wb_read_data : r2;
r3 <= reg_bank_wen_c[3 ] ? i_reg : read_data_wen[3 ] ? i_wb_read_data : r3;
r4 <= reg_bank_wen_c[4 ] ? i_reg : read_data_wen[4 ] ? i_wb_read_data : r4;
r5 <= reg_bank_wen_c[5 ] ? i_reg : read_data_wen[5 ] ? i_wb_read_data : r5;
r6 <= reg_bank_wen_c[6 ] ? i_reg : read_data_wen[6 ] ? i_wb_read_data : r6;
r7 <= reg_bank_wen_c[7 ] ? i_reg : read_data_wen[7 ] ? i_wb_read_data : r7;
// these registers are used in all modes
r0 <= reg_bank_wen_c[0 ] ? i_reg : read_data_wen[0 ] ? i_wb_read_data : r0;
r1 <= reg_bank_wen_c[1 ] ? i_reg : read_data_wen[1 ] ? i_wb_read_data : r1;
r2 <= reg_bank_wen_c[2 ] ? i_reg : read_data_wen[2 ] ? i_wb_read_data : r2;
r3 <= reg_bank_wen_c[3 ] ? i_reg : read_data_wen[3 ] ? i_wb_read_data : r3;
r4 <= reg_bank_wen_c[4 ] ? i_reg : read_data_wen[4 ] ? i_wb_read_data : r4;
r5 <= reg_bank_wen_c[5 ] ? i_reg : read_data_wen[5 ] ? i_wb_read_data : r5;
r6 <= reg_bank_wen_c[6 ] ? i_reg : read_data_wen[6 ] ? i_wb_read_data : r6;
r7 <= reg_bank_wen_c[7 ] ? i_reg : read_data_wen[7 ] ? i_wb_read_data : r7;
r8 <= reg_bank_wen_c[8 ] && !firq_idec ? i_reg : read_data_wen[8 ] && ( !firq_idec || i_wb_user_mode ) ? i_wb_read_data : r8;
r9 <= reg_bank_wen_c[9 ] && !firq_idec ? i_reg : read_data_wen[9 ] && ( !firq_idec || i_wb_user_mode ) ? i_wb_read_data : r9;
r10 <= reg_bank_wen_c[10] && !firq_idec ? i_reg : read_data_wen[10] && ( !firq_idec || i_wb_user_mode ) ? i_wb_read_data : r10;
r11 <= reg_bank_wen_c[11] && !firq_idec ? i_reg : read_data_wen[11] && ( !firq_idec || i_wb_user_mode ) ? i_wb_read_data : r11;
r12 <= reg_bank_wen_c[12] && !firq_idec ? i_reg : read_data_wen[12] && ( !firq_idec || i_wb_user_mode ) ? i_wb_read_data : r12;
// these registers are used in all modes, except fast irq
r8 <= reg_bank_wen_c[8 ] && !firq_idec ? i_reg : read_data_wen[8 ] && i_wb_mode != FIRQ ? i_wb_read_data : r8;
r9 <= reg_bank_wen_c[9 ] && !firq_idec ? i_reg : read_data_wen[9 ] && i_wb_mode != FIRQ ? i_wb_read_data : r9;
r10 <= reg_bank_wen_c[10] && !firq_idec ? i_reg : read_data_wen[10] && i_wb_mode != FIRQ ? i_wb_read_data : r10;
r11 <= reg_bank_wen_c[11] && !firq_idec ? i_reg : read_data_wen[11] && i_wb_mode != FIRQ ? i_wb_read_data : r11;
r12 <= reg_bank_wen_c[12] && !firq_idec ? i_reg : read_data_wen[12] && i_wb_mode != FIRQ ? i_wb_read_data : r12;
r8_firq <= reg_bank_wen_c[8 ] && firq_idec ? i_reg : read_data_wen[8 ] && ( firq_idec && !i_wb_user_mode ) ? i_wb_read_data : r8_firq;
r9_firq <= reg_bank_wen_c[9 ] && firq_idec ? i_reg : read_data_wen[9 ] && ( firq_idec && !i_wb_user_mode ) ? i_wb_read_data : r9_firq;
r10_firq <= reg_bank_wen_c[10] && firq_idec ? i_reg : read_data_wen[10] && ( firq_idec && !i_wb_user_mode ) ? i_wb_read_data : r10_firq;
r11_firq <= reg_bank_wen_c[11] && firq_idec ? i_reg : read_data_wen[11] && ( firq_idec && !i_wb_user_mode ) ? i_wb_read_data : r11_firq;
r12_firq <= reg_bank_wen_c[12] && firq_idec ? i_reg : read_data_wen[12] && ( firq_idec && !i_wb_user_mode ) ? i_wb_read_data : r12_firq;
// these registers are used in fast irq mode
r8_firq <= reg_bank_wen_c[8 ] && firq_idec ? i_reg : read_data_wen[8 ] && i_wb_mode == FIRQ ? i_wb_read_data : r8_firq;
r9_firq <= reg_bank_wen_c[9 ] && firq_idec ? i_reg : read_data_wen[9 ] && i_wb_mode == FIRQ ? i_wb_read_data : r9_firq;
r10_firq <= reg_bank_wen_c[10] && firq_idec ? i_reg : read_data_wen[10] && i_wb_mode == FIRQ ? i_wb_read_data : r10_firq;
r11_firq <= reg_bank_wen_c[11] && firq_idec ? i_reg : read_data_wen[11] && i_wb_mode == FIRQ ? i_wb_read_data : r11_firq;
r12_firq <= reg_bank_wen_c[12] && firq_idec ? i_reg : read_data_wen[12] && i_wb_mode == FIRQ ? i_wb_read_data : r12_firq;
 
r13 <= reg_bank_wen_c[13] && usr_idec ? i_reg : read_data_wen[13] && ( usr_idec || i_wb_user_mode ) ? i_wb_read_data : r13;
r14 <= reg_bank_wen_c[14] && usr_idec ? i_reg : read_data_wen[14] && ( usr_idec || i_wb_user_mode ) ? i_wb_read_data : r14;
// these registers are used in user mode
r13 <= reg_bank_wen_c[13] && usr_idec ? i_reg : read_data_wen[13] && i_wb_mode == USR ? i_wb_read_data : r13;
r14 <= reg_bank_wen_c[14] && usr_idec ? i_reg : read_data_wen[14] && i_wb_mode == USR ? i_wb_read_data : r14;
r13_svc <= reg_bank_wen_c[13] && svc_idec ? i_reg : read_data_wen[13] && ( svc_idec && !i_wb_user_mode ) ? i_wb_read_data : r13_svc;
r14_svc <= reg_bank_wen_c[14] && svc_idec ? i_reg : read_data_wen[14] && ( svc_idec && !i_wb_user_mode ) ? i_wb_read_data : r14_svc;
// these registers are used in supervisor mode
r13_svc <= reg_bank_wen_c[13] && svc_idec ? i_reg : read_data_wen[13] && i_wb_mode == SVC ? i_wb_read_data : r13_svc;
r14_svc <= reg_bank_wen_c[14] && svc_idec ? i_reg : read_data_wen[14] && i_wb_mode == SVC ? i_wb_read_data : r14_svc;
r13_irq <= reg_bank_wen_c[13] && irq_idec ? i_reg : read_data_wen[13] && ( irq_idec && !i_wb_user_mode ) ? i_wb_read_data : r13_irq;
r14_irq <= reg_bank_wen_c[14] && irq_idec ? i_reg : read_data_wen[14] && ( irq_idec && !i_wb_user_mode ) ? i_wb_read_data : r14_irq;
// these registers are used in irq mode
r13_irq <= reg_bank_wen_c[13] && irq_idec ? i_reg : read_data_wen[13] && i_wb_mode == IRQ ? i_wb_read_data : r13_irq;
r14_irq <= (reg_bank_wen_c[14] && irq_idec) ? i_reg : read_data_wen[14] && i_wb_mode == IRQ ? i_wb_read_data : r14_irq;
r13_firq <= reg_bank_wen_c[13] && firq_idec ? i_reg : read_data_wen[13] && ( firq_idec && !i_wb_user_mode ) ? i_wb_read_data : r13_firq;
r14_firq <= reg_bank_wen_c[14] && firq_idec ? i_reg : read_data_wen[14] && ( firq_idec && !i_wb_user_mode ) ? i_wb_read_data : r14_firq;
// these registers are used in fast irq mode
r13_firq <= reg_bank_wen_c[13] && firq_idec ? i_reg : read_data_wen[13] && i_wb_mode == FIRQ ? i_wb_read_data : r13_firq;
r14_firq <= reg_bank_wen_c[14] && firq_idec ? i_reg : read_data_wen[14] && i_wb_mode == FIRQ ? i_wb_read_data : r14_firq;
r15 <= pc_wen_c ? i_pc : pc_dmem_wen ? i_wb_read_data[25:2] : r15;
// these registers are used in all modes
r15 <= pc_wen_c ? i_pc : pc_dmem_wen ? i_wb_read_data[25:2] : r15;
end
/amber/trunk/hw/vlog/amber25/a25_decode.v
45,7 → 45,7
(
input i_clk,
input [31:0] i_fetch_instruction,
input i_access_stall, // stall all stages of the cpu at the same time
input i_core_stall, // stall all stages of the Amber core at the same time
input i_irq, // interrupt request
input i_firq, // Fast interrupt request
input i_dabt, // data abort interrupt request
61,8 → 61,6
// --------------------------------------------------
// Control signals to execute stage
// --------------------------------------------------
// output reg [4:0] o_read_data_alignment = 1'd0, // 2 LSBs of read address used for calculating shift in ldrb ops
 
output reg [31:0] o_imm32 = 'd0,
output reg [4:0] o_imm_shift_amount = 'd0,
output reg o_shift_imm_zero = 'd0,
166,6 → 164,7
// Internal signals
// ========================================================
wire [31:0] instruction;
wire [3:0] type; // regop, mem access etc.
wire instruction_iabt; // abort flag, follows the instruction
wire instruction_adex; // address exception flag, follows the instruction
wire [31:0] instruction_address; // instruction virtual address, follows
172,7 → 171,6
// the instruction
wire [7:0] instruction_iabt_status; // abort status, follows the instruction
wire [1:0] instruction_sel;
reg [3:0] type;
wire [3:0] opcode;
wire [7:0] imm8;
wire [31:0] offset12;
255,17 → 253,21
reg [31:0] fetch_address_r = 'd0;
reg [7:0] abt_status_reg = 'd0;
reg [31:0] fetch_instruction_r = 'd0;
reg [3:0] fetch_instruction_type_r = 'd0;
reg [31:0] saved_current_instruction = 'd0;
reg [3:0] saved_current_instruction_type = 'd0;
reg saved_current_instruction_iabt = 'd0; // access abort flag
reg saved_current_instruction_adex = 'd0; // address exception
reg [31:0] saved_current_instruction_address = 'd0; // virtual address of abort instruction
reg [7:0] saved_current_instruction_iabt_status = 'd0; // status of abort instruction
reg [31:0] pre_fetch_instruction = 'd0;
reg [3:0] pre_fetch_instruction_type = 'd0;
reg pre_fetch_instruction_iabt = 'd0; // access abort flag
reg pre_fetch_instruction_adex = 'd0; // address exception
reg [31:0] pre_fetch_instruction_address = 'd0; // virtual address of abort instruction
reg [7:0] pre_fetch_instruction_iabt_status = 'd0; // status of abort instruction
reg [31:0] hold_instruction = 'd0;
reg [3:0] hold_instruction_type = 'd0;
reg hold_instruction_iabt = 'd0; // access abort flag
reg hold_instruction_adex = 'd0; // address exception
reg [31:0] hold_instruction_address = 'd0; // virtual address of abort instruction
310,6 → 312,7
wire ldm_flags;
wire [6:0] load_rd_d1_nxt;
reg [6:0] load_rd_d1 = 'd0; // MSB is the valid bit
 
wire rn_valid;
wire rm_valid;
wire rs_valid;
329,7 → 332,7
wire stm_conflict2b;
wire conflict1; // Register conflict1 with ldr operation
wire conflict2; // Register conflict1 with ldr operation
wire conflict; // Register conflict1 with ldr operation
wire conflict; // Register conflict1 with ldr operation
reg conflict_r = 'd0;
reg rn_conflict1_r = 'd0;
reg rm_conflict1_r = 'd0;
392,6 → 395,11
instruction_sel == 2'd1 ? saved_current_instruction :
instruction_sel == 2'd3 ? hold_instruction :
pre_fetch_instruction ;
assign type = instruction_sel == 2'd0 ? fetch_instruction_type_r :
instruction_sel == 2'd1 ? saved_current_instruction_type :
instruction_sel == 2'd3 ? hold_instruction_type :
pre_fetch_instruction_type ;
 
// abort flag
assign instruction_iabt = instruction_sel == 2'd0 ? iabt_reg :
415,21 → 423,6
instruction_sel == 2'd3 ? hold_instruction_adex :
pre_fetch_instruction_adex ;
 
// Instruction Decode - Order is important!
always @*
casez ({instruction[27:20], instruction[7:4]})
12'b00010?001001 : type = SWAP;
12'b000000??1001 : type = MULT;
12'b00?????????? : type = REGOP;
12'b01?????????? : type = TRANS;
12'b100????????? : type = MTRANS;
12'b101????????? : type = BRANCH;
12'b110????????? : type = CODTRANS;
12'b1110???????0 : type = COREGOP;
12'b1110???????1 : type = CORTRANS;
default: type = SWI;
endcase
 
// ========================================================
// Fixed fields within the instruction
551,7 → 544,7
 
 
always @( posedge i_clk )
if ( !i_access_stall )
if ( !i_core_stall )
begin
conflict_r <= conflict;
instruction_execute_r <= instruction_execute;
786,9 → 779,11
else
reg_bank_wen_nxt = decode (instruction[15:12]);
end
if ( !immediate_shift_op )
begin
barrel_shift_function_nxt = instruction[6:5];
end
if ( !immediate_shift_op )
barrel_shift_data_sel_nxt = 2'd2; // Shift value from Rm register
937,9 → 932,9
 
if ( type == BRANCH )
begin
pc_sel_nxt = 3'd1; // alu_out
iaddress_sel_nxt = 4'd1; // alu_out
alu_out_sel_nxt = 4'd1; // Add
pc_sel_nxt = 3'd1; // alu_out
iaddress_sel_nxt = 4'd1; // alu_out
alu_out_sel_nxt = 4'd1; // Add
if ( instruction[24] ) // Link
begin
1559,11 → 1554,12
// Register Update
// ========================================================
always @ ( posedge i_clk )
if ( !i_access_stall )
if ( !i_core_stall )
begin
if (!conflict)
begin
fetch_instruction_r <= i_fetch_instruction;
fetch_instruction_type_r <= instruction_type(i_fetch_instruction);
fetch_address_r <= i_execute_iaddress;
iabt_reg <= i_iabt;
adex_reg <= i_adex;
1630,7 → 1626,7
 
 
always @ ( posedge i_clk )
if ( !i_access_stall )
if ( !i_core_stall )
begin
// sometimes this is a pre-fetch instruction
// e.g. two ldr instructions in a row. The second ldr will be saved
1640,6 → 1636,7
if ( type == MTRANS )
begin
saved_current_instruction <= mtrans_instruction_nxt;
saved_current_instruction_type <= type;
saved_current_instruction_iabt <= instruction_iabt;
saved_current_instruction_adex <= instruction_adex;
saved_current_instruction_address <= instruction_address;
1648,6 → 1645,7
else if ( saved_current_instruction_wen )
begin
saved_current_instruction <= instruction;
saved_current_instruction_type <= type;
saved_current_instruction_iabt <= instruction_iabt;
saved_current_instruction_adex <= instruction_adex;
saved_current_instruction_address <= instruction_address;
1657,13 → 1655,17
if ( pre_fetch_instruction_wen )
begin
pre_fetch_instruction <= fetch_instruction_r;
pre_fetch_instruction_type <= fetch_instruction_type_r;
pre_fetch_instruction_iabt <= iabt_reg;
pre_fetch_instruction_adex <= adex_reg;
pre_fetch_instruction_address <= fetch_address_r;
pre_fetch_instruction_iabt_status <= abt_status_reg;
end
// TODO possible to use saved_current_instruction instead and save some regs?
hold_instruction <= instruction;
hold_instruction_type <= type;
hold_instruction_iabt <= instruction_iabt;
hold_instruction_adex <= instruction_adex;
hold_instruction_address <= instruction_address;
1673,7 → 1675,7
 
always @ ( posedge i_clk )
if ( !i_access_stall )
if ( !i_core_stall )
begin
irq <= i_irq;
firq <= i_firq;
1702,7 → 1704,7
 
a25_decompile u_decompile (
.i_clk ( i_clk ),
.i_access_stall ( i_access_stall ),
.i_core_stall ( i_core_stall ),
.i_instruction ( instruction ),
.i_instruction_valid ( instruction_valid &&!conflict ),
.i_instruction_execute ( instruction_execute ),
/amber/trunk/hw/vlog/amber25/a25_core.v
53,10 → 53,10
 
// Wishbone Master I/F
output [31:0] o_wb_adr,
output [3:0] o_wb_sel,
output [15:0] o_wb_sel,
output o_wb_we,
input [31:0] i_wb_dat,
output [31:0] o_wb_dat,
input [127:0] i_wb_dat,
output [127:0] o_wb_dat,
output o_wb_cyc,
output o_wb_stb,
input i_wb_ack,
86,7 → 86,8
 
wire fetch_stall;
wire mem_stall;
wire access_stall;
wire exec_stall;
wire core_stall;
 
wire [1:0] status_bits_mode;
wire status_bits_irq_mask;
105,7 → 106,7
wire [3:0] rm_sel;
wire [3:0] rs_sel;
wire [7:0] decode_load_rd;
wire [7:0] exec_load_rd;
wire [8:0] exec_load_rd;
wire [3:0] rn_sel;
wire [1:0] barrel_shift_amount_sel;
wire [1:0] barrel_shift_data_sel;
154,27 → 155,27
 
wire [31:0] mem_read_data;
wire mem_read_data_valid;
wire [9:0] mem_load_rd;
wire [10:0] mem_load_rd;
 
wire [31:0] wb_read_data;
wire wb_read_data_valid;
wire [9:0] wb_load_rd;
wire [10:0] wb_load_rd;
wire dcache_wb_cached_req;
wire dcache_wb_uncached_req;
wire dcache_wb_qword;
wire dcache_wb_write;
wire [3:0] dcache_wb_byte_enable;
wire [15:0] dcache_wb_byte_enable;
wire [31:0] dcache_wb_address;
wire [31:0] dcache_wb_read_data;
wire [31:0] dcache_wb_write_data;
wire [127:0] dcache_wb_cached_rdata;
wire [127:0] dcache_wb_uncached_rdata;
wire [127:0] dcache_wb_write_data;
wire dcache_wb_cached_ready;
wire dcache_wb_uncached_ready;
wire [31:0] icache_wb_address;
wire icache_wb_req;
wire icache_wb_qword;
wire [31:0] icache_wb_adr;
wire [31:0] icache_wb_read_data;
wire [127:0] icache_wb_read_data;
wire icache_wb_ready;
 
wire conflict;
188,7 → 189,7
assign decode_fault_address = dabt_trigger ? dabt_fault_address : iabt_fault_address;
assign decode_fault = dabt_trigger | iabt_trigger;
 
assign access_stall = fetch_stall || mem_stall;
assign core_stall = fetch_stall || mem_stall || exec_stall;
 
// ======================================
// Fetch Stage
196,6 → 197,7
a25_fetch u_fetch (
.i_clk ( i_clk ),
.i_mem_stall ( mem_stall ),
.i_exec_stall ( exec_stall ),
.i_conflict ( conflict ),
.i_system_rdy ( i_system_rdy ),
.o_fetch_stall ( fetch_stall ),
208,9 → 210,7
.i_cache_flush ( cache_flush ),
.i_cacheable_area ( cacheable_area ),
 
 
.o_wb_req ( icache_wb_req ),
.o_wb_qword ( icache_wb_qword ),
.o_wb_address ( icache_wb_address ),
.i_wb_read_data ( icache_wb_read_data ),
.i_wb_ready ( icache_wb_ready )
222,8 → 222,8
// ======================================
a25_decode u_decode (
.i_clk ( i_clk ),
.i_access_stall ( access_stall ),
.i_core_stall ( core_stall ),
// Instruction fetch or data read signals
.i_fetch_instruction ( fetch_instruction ),
.i_execute_iaddress ( execute_iaddress ),
303,8 → 303,9
// ======================================
a25_execute u_execute (
.i_clk ( i_clk ),
.i_access_stall ( access_stall ),
.i_core_stall ( core_stall ),
.i_mem_stall ( mem_stall ),
.o_exec_stall ( exec_stall ),
.i_wb_read_data ( wb_read_data ),
.i_wb_read_data_valid ( wb_read_data_valid ),
381,6 → 382,7
a25_mem u_mem (
.i_clk ( i_clk ),
.i_fetch_stall ( fetch_stall ),
.i_exec_stall ( exec_stall ),
.o_mem_stall ( mem_stall ),
.i_daddress ( execute_daddress ),
407,9 → 409,10
.o_wb_write_data ( dcache_wb_write_data ),
.o_wb_byte_enable ( dcache_wb_byte_enable ),
.o_wb_address ( dcache_wb_address ),
.i_wb_read_data ( dcache_wb_read_data ),
.i_wb_cached_ready ( dcache_wb_cached_ready ),
.i_wb_uncached_ready ( dcache_wb_uncached_ready )
.i_wb_cached_rdata ( dcache_wb_cached_rdata ),
.i_wb_uncached_ready ( dcache_wb_uncached_ready ),
.i_wb_uncached_rdata ( dcache_wb_cached_rdata )
);
 
 
431,9 → 434,10
.o_wb_read_data_valid ( wb_read_data_valid ),
.o_wb_load_rd ( wb_load_rd )
);
 
 
 
// ======================================
// Wishbone Master I/F
// ======================================
441,26 → 445,34
// CPU Side
.i_clk ( i_clk ),
// Instruction Cache Accesses
.i_icache_req ( icache_wb_req ),
.i_icache_qword ( icache_wb_qword ),
.i_icache_address ( icache_wb_address ),
.o_icache_read_data ( icache_wb_read_data ),
.o_icache_ready ( icache_wb_ready ),
// Port 0 - dcache uncached
.i_port0_req ( dcache_wb_uncached_req ),
.i_port0_write ( dcache_wb_write ),
.i_port0_wdata ( dcache_wb_write_data ),
.i_port0_be ( dcache_wb_byte_enable ),
.i_port0_addr ( dcache_wb_address ),
.o_port0_rdata ( dcache_wb_uncached_rdata ),
.o_port0_ready ( dcache_wb_uncached_ready ),
 
// Data Cache Accesses
.i_exclusive ( exclusive ),
.i_dcache_cached_req ( dcache_wb_cached_req ),
.i_dcache_uncached_req ( dcache_wb_uncached_req ),
.i_dcache_qword ( dcache_wb_qword ),
.i_dcache_write ( dcache_wb_write ),
.i_dcache_write_data ( dcache_wb_write_data ),
.i_dcache_byte_enable ( dcache_wb_byte_enable ),
.i_dcache_address ( dcache_wb_address ),
.o_dcache_read_data ( dcache_wb_read_data ),
.o_dcache_cached_ready ( dcache_wb_cached_ready ),
.o_dcache_uncached_ready ( dcache_wb_uncached_ready ),
// Port 1 - dcache cached
.i_port1_req ( dcache_wb_cached_req ),
.i_port1_write ( dcache_wb_write ),
.i_port1_wdata ( dcache_wb_write_data ),
.i_port1_be ( dcache_wb_byte_enable ),
.i_port1_addr ( dcache_wb_address ),
.o_port1_rdata ( dcache_wb_cached_rdata ),
.o_port1_ready ( dcache_wb_cached_ready ),
 
// Port 2 - instruction cache accesses, read only
.i_port2_req ( icache_wb_req ),
.i_port2_write ( 1'd0 ),
.i_port2_wdata ( 128'd0 ),
.i_port2_be ( 16'd0 ),
.i_port2_addr ( icache_wb_address ),
.o_port2_rdata ( icache_wb_read_data ),
.o_port2_ready ( icache_wb_ready ),
 
// Wishbone
.o_wb_adr ( o_wb_adr ),
.o_wb_sel ( o_wb_sel ),
.o_wb_we ( o_wb_we ),
473,13 → 485,12
);
 
 
 
// ======================================
// Co-Processor #15
// ======================================
a25_coprocessor u_coprocessor (
.i_clk ( i_clk ),
.i_access_stall ( access_stall ),
.i_core_stall ( core_stall ),
.i_copro_opcode1 ( copro_opcode1 ),
.i_copro_opcode2 ( copro_opcode2 ),
/amber/trunk/hw/vlog/amber25/a25_fetch.v
46,6 → 46,7
(
input i_clk,
input i_mem_stall,
input i_exec_stall,
input i_conflict, // Decode stage stall pipeline because of an instruction conflict
output o_fetch_stall, // when this is asserted all registers
// in decode and exec stages are frozen
61,9 → 62,8
input [31:0] i_cacheable_area, // each bit corresponds to 2MB address space
 
output o_wb_req,
output o_wb_qword, // High for a quad-word fetch request
output [31:0] o_wb_address,
input [31:0] i_wb_read_data,
input [127:0] i_wb_read_data,
input i_wb_ready
 
);
72,6 → 72,7
 
wire core_stall;
wire cache_stall;
wire [127:0] cache_read_data128;
wire [31:0] cache_read_data;
wire sel_cache;
wire uncached_instruction_read;
79,6 → 80,7
wire icache_wb_req;
wire wait_wb;
reg wb_req_r = 'd0;
wire [31:0] wb_rdata32;
 
// ======================================
// Memory Decode
92,8 → 94,19
assign uncached_instruction_read = !sel_cache && i_iaddress_valid && !(cache_stall);
 
// Return read data either from the wishbone bus or the cache
 
assign cache_read_data = i_iaddress[3:2] == 2'd0 ? cache_read_data128[ 31: 0] :
i_iaddress[3:2] == 2'd1 ? cache_read_data128[ 63:32] :
i_iaddress[3:2] == 2'd2 ? cache_read_data128[ 95:64] :
cache_read_data128[127:96] ;
 
assign wb_rdata32 = i_iaddress[3:2] == 2'd0 ? i_wb_read_data[ 31: 0] :
i_iaddress[3:2] == 2'd1 ? i_wb_read_data[ 63:32] :
i_iaddress[3:2] == 2'd2 ? i_wb_read_data[ 95:64] :
i_wb_read_data[127:96] ;
 
assign o_fetch_instruction = sel_cache ? cache_read_data :
uncached_instruction_read ? i_wb_read_data :
uncached_instruction_read ? wb_rdata32 :
32'hffeeddcc ;
 
// Stall the instruction decode and execute stages of the core
103,7 → 116,6
 
assign o_wb_address = i_iaddress;
assign o_wb_req = icache_wb_req || uncached_instruction_read;
assign o_wb_qword = icache_wb_req;
 
assign wait_wb = (o_wb_req || wb_req_r) && !i_wb_ready;
 
110,7 → 122,7
always @(posedge i_clk)
wb_req_r <= o_wb_req && !i_wb_ready;
 
assign core_stall = o_fetch_stall || i_mem_stall || i_conflict;
assign core_stall = o_fetch_stall || i_mem_stall || i_exec_stall || i_conflict;
 
// ======================================
// L1 Instruction Cache
125,7 → 137,7
.i_address_nxt ( i_iaddress_nxt ),
.i_cache_enable ( i_cache_enable ),
.i_cache_flush ( i_cache_flush ),
.o_read_data ( cache_read_data ),
.o_read_data ( cache_read_data128 ),
.o_wb_req ( icache_wb_req ),
.i_wb_read_data ( i_wb_read_data ),
/amber/trunk/hw/vlog/amber25/a25_decompile.v
45,7 → 45,7
module a25_decompile
(
input i_clk,
input i_access_stall,
input i_core_stall,
input [31:0] i_instruction,
input i_instruction_valid,
input i_instruction_undefined,
97,7 → 97,7
// Delay instruction to Execute stage
// ========================================================
always @( posedge i_clk )
if ( !i_access_stall && i_instruction_valid )
if ( !i_core_stall && i_instruction_valid )
begin
execute_instruction <= i_instruction;
execute_address <= i_instruction_address;
109,7 → 109,7
 
 
always @ ( posedge i_clk )
if ( !i_access_stall )
if ( !i_core_stall )
execute_valid <= i_instruction_valid;
// ========================================================
255,7 → 255,44
always @( posedge i_clk )
clk_count <= clk_count + 1'd1;
// =================================================================================
// Memory Reads and Writes
// =================================================================================
 
reg [31:0] tmp_address;
 
 
always @( posedge i_clk )
begin
// Data Write
if ( get_1bit_signal(0) && !get_1bit_signal(3) )
begin
$fwrite(decompile_file, "%09d write addr ", clk_count);
tmp_address = get_32bit_signal(2);
fwrite_hex_drop_zeros(decompile_file, {tmp_address [31:2], 2'd0} );
$fwrite(decompile_file, ", data %08h, be %h",
get_32bit_signal(3), // u_cache.i_write_data
get_4bit_signal (0)); // u_cache.i_byte_enable
$fwrite(decompile_file, "\n");
end
// Data Read
if ( get_1bit_signal(4) && !get_1bit_signal(1) )
begin
$fwrite(decompile_file, "%09d read addr ", clk_count);
tmp_address = get_32bit_signal(5);
fwrite_hex_drop_zeros(decompile_file, {tmp_address[31:2], 2'd0} );
$fwrite(decompile_file, ", data %08h to ", get_32bit_signal(4));
warmreg(get_4bit_signal(1));
$fwrite(decompile_file, "\n");
end
 
// instruction
if ( execute_now )
begin
382,10 → 419,12
$fwrite( decompile_file,"%08x\n", pcf(get_reg_val(5'd21)-4'd4) );
end
end
end
 
 
always @( posedge i_clk )
if ( !i_access_stall )
if ( !i_core_stall )
begin
interrupt_d1 <= i_interrupt;
422,7 → 461,7
if (
i_pc_sel != 3'd0 &&
i_pc_wen &&
!i_access_stall &&
!i_core_stall &&
i_instruction_execute &&
i_interrupt == 3'd0 &&
!execute_undefined &&
438,45 → 477,7
$fwrite(decompile_file,"r1 %08h\n", get_reg_val ( 5'd1 ));
end
 
// =================================================================================
// Memory Reads and Writes
// =================================================================================
 
reg [31:0] tmp_address;
 
// Data access
always @( posedge i_clk )
begin
// Data Write
if ( get_1bit_signal(0) && !get_1bit_signal(3) )
begin
$fwrite(decompile_file, "%09d write addr ", clk_count);
tmp_address = get_32bit_signal(2);
fwrite_hex_drop_zeros(decompile_file, {tmp_address [31:2], 2'd0} );
$fwrite(decompile_file, ", data %08h, be %h",
get_32bit_signal(3), // u_cache.i_write_data
get_4bit_signal (0)); // u_cache.i_byte_enable
$fwrite(decompile_file, "\n");
end
// Data Read
if ( get_1bit_signal(4) && !get_1bit_signal(1) )
begin
$fwrite(decompile_file, "%09d read addr ", clk_count);
tmp_address = get_32bit_signal(5);
fwrite_hex_drop_zeros(decompile_file, {tmp_address[31:2], 2'd0} );
$fwrite(decompile_file, ", data %08h to ", get_32bit_signal(4));
warmreg(get_4bit_signal(1));
$fwrite(decompile_file, "\n");
end
end
 
 
// =================================================================================
// Tasks
// =================================================================================
843,7 → 844,7
3'd0: get_1bit_signal = `U_EXECUTE.o_write_enable;
3'd1: get_1bit_signal = `U_AMBER.mem_stall;
3'd2: get_1bit_signal = `U_EXECUTE.o_daddress_valid;
3'd3: get_1bit_signal = `U_AMBER.access_stall;
3'd3: get_1bit_signal = `U_AMBER.core_stall;
3'd4: get_1bit_signal = `U_WB.mem_read_data_valid_r;
endcase
end
/amber/trunk/hw/vlog/amber25/a25_coprocessor.v
41,7 → 41,7
module a25_coprocessor
(
input i_clk,
input i_access_stall, // stall all stages of the cpu at the same time
input i_core_stall, // stall all stages of the Amber core at the same time
input [2:0] i_copro_opcode1,
input [2:0] i_copro_opcode2,
input [3:0] i_copro_crn, // Register Number
98,7 → 98,7
// Capture an access fault address and status
// ---------------------------
always @ ( posedge i_clk )
if ( !i_access_stall )
if ( !i_core_stall )
begin
if ( i_fault )
begin
117,7 → 117,7
// Register Writes
// ---------------------------
always @ ( posedge i_clk )
if ( !i_access_stall )
if ( !i_core_stall )
begin
if ( i_copro_operation == 2'd2 )
case ( i_copro_crn )
129,7 → 129,7
end
 
// Flush the cache
assign copro15_reg1_write = !i_access_stall && i_copro_operation == 2'd2 && i_copro_crn == 4'd1;
assign copro15_reg1_write = !i_core_stall && i_copro_operation == 2'd2 && i_copro_crn == 4'd1;
 
 
// ---------------------------
136,7 → 136,7
// Register Reads
// ---------------------------
always @ ( posedge i_clk )
if ( !i_access_stall )
if ( !i_core_stall )
case ( i_copro_crn )
// ID Register - [31:24] Company id, [23:16] Manuf id, [15:8] Part type, [7:0] revision
4'd0: o_copro_read_data <= 32'h4156_0300;
161,7 → 161,7
reg [3:0] copro_crn_d1;
 
always @( posedge i_clk )
if ( !i_access_stall )
if ( !i_core_stall )
begin
copro_operation_d1 <= i_copro_operation;
copro_crn_d1 <= i_copro_crn;
168,7 → 168,7
end
 
always @( posedge i_clk )
if ( !i_access_stall )
if ( !i_core_stall )
begin
if ( i_copro_operation == 2'd2 ) // mcr
case ( i_copro_crn )
/amber/trunk/hw/vlog/amber25/a25_execute.v
45,12 → 45,13
module a25_execute (
 
input i_clk,
input i_access_stall, // stall all stages of the cpu at the same time
input i_core_stall, // stall all stages of the Amber core at the same time
input i_mem_stall, // data memory access stalls
output o_exec_stall, // stall the core pipeline
 
input [31:0] i_wb_read_data, // data reads
input i_wb_read_data_valid, // read data is valid
input [9:0] i_wb_load_rd, // Rd for data reads
input [10:0] i_wb_load_rd, // Rd for data reads
 
input [31:0] i_copro_read_data, // From Co-Processor, to either Register
// or Memory
73,7 → 74,7
output reg o_exclusive = 'd0, // swap access
output reg o_write_enable = 'd0,
output reg [3:0] o_byte_enable = 'd0,
output reg [7:0] o_exec_load_rd = 'd0, // The destination register for a load instruction
output reg [8:0] o_exec_load_rd = 'd0, // The destination register for a load instruction
output [31:0] o_status_bits, // Full PC will all status bits, but PC part zero'ed out
output o_multiply_done,
 
156,6 → 157,7
wire [31:0] barrel_shift_in;
wire [31:0] barrel_shift_out;
wire barrel_shift_carry;
wire barrel_shift_stall;
 
wire [3:0] status_bits_flags_nxt;
reg [3:0] status_bits_flags = 'd0;
169,6 → 171,7
reg status_bits_irq_mask = 1'd1;
wire status_bits_firq_mask_nxt;
reg status_bits_firq_mask = 1'd1;
wire [8:0] exec_load_rd_nxt;
 
wire execute; // high when condition execution is true
wire [31:0] reg_write_nxt;
224,8 → 227,8
// ========================================================
// Status Bits Select
// ========================================================
assign ldm_flags = i_wb_read_data_valid & ~i_mem_stall & i_wb_load_rd[7];
assign ldm_status_bits = i_wb_read_data_valid & ~i_mem_stall & i_wb_load_rd[6];
assign ldm_flags = i_wb_read_data_valid & ~i_mem_stall & i_wb_load_rd[8];
assign ldm_status_bits = i_wb_read_data_valid & ~i_mem_stall & i_wb_load_rd[7];
 
 
assign status_bits_flags_nxt = ldm_flags ? read_data_filtered[31:28] :
348,16 → 351,16
// ========================================================
// Filter Read Data
// ========================================================
// mem_load_rd[9:8] -> shift ROR bytes
// mem_load_rd[7] -> load flags with PC
// mem_load_rd[6] -> load status bits with PC
// mem_load_rd[5] -> Write into User Mode register
// mem_load_rd[10:9]-> shift ROR bytes
// mem_load_rd[8] -> load flags with PC
// mem_load_rd[7] -> load status bits with PC
// mem_load_rd[6:5] -> Write into this Mode registers
// mem_load_rd[4] -> zero_extend byte
// mem_load_rd[3:0] -> Destination Register
assign read_data_filtered1 = i_wb_load_rd[9:8] === 2'd0 ? i_wb_read_data :
i_wb_load_rd[9:8] === 2'd1 ? {i_wb_read_data[7:0], i_wb_read_data[31:8]} :
i_wb_load_rd[9:8] === 2'd2 ? {i_wb_read_data[15:0], i_wb_read_data[31:16]} :
{i_wb_read_data[23:0], i_wb_read_data[31:24]} ;
assign read_data_filtered1 = i_wb_load_rd[10:9] === 2'd0 ? i_wb_read_data :
i_wb_load_rd[10:9] === 2'd1 ? {i_wb_read_data[7:0], i_wb_read_data[31:8]} :
i_wb_load_rd[10:9] === 2'd2 ? {i_wb_read_data[15:0], i_wb_read_data[31:16]} :
{i_wb_read_data[23:0], i_wb_read_data[31:24]} ;
 
assign read_data_filtered = i_wb_load_rd[4] ? {24'd0, read_data_filtered1[7:0]} : read_data_filtered1 ;
 
456,7 → 459,7
// ========================================================
// Address Valid
// ========================================================
assign daddress_valid_nxt = execute && i_decode_daccess && !i_access_stall;
assign daddress_valid_nxt = execute && i_decode_daccess && !i_core_stall;
 
// For some multi-cycle instructions, the stream of instrution
// reads can be paused. However if the instruction does not execute
485,27 → 488,36
 
 
// ========================================================
// Set mode for the destination registers of a mem read
// ========================================================
// The mode is either user mode, or the current mode
assign exec_load_rd_nxt = { i_decode_load_rd[7:6],
i_decode_load_rd[5] ? USR : status_bits_mode, // 1 bit -> 2 bits
i_decode_load_rd[4:0] };
 
// ========================================================
// Register Update
// ========================================================
assign o_exec_stall = barrel_shift_stall;
 
assign daddress_update = !i_access_stall;
assign exec_load_rd_update = !i_access_stall && execute;
assign priviledged_update = !i_access_stall;
assign exclusive_update = !i_access_stall && execute;
assign write_enable_update = !i_access_stall;
assign write_data_update = !i_access_stall && execute && i_write_data_wen;
assign byte_enable_update = !i_access_stall && execute && i_write_data_wen;
assign daddress_update = !i_core_stall;
assign exec_load_rd_update = !i_core_stall && execute;
assign priviledged_update = !i_core_stall;
assign exclusive_update = !i_core_stall && execute;
assign write_enable_update = !i_core_stall;
assign write_data_update = !i_core_stall && execute && i_write_data_wen;
assign byte_enable_update = !i_core_stall && execute && i_write_data_wen;
 
assign iaddress_update = pc_dmem_wen || (!i_access_stall && !i_conflict);
assign copro_write_data_update = !i_access_stall && execute && i_copro_write_data_wen;
assign iaddress_update = pc_dmem_wen || (!i_core_stall && !i_conflict);
assign copro_write_data_update = !i_core_stall && execute && i_copro_write_data_wen;
 
assign base_address_update = !i_access_stall && execute && i_base_address_wen;
// assign dcache_read_data_update = !i_mem_stall;
assign status_bits_flags_update = ldm_flags || (!i_access_stall && execute && i_status_bits_flags_wen);
assign status_bits_mode_update = ldm_status_bits || (!i_access_stall && execute && i_status_bits_mode_wen);
assign status_bits_mode_rds_oh_update = !i_access_stall;
assign status_bits_irq_mask_update = ldm_status_bits || (!i_access_stall && execute && i_status_bits_irq_mask_wen);
assign status_bits_firq_mask_update = ldm_status_bits || (!i_access_stall && execute && i_status_bits_firq_mask_wen);
assign base_address_update = !i_core_stall && execute && i_base_address_wen;
assign status_bits_flags_update = ldm_flags || (!i_core_stall && execute && i_status_bits_flags_wen);
assign status_bits_mode_update = ldm_status_bits || (!i_core_stall && execute && i_status_bits_mode_wen);
assign status_bits_mode_rds_oh_update = !i_core_stall;
assign status_bits_irq_mask_update = ldm_status_bits || (!i_core_stall && execute && i_status_bits_irq_mask_wen);
assign status_bits_firq_mask_update = ldm_status_bits || (!i_core_stall && execute && i_status_bits_firq_mask_wen);
 
 
always @( posedge i_clk )
512,7 → 524,7
begin
o_daddress <= daddress_update ? o_daddress_nxt : o_daddress;
o_daddress_valid <= daddress_update ? daddress_valid_nxt : o_daddress_valid;
o_exec_load_rd <= exec_load_rd_update ? i_decode_load_rd : o_exec_load_rd;
o_exec_load_rd <= exec_load_rd_update ? exec_load_rd_nxt : o_exec_load_rd;
o_priviledged <= priviledged_update ? priviledged_nxt : o_priviledged;
o_exclusive <= exclusive_update ? i_decode_exclusive : o_exclusive;
o_write_enable <= write_enable_update ? write_enable_nxt : o_write_enable;
532,11 → 544,12
status_bits_firq_mask <= status_bits_firq_mask_update ? status_bits_firq_mask_nxt : status_bits_firq_mask;
end
 
 
// ========================================================
// Instantiate Barrel Shift
// ========================================================
a25_barrel_shift u_barrel_shift (
.i_clk ( i_clk ),
.i_in ( barrel_shift_in ),
.i_carry_in ( status_bits_flags[1] ),
.i_shift_amount ( shift_amount ),
544,7 → 557,8
.i_function ( i_barrel_shift_function ),
 
.o_out ( barrel_shift_out ),
.o_carry_out ( barrel_shift_carry )
.o_carry_out ( barrel_shift_carry ),
.o_stall ( barrel_shift_stall )
);
 
 
568,7 → 582,7
// ========================================================
a25_multiply u_multiply (
.i_clk ( i_clk ),
.i_access_stall ( i_access_stall ),
.i_core_stall ( i_core_stall ),
.i_a_in ( rs ),
.i_b_in ( rm ),
.i_function ( i_multiply_function ),
584,7 → 598,7
// ========================================================
a25_register_bank u_register_bank(
.i_clk ( i_clk ),
.i_access_stall ( i_access_stall ),
.i_core_stall ( i_core_stall ),
.i_mem_stall ( i_mem_stall ),
.i_rm_sel ( i_rm_sel ),
.i_rs_sel ( i_rs_sel ),
599,7 → 613,7
.i_wb_read_data ( read_data_filtered ),
.i_wb_read_data_valid ( i_wb_read_data_valid ),
.i_wb_read_data_rd ( i_wb_load_rd[3:0] ),
.i_wb_user_mode ( i_wb_load_rd[5] ),
.i_wb_mode ( i_wb_load_rd[6:5] ),
 
.i_status_bits_flags ( status_bits_flags ),
.i_status_bits_irq_mask ( status_bits_irq_mask ),
/amber/trunk/hw/vlog/amber25/a25_config_defines.v
45,13 → 45,18
// Cache Ways
// Changing this parameter is the recommended
// way to change the Amber cache size; 2, 3, 4 and 8 ways are supported.
//
// 2 ways -> 8KB cache
// 3 ways -> 12KB cache
// 4 ways -> 16KB cache
// 8 ways -> 32KB cache
`define A25_ICACHE_WAYS 4
`define A25_DCACHE_WAYS 4
//
// e.g. if both caches have 8 ways, the total is 32KB icache + 32KB dcache = 64KB
 
`define A25_ICACHE_WAYS 2
`define A25_DCACHE_WAYS 2
 
 
// --------------------------------------------------------------------
// Debug switches
// --------------------------------------------------------------------
/amber/trunk/hw/sim/wave.do
1,130 → 1,182
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate -format Literal -radix decimal /tb/clk_count
add wave -noupdate -group System -group {uart 0} -format Logic /tb/u_system/u_uart0/i_uart_rxd
add wave -noupdate -group System -group {uart 0} -format Literal {/tb/u_system/u_uart0/rx_fifo[0]}
add wave -noupdate -group System -group {uart 0} -format Logic /tb/u_system/u_uart0/fifo_enable
add wave -noupdate -group System -group {uart 0} -format Logic /tb/u_system/u_uart0/rx_fifo_push
add wave -noupdate -group System -group {uart 0} -format Logic /tb/u_system/u_uart0/rx_fifo_push_not_full
add wave -noupdate -group System -group {uart 0} -format Literal /tb/u_system/u_uart0/rx_byte
add wave -noupdate -group System -group {uart 0} -format Literal -radix ascii /tb/u_system/u_uart0/xRXD_STATE
add wave -noupdate -group System -group {uart 0} -format Literal -radix decimal /tb/u_system/u_uart0/TX_BITADJUST_COUNT
add wave -noupdate -group System -group {uart 0} -format Literal -radix decimal /tb/u_system/u_uart0/TX_BITPULSE_COUNT
add wave -noupdate -group System -group {uart 0} -format Literal -radix ascii /tb/u_system/u_uart0/xTXD_STATE
add wave -noupdate -group System -group tb_uart -format Logic /tb/u_tb_uart/i_uart_rxd
add wave -noupdate -group System -group tb_uart -format Logic /tb/u_tb_uart/o_uart_txd
add wave -noupdate -group System -group tb_uart -format Literal /tb/u_tb_uart/rx_bit_count
add wave -noupdate -group System -group tb_uart -format Logic /tb/u_tb_uart/rx_bit_start
add wave -noupdate -group System -group tb_uart -format Literal /tb/u_tb_uart/rx_byte
add wave -noupdate -group System -group {DDR3 Bus} -format Literal /tb/u_system/ddr3_addr
add wave -noupdate -group System -group {DDR3 Bus} -format Literal /tb/u_system/ddr3_ba
add wave -noupdate -group System -group {DDR3 Bus} -format Logic /tb/u_system/ddr3_cas_n
add wave -noupdate -group System -group {DDR3 Bus} -format Logic /tb/u_system/ddr3_ck_n
add wave -noupdate -group System -group {DDR3 Bus} -format Logic /tb/u_system/ddr3_ck_p
add wave -noupdate -group System -group {DDR3 Bus} -format Logic /tb/u_system/ddr3_cke
add wave -noupdate -group System -group {DDR3 Bus} -format Literal /tb/u_system/ddr3_dm
add wave -noupdate -group System -group {DDR3 Bus} -format Literal /tb/u_system/ddr3_dq
add wave -noupdate -group System -group {DDR3 Bus} -format Literal /tb/u_system/ddr3_dqs_n
add wave -noupdate -group System -group {DDR3 Bus} -format Literal /tb/u_system/ddr3_dqs_p
add wave -noupdate -group System -group {DDR3 Bus} -format Logic /tb/u_system/ddr3_odt
add wave -noupdate -group System -group {DDR3 Bus} -format Logic /tb/u_system/ddr3_ras_n
add wave -noupdate -group System -group {DDR3 Bus} -format Logic /tb/u_system/ddr3_reset_n
add wave -noupdate -group System -group {DDR3 Bus} -format Logic /tb/u_system/ddr3_we_n
add wave -noupdate -expand -group Amber -format Logic /tb/u_system/u_amber/fetch_stall
add wave -noupdate -expand -group Amber -format Logic /tb/u_system/u_amber/mem_stall
add wave -noupdate -expand -group Amber -expand -group Fetch -format Literal /tb/u_system/u_amber/u_fetch/i_iaddress
add wave -noupdate -expand -group Amber -expand -group Fetch -format Logic /tb/u_system/u_amber/u_fetch/i_iaddress_valid
add wave -noupdate -expand -group Amber -expand -group Fetch -format Literal /tb/u_system/u_amber/u_fetch/o_fetch_instruction
add wave -noupdate -expand -group Amber -expand -group Fetch -format Logic /tb/u_system/u_amber/u_fetch/o_wb_req
add wave -noupdate -expand -group Amber -expand -group Fetch -format Logic /tb/u_system/u_amber/u_fetch/o_fetch_stall
add wave -noupdate -expand -group Amber -expand -group Fetch -format Logic /tb/u_system/u_amber/u_fetch/sel_cache
add wave -noupdate -expand -group Amber -expand -group Fetch -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/o_stall
add wave -noupdate -expand -group Amber -expand -group Fetch -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/read_stall
add wave -noupdate -expand -group Amber -expand -group Fetch -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/o_wb_req
add wave -noupdate -expand -group Amber -expand -group Fetch -group {Instruction Cache} -format Literal -radix ascii /tb/u_system/u_amber/u_fetch/u_cache/xC_STATE
add wave -noupdate -expand -group Amber -expand -group Fetch -group {Instruction Cache} -format Literal /tb/u_system/u_amber/u_fetch/u_cache/miss_address
add wave -noupdate -expand -group Amber -expand -group Fetch -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/read_miss
add wave -noupdate -expand -group Amber -expand -group Fetch -group {Instruction Cache} -format Literal /tb/u_system/u_amber/u_fetch/u_cache/o_read_data
add wave -noupdate -expand -group Amber -expand -group Fetch -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_coprocessor/o_cache_enable
add wave -noupdate -expand -group Amber -expand -group Fetch -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/i_core_stall
add wave -noupdate -expand -group Amber -expand -group Fetch -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/i_select
add wave -noupdate -expand -group Amber -expand -group Fetch -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/sel_cache
add wave -noupdate -expand -group Amber -expand -group Fetch -group {Instruction Cache} -format Literal /tb/u_system/u_amber/u_fetch/u_cache/tag_wdata
add wave -noupdate -expand -group Amber -expand -group Fetch -group {Instruction Cache} -format Literal /tb/u_system/u_amber/u_fetch/u_cache/tag_address
add wave -noupdate -expand -group Amber -expand -group Fetch -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/tag_wenable
add wave -noupdate -expand -group Amber -expand -group Fetch -group {Instruction Cache} -format Literal /tb/u_system/u_amber/u_fetch/u_cache/data_wdata
add wave -noupdate -expand -group Amber -expand -group Decode -format Literal -radix ascii /tb/u_system/u_amber/u_decode/xTYPE
add wave -noupdate -expand -group Amber -expand -group Decode -format Literal -radix ascii /tb/u_system/u_amber/u_decode/xMODE
add wave -noupdate -expand -group Amber -expand -group Decode -format Literal -radix ascii /tb/u_system/u_amber/u_decode/xCONTROL_STATE
add wave -noupdate -expand -group Amber -expand -group Decode -format Logic /tb/u_system/u_amber/u_decode/instruction_execute
add wave -noupdate -expand -group Amber -expand -group Decode -format Logic /tb/u_system/u_amber/u_decode/decode_iaccess_nxt
add wave -noupdate -expand -group Amber -expand -group Decode -format Logic /tb/u_system/u_amber/u_decode/interrupt
add wave -noupdate -expand -group Amber -expand -group Decode -format Literal /tb/u_system/u_amber/u_decode/mtrans_num_registers
add wave -noupdate -expand -group Amber -expand -group Decode -format Logic /tb/u_system/u_amber/u_decode/pre_fetch_instruction_wen
add wave -noupdate -expand -group Amber -expand -group Decode -format Literal /tb/u_system/u_amber/u_decode/fetch_instruction_r
add wave -noupdate -expand -group Amber -expand -group Decode -format Literal /tb/u_system/u_amber/u_decode/instruction
add wave -noupdate -expand -group Amber -expand -group Decode -format Logic /tb/u_system/u_amber/u_decode/instruction_valid
add wave -noupdate -expand -group Amber -expand -group Decode -format Logic /tb/u_system/u_amber/u_decode/saved_current_instruction_wen
add wave -noupdate -expand -group Amber -expand -group Decode -format Logic /tb/u_system/u_amber/u_decode/use_saved_current_instruction
add wave -noupdate -expand -group Amber -expand -group Decode -format Logic /tb/u_system/u_amber/u_decode/pc_wen_nxt
add wave -noupdate -expand -group Amber -expand -group Decode -format Logic /tb/u_system/u_amber/u_decode/write_pc
add wave -noupdate -expand -group Amber -expand -group Decode -expand -group Conflict -format Logic /tb/u_system/u_amber/u_decode/rn_conflict1
add wave -noupdate -expand -group Amber -expand -group Decode -expand -group Conflict -format Logic /tb/u_system/u_amber/u_decode/rn_conflict2
add wave -noupdate -expand -group Amber -expand -group Decode -expand -group Conflict -format Logic /tb/u_system/u_amber/u_decode/conflict1
add wave -noupdate -expand -group Amber -expand -group Decode -expand -group Conflict -format Logic /tb/u_system/u_amber/u_decode/conflict2
add wave -noupdate -expand -group Amber -group Execute -format Logic /tb/u_system/u_amber/u_execute/execute
add wave -noupdate -expand -group Amber -group Execute -format Literal -radix ascii /tb/u_system/u_amber/u_decode/u_decompile/xINSTRUCTION_EXECUTE
add wave -noupdate -expand -group Amber -group Execute -format Literal /tb/u_system/u_amber/u_execute/i_pc_sel
add wave -noupdate -expand -group Amber -group Execute -expand -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r0
add wave -noupdate -expand -group Amber -group Execute -expand -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r1
add wave -noupdate -expand -group Amber -group Execute -expand -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r2
add wave -noupdate -expand -group Amber -group Execute -expand -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r3
add wave -noupdate -expand -group Amber -group Execute -expand -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r12_out
add wave -noupdate -expand -group Amber -group Execute -expand -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r13_out
add wave -noupdate -expand -group Amber -group Execute -expand -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r14_out
add wave -noupdate -expand -group Amber -group Execute -expand -group Registers -format Logic /tb/u_system/u_amber/u_execute/pc_wen
add wave -noupdate -expand -group Amber -group Execute -expand -group Registers -format Literal /tb/u_system/u_amber/u_execute/pc_nxt
add wave -noupdate -expand -group Amber -group Execute -expand -group Registers -format Literal /tb/u_system/u_amber/u_execute/rn
add wave -noupdate -expand -group Amber -group Execute -expand -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r15
add wave -noupdate -expand -group Amber -group Execute -group internals -format Logic /tb/u_system/u_amber/u_decode/instruction_execute
add wave -noupdate -expand -group Amber -group Execute -group internals -format Literal /tb/u_system/u_amber/u_decode/pre_fetch_instruction
add wave -noupdate -expand -group Amber -group Execute -group internals -format Literal -radix ascii /tb/u_system/u_amber/u_decode/u_decompile/xINSTRUCTION_EXECUTE
add wave -noupdate -expand -group Amber -group Execute -group internals -format Literal -radix ascii /tb/u_system/u_amber/u_decode/xCONTROL_STATE
add wave -noupdate -expand -group Amber -group Execute -group internals -format Literal -radix ascii /tb/u_system/u_amber/u_decode/xMODE
add wave -noupdate -expand -group Amber -group Execute -group internals -format Literal /tb/u_system/u_amber/u_execute/i_pc_sel
add wave -noupdate -expand -group Amber -group Execute -group internals -format Logic /tb/u_system/u_amber/u_decode/o_pc_wen
add wave -noupdate -expand -group Amber -group Execute -group internals -format Logic /tb/u_system/u_amber/u_decode/u_decompile/execute_valid
add wave -noupdate -expand -group Amber -group Execute -group internals -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r14_irq
add wave -noupdate -expand -group Amber -group Execute -group internals -format Literal /tb/u_system/u_amber/u_execute/pc
add wave -noupdate -expand -group Amber -group Execute -group internals -format Logic /tb/u_system/u_amber/u_execute/pc_wen
add wave -noupdate -expand -group Amber -group Execute -group internals -format Literal /tb/u_system/u_amber/u_execute/i_pc_sel
add wave -noupdate -expand -group Amber -group Execute -group internals -format Literal /tb/u_system/u_amber/u_execute/alu_out
add wave -noupdate -expand -group Amber -group Execute -group internals -format Logic /tb/u_system/u_amber/u_execute/i_status_bits_flags_wen
add wave -noupdate -expand -group Amber -group Execute -group internals -format Literal /tb/u_system/u_amber/u_execute/status_bits_flags
add wave -noupdate -expand -group Amber -group Execute -group internals -format Literal /tb/u_system/u_amber/u_execute/i_status_bits_sel
add wave -noupdate -expand -group Amber -group Execute -group internals -format Literal /tb/u_system/u_amber/u_execute/i_condition
add wave -noupdate -expand -group Amber -group Execute -group internals -format Logic /tb/u_system/u_amber/u_execute/execute
add wave -noupdate -expand -group Amber -group Wishbone -expand -group {WB Bus} -format Logic /tb/u_system/u_amber/o_wb_cyc
add wave -noupdate -expand -group Amber -group Wishbone -expand -group {WB Bus} -format Logic /tb/u_system/u_amber/o_wb_stb
add wave -noupdate -expand -group Amber -group Wishbone -expand -group {WB Bus} -format Logic /tb/u_system/u_amber/i_wb_ack
add wave -noupdate -expand -group Amber -group Wishbone -expand -group {WB Bus} -format Literal /tb/u_system/u_amber/u_wishbone/o_wb_adr
add wave -noupdate -expand -group Amber -group Wishbone -expand -group {WB Bus} -format Literal /tb/u_system/u_amber/o_wb_dat
add wave -noupdate -expand -group Amber -group Wishbone -expand -group {WB Bus} -format Literal /tb/u_system/u_amber/o_wb_sel
add wave -noupdate -expand -group Amber -group Wishbone -expand -group {WB Bus} -format Logic /tb/u_system/u_amber/o_wb_we
add wave -noupdate -expand -group Amber -group Wishbone -expand -group {WB Bus} -format Literal /tb/u_system/u_amber/i_wb_dat
add wave -noupdate -expand -group Amber -group Wishbone -expand -group {WB Bus} -format Logic /tb/u_system/u_amber/i_wb_err
add wave -noupdate -expand -group Amber -group Co-Processor -format Literal /tb/u_system/u_amber/u_coprocessor/fault_address
add wave -noupdate -expand -group Amber -group Co-Processor -format Literal /tb/u_system/u_amber/u_coprocessor/fault_status
add wave -noupdate -format Literal -radix decimal -radixenum numeric /tb/clk_count
add wave -noupdate -expand -group System -height 20 -group {uart 0} -format Logic /tb/u_system/u_uart0/i_uart_rxd
add wave -noupdate -expand -group System -height 20 -group {uart 0} -format Literal {/tb/u_system/u_uart0/rx_fifo[0]}
add wave -noupdate -expand -group System -height 20 -group {uart 0} -format Logic /tb/u_system/u_uart0/fifo_enable
add wave -noupdate -expand -group System -height 20 -group {uart 0} -format Logic /tb/u_system/u_uart0/rx_fifo_push
add wave -noupdate -expand -group System -height 20 -group {uart 0} -format Logic /tb/u_system/u_uart0/rx_fifo_push_not_full
add wave -noupdate -expand -group System -height 20 -group {uart 0} -format Literal /tb/u_system/u_uart0/rx_byte
add wave -noupdate -expand -group System -height 20 -group {uart 0} -format Literal -radix ascii /tb/u_system/u_uart0/xRXD_STATE
add wave -noupdate -expand -group System -height 20 -group {uart 0} -format Literal -radix decimal /tb/u_system/u_uart0/TX_BITADJUST_COUNT
add wave -noupdate -expand -group System -height 20 -group {uart 0} -format Literal -radix decimal /tb/u_system/u_uart0/TX_BITPULSE_COUNT
add wave -noupdate -expand -group System -height 20 -group {uart 0} -format Literal -radix ascii /tb/u_system/u_uart0/xTXD_STATE
add wave -noupdate -expand -group System -height 20 -group tb_uart -format Logic /tb/u_tb_uart/i_uart_rxd
add wave -noupdate -expand -group System -height 20 -group tb_uart -format Logic /tb/u_tb_uart/o_uart_txd
add wave -noupdate -expand -group System -height 20 -group tb_uart -format Literal /tb/u_tb_uart/rx_bit_count
add wave -noupdate -expand -group System -height 20 -group tb_uart -format Logic /tb/u_tb_uart/rx_bit_start
add wave -noupdate -expand -group System -height 20 -group tb_uart -format Literal /tb/u_tb_uart/rx_byte
add wave -noupdate -expand -group System -height 20 -group {DDR3 Bus} -format Literal /tb/u_system/ddr3_addr
add wave -noupdate -expand -group System -height 20 -group {DDR3 Bus} -format Literal /tb/u_system/ddr3_ba
add wave -noupdate -expand -group System -height 20 -group {DDR3 Bus} -format Logic /tb/u_system/ddr3_cas_n
add wave -noupdate -expand -group System -height 20 -group {DDR3 Bus} -format Logic /tb/u_system/ddr3_ck_n
add wave -noupdate -expand -group System -height 20 -group {DDR3 Bus} -format Logic /tb/u_system/ddr3_ck_p
add wave -noupdate -expand -group System -height 20 -group {DDR3 Bus} -format Logic /tb/u_system/ddr3_cke
add wave -noupdate -expand -group System -height 20 -group {DDR3 Bus} -format Literal /tb/u_system/ddr3_dm
add wave -noupdate -expand -group System -height 20 -group {DDR3 Bus} -format Literal /tb/u_system/ddr3_dq
add wave -noupdate -expand -group System -height 20 -group {DDR3 Bus} -format Literal /tb/u_system/ddr3_dqs_n
add wave -noupdate -expand -group System -height 20 -group {DDR3 Bus} -format Literal /tb/u_system/ddr3_dqs_p
add wave -noupdate -expand -group System -height 20 -group {DDR3 Bus} -format Logic /tb/u_system/ddr3_odt
add wave -noupdate -expand -group System -height 20 -group {DDR3 Bus} -format Logic /tb/u_system/ddr3_ras_n
add wave -noupdate -expand -group System -height 20 -group {DDR3 Bus} -format Logic /tb/u_system/ddr3_reset_n
add wave -noupdate -expand -group System -height 20 -group {DDR3 Bus} -format Logic /tb/u_system/ddr3_we_n
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Literal /tb/u_system/u_amber/u_execute/pc
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Literal -radix ascii /tb/u_system/u_amber/u_decode/u_decompile/xINSTRUCTION_EXECUTE
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Literal -radix ascii /tb/u_system/u_amber/u_decode/xCONTROL_STATE
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Literal -radix ascii /tb/u_system/u_amber/u_execute/xMODE
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Literal /tb/u_system/u_amber/u_execute/o_iaddress
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Logic /tb/u_system/u_amber/u_execute/o_iaddress_valid
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Logic /tb/u_system/u_amber/u_execute/i_core_stall
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Logic /tb/u_system/u_amber/u_execute/o_exec_stall
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Logic /tb/u_system/u_amber/u_mem/o_mem_stall
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Logic /tb/u_system/u_amber/fetch_stall
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Literal /tb/u_system/u_amber/u_fetch/o_fetch_instruction
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Logic /tb/u_system/u_amber/u_execute/o_daddress_valid
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Literal /tb/u_system/u_amber/u_execute/o_daddress
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Logic /tb/u_system/u_amber/u_execute/o_write_enable
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Literal /tb/u_system/u_amber/u_execute/o_write_data
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Logic /tb/u_system/u_amber/u_mem/o_mem_read_data_valid
add wave -noupdate -expand -group Amber -expand -group {Core Memory Accesses} -format Literal /tb/u_system/u_amber/u_mem/o_mem_read_data
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -height 20 -group {Read buffer} -format Literal /tb/u_system/u_amber/u_fetch/u_cache/read_buf_addr_r
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -height 20 -group {Read buffer} -format Literal /tb/u_system/u_amber/u_fetch/u_cache/read_buf_data_r
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -height 20 -group {Read buffer} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/read_buf_hit
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -height 20 -group {Read buffer} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/read_buf_valid_r
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/o_stall
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/read_stall
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/o_wb_req
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/i_wb_ready
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -format Literal -radix ascii /tb/u_system/u_amber/u_fetch/u_cache/xC_STATE
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -format Literal /tb/u_system/u_amber/u_fetch/u_cache/miss_address
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/read_miss
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -format Literal /tb/u_system/u_amber/u_fetch/u_cache/o_read_data
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_coprocessor/o_cache_enable
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/i_core_stall
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/i_select
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/sel_cache
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -format Literal /tb/u_system/u_amber/u_fetch/u_cache/tag_wdata
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -format Literal /tb/u_system/u_amber/u_fetch/u_cache/tag_address
add wave -noupdate -expand -group Amber -height 20 -group Fetch -height 20 -expand -group {Instruction Cache} -format Logic /tb/u_system/u_amber/u_fetch/u_cache/tag_wenable
add wave -noupdate -expand -group Amber -height 20 -group Decode -format Literal -radix ascii /tb/u_system/u_amber/u_decode/xTYPE
add wave -noupdate -expand -group Amber -height 20 -group Decode -format Literal -radix ascii /tb/u_system/u_amber/u_decode/xMODE
add wave -noupdate -expand -group Amber -height 20 -group Decode -format Logic /tb/u_system/u_amber/u_decode/instruction_execute
add wave -noupdate -expand -group Amber -height 20 -group Decode -format Logic /tb/u_system/u_amber/u_decode/decode_iaccess_nxt
add wave -noupdate -expand -group Amber -height 20 -group Decode -format Logic /tb/u_system/u_amber/u_decode/interrupt
add wave -noupdate -expand -group Amber -height 20 -group Decode -format Literal /tb/u_system/u_amber/u_decode/mtrans_num_registers
add wave -noupdate -expand -group Amber -height 20 -group Decode -format Logic /tb/u_system/u_amber/u_decode/pre_fetch_instruction_wen
add wave -noupdate -expand -group Amber -height 20 -group Decode -format Literal /tb/u_system/u_amber/u_decode/fetch_instruction_r
add wave -noupdate -expand -group Amber -height 20 -group Decode -format Literal /tb/u_system/u_amber/u_decode/instruction
add wave -noupdate -expand -group Amber -height 20 -group Decode -format Logic /tb/u_system/u_amber/u_decode/instruction_valid
add wave -noupdate -expand -group Amber -height 20 -group Decode -format Logic /tb/u_system/u_amber/u_decode/saved_current_instruction_wen
add wave -noupdate -expand -group Amber -height 20 -group Decode -format Logic /tb/u_system/u_amber/u_decode/use_saved_current_instruction
add wave -noupdate -expand -group Amber -height 20 -group Decode -format Logic /tb/u_system/u_amber/u_decode/pc_wen_nxt
add wave -noupdate -expand -group Amber -height 20 -group Decode -format Logic /tb/u_system/u_amber/u_decode/write_pc
add wave -noupdate -expand -group Amber -height 20 -group Decode -height 20 -group Conflict -format Logic /tb/u_system/u_amber/u_decode/rn_conflict1
add wave -noupdate -expand -group Amber -height 20 -group Decode -height 20 -group Conflict -format Logic /tb/u_system/u_amber/u_decode/rn_conflict2
add wave -noupdate -expand -group Amber -height 20 -group Decode -height 20 -group Conflict -format Logic /tb/u_system/u_amber/u_decode/conflict1
add wave -noupdate -expand -group Amber -height 20 -group Decode -height 20 -group Conflict -format Logic /tb/u_system/u_amber/u_decode/conflict2
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -format Logic /tb/u_system/u_amber/u_execute/execute
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -format Literal -radix ascii /tb/u_system/u_amber/u_decode/u_decompile/xINSTRUCTION_EXECUTE
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -format Literal /tb/u_system/u_amber/u_execute/i_pc_sel
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/reg_write_nxt
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/i_wb_read_data
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/i_wb_mode
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal -radix unsigned /tb/u_system/u_amber/u_execute/u_register_bank/i_wb_read_data_rd
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/reg_bank_wen_c
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal -radix hexadecimal /tb/u_system/u_amber/u_execute/i_reg_bank_wen
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/read_data_wen
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r0
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r1
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r2
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r3
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r8
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r12_out
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r13_out
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r14_irq
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r14_svc
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r14_out
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Logic /tb/u_system/u_amber/u_execute/pc_wen
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/pc_nxt
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/rn
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group Registers -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r15
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group internals -format Logic /tb/u_system/u_amber/u_decode/instruction_execute
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group internals -format Literal /tb/u_system/u_amber/u_decode/pre_fetch_instruction
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group internals -format Literal -radix ascii /tb/u_system/u_amber/u_decode/xCONTROL_STATE
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group internals -format Literal -radix ascii /tb/u_system/u_amber/u_decode/xMODE
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group internals -format Literal /tb/u_system/u_amber/u_execute/i_pc_sel
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group internals -format Logic /tb/u_system/u_amber/u_decode/o_pc_wen
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group internals -format Logic /tb/u_system/u_amber/u_decode/u_decompile/execute_valid
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group internals -format Literal /tb/u_system/u_amber/u_execute/u_register_bank/r14_irq
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group internals -format Logic /tb/u_system/u_amber/u_execute/pc_wen
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group internals -format Literal /tb/u_system/u_amber/u_execute/i_pc_sel
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group internals -format Literal /tb/u_system/u_amber/u_execute/alu_out
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group internals -format Logic /tb/u_system/u_amber/u_execute/i_status_bits_flags_wen
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group internals -format Literal /tb/u_system/u_amber/u_execute/status_bits_flags
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group internals -format Literal /tb/u_system/u_amber/u_execute/i_status_bits_sel
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group internals -format Literal /tb/u_system/u_amber/u_execute/i_condition
add wave -noupdate -expand -group Amber -height 20 -expand -group Execute -height 20 -group internals -format Logic /tb/u_system/u_amber/u_execute/execute
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -height 20 -expand -group {WB Bus} -format Logic /tb/u_system/u_amber/o_wb_cyc
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -height 20 -expand -group {WB Bus} -format Logic /tb/u_system/u_amber/o_wb_stb
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -height 20 -expand -group {WB Bus} -format Logic /tb/u_system/u_amber/i_wb_ack
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -height 20 -expand -group {WB Bus} -format Literal /tb/u_system/u_amber/u_wishbone/o_wb_adr
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -height 20 -expand -group {WB Bus} -format Literal /tb/u_system/u_amber/o_wb_dat
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -height 20 -expand -group {WB Bus} -format Literal /tb/u_system/u_amber/o_wb_sel
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -height 20 -expand -group {WB Bus} -format Logic /tb/u_system/u_amber/o_wb_we
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -height 20 -expand -group {WB Bus} -format Literal /tb/u_system/u_amber/i_wb_dat
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -height 20 -expand -group {WB Bus} -format Logic /tb/u_system/u_amber/i_wb_err
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -group {Port 0} -format Logic /tb/u_system/u_amber/u_wishbone/i_port0_req
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -group {Port 0} -format Literal /tb/u_system/u_amber/u_wishbone/i_port0_addr
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -group {Port 0} -format Literal /tb/u_system/u_amber/u_wishbone/i_port0_be
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -group {Port 0} -format Literal /tb/u_system/u_amber/u_wishbone/i_port0_wdata
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -group {Port 0} -format Logic /tb/u_system/u_amber/u_wishbone/i_port0_write
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -group {Port 0} -format Literal /tb/u_system/u_amber/u_wishbone/o_port0_rdata
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -group {Port 0} -format Logic /tb/u_system/u_amber/u_wishbone/o_port0_ready
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -group {Port 2} -format Literal /tb/u_system/u_amber/u_wishbone/i_port2_addr
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -group {Port 2} -format Literal /tb/u_system/u_amber/u_wishbone/i_port2_be
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -group {Port 2} -format Logic /tb/u_system/u_amber/u_wishbone/i_port2_req
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -group {Port 2} -format Literal /tb/u_system/u_amber/u_wishbone/i_port2_wdata
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -group {Port 2} -format Logic /tb/u_system/u_amber/u_wishbone/i_port2_write
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -group {Port 2} -format Literal /tb/u_system/u_amber/u_wishbone/o_port2_rdata
add wave -noupdate -expand -group Amber -height 20 -group Wishbone -group {Port 2} -format Logic /tb/u_system/u_amber/u_wishbone/o_port2_ready
add wave -noupdate -expand -group Amber -height 20 -group Co-Processor -format Literal /tb/u_system/u_amber/u_coprocessor/fault_address
add wave -noupdate -expand -group Amber -height 20 -group Co-Processor -format Literal /tb/u_system/u_amber/u_coprocessor/fault_status
add wave -noupdate -group DCache -format Literal -radix ascii /tb/u_system/u_amber/u_mem/u_dcache/xC_STATE
add wave -noupdate -group DCache -format Literal -radix ascii /tb/u_system/u_amber/u_mem/u_dcache/xSOURCE_SEL
add wave -noupdate -group DCache -format Logic /tb/u_system/u_amber/u_mem/u_dcache/read_stall
add wave -noupdate -group DCache -format Logic /tb/u_system/u_amber/u_mem/u_dcache/write_stall
add wave -noupdate -group DCache -format Logic /tb/u_system/u_amber/u_mem/u_dcache/cache_busy_stall
add wave -noupdate -group DCache -format Logic /tb/u_system/u_amber/u_mem/u_dcache/write_hit
add wave -noupdate -group DCache -format Logic /tb/u_system/u_amber/u_mem/u_dcache/write_miss
add wave -noupdate -group DCache -format Literal /tb/u_system/u_amber/u_mem/u_dcache/o_read_data
add wave -noupdate -group DCache -format Logic /tb/u_system/u_amber/u_mem/u_dcache/consecutive_write
add wave -noupdate -group DCache -format Literal /tb/u_system/u_amber/u_mem/u_dcache/data_wdata_r
add wave -noupdate -group DCache -format Literal -radix binary /tb/u_system/u_amber/u_mem/u_dcache/data_wenable_way
add wave -noupdate -group DCache -format Logic /tb/u_system/u_amber/u_mem/u_dcache/tag_wenable
add wave -noupdate -group DCache -format Literal /tb/u_system/u_amber/u_mem/u_dcache/tag_address
add wave -noupdate -group DCache -format Literal /tb/u_system/u_amber/u_mem/u_dcache/tag_wdata
add wave -noupdate -group DCache -format Literal /tb/u_system/u_amber/u_mem/u_dcache/data_wdata
add wave -noupdate -format Logic /tb/u_system/u_amber/u_execute/u_barrel_shift/o_stall
add wave -noupdate -format Logic /tb/u_system/u_amber/u_execute/u_barrel_shift/use_quick_r
add wave -noupdate -format Literal /tb/u_system/u_amber/u_execute/u_barrel_shift/i_shift_amount
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {1138913 ps} 0} {{Cursor 3} {10386717250 ps} 0}
configure wave -namecolwidth 279
configure wave -valuecolwidth 174
WaveRestoreCursors {{Cursor 1} {30001543 ps} 0} {{Cursor 3} {81811238721 ps} 0}
configure wave -namecolwidth 258
configure wave -valuecolwidth 203
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -rowmargin 8
configure wave -childrowmargin 6
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 4000
131,4 → 183,4
configure wave -timeline 0
configure wave -timelineunits ns
update
WaveRestoreZoom {913193 ps} {1614177 ps}
WaveRestoreZoom {0 ps} {9006375 ps}
/amber/trunk/hw/sim/run-log.do
1,3 → 1,11
log -r /tb/u_system/u_amber/u_fetch/*
log -r /tb/u_system/u_amber/u_mem/*
log -r /tb/u_system/u_amber/u_execute/*
log /tb/u_system/u_amber/u_execute/u_register_bank/*
log /tb/u_system/u_amber/u_decode/*
log /tb/u_system/u_amber/u_wishbone/*
 
 
log /tb/clk_count
log /tb/u_system/u_uart0/i_uart_rxd
log /tb/u_system/u_uart0/rx_fifo
45,7 → 53,6
log /tb/u_system/u_amber/u_fetch/u_cache/tag_wdata
log /tb/u_system/u_amber/u_fetch/u_cache/tag_address
log /tb/u_system/u_amber/u_fetch/u_cache/tag_wenable
log /tb/u_system/u_amber/u_fetch/u_cache/data_wdata
log /tb/u_system/u_amber/u_decode/xMODE
log /tb/u_system/u_amber/u_decode/xCONTROL_STATE
log /tb/u_system/u_amber/u_decode/instruction_execute
61,13 → 68,6
log /tb/u_system/u_amber/u_execute/execute
log /tb/u_system/u_amber/u_decode/u_decompile/xINSTRUCTION_EXECUTE
log /tb/u_system/u_amber/u_execute/i_pc_sel
log /tb/u_system/u_amber/u_execute/u_register_bank/r0
log /tb/u_system/u_amber/u_execute/u_register_bank/r1
log /tb/u_system/u_amber/u_execute/u_register_bank/r2
log /tb/u_system/u_amber/u_execute/u_register_bank/r3
log /tb/u_system/u_amber/u_execute/u_register_bank/r12_out
log /tb/u_system/u_amber/u_execute/u_register_bank/r13_out
log /tb/u_system/u_amber/u_execute/u_register_bank/r14_out
log /tb/u_system/u_amber/u_execute/pc_wen
log /tb/u_system/u_amber/u_execute/pc_nxt
log /tb/u_system/u_amber/u_execute/rn
amber/trunk/hw/sim Property changes : Modified: svn:ignore ## -15,3 +15,4 ## *.vtakprj *.vtakwave work +rt Index: amber/trunk/hw/fpga/bin/xv6_source_files.prj =================================================================== --- amber/trunk/hw/fpga/bin/xv6_source_files.prj (revision 34) +++ amber/trunk/hw/fpga/bin/xv6_source_files.prj (revision 35) @@ -50,6 +50,7 @@ verilog work ../../vlog/system/wishbone_arbiter.v verilog work ../../vlog/system/afifo.v verilog work ../../vlog/system/ddr3_afifo.v +verilog work ../../vlog/system/ethmac_wb.v # EthMac verilog work ../../vlog/ethmac/eth_clockgen.v @@ -93,6 +94,7 @@ # Amber 25 verilog work ../../vlog/amber25/a25_alu.v verilog work ../../vlog/amber25/a25_barrel_shift.v +verilog work ../../vlog/amber25/a25_shifter.v verilog work ../../vlog/amber25/a25_coprocessor.v verilog work ../../vlog/amber25/a25_core.v verilog work ../../vlog/amber25/a25_dcache.v @@ -104,6 +106,7 @@ verilog work ../../vlog/amber25/a25_multiply.v verilog work ../../vlog/amber25/a25_register_bank.v verilog work ../../vlog/amber25/a25_wishbone.v +verilog work ../../vlog/amber25/a25_wishbone_buf.v verilog work ../../vlog/amber25/a25_write_back.v # Xilinx Virtex-6 FPGA Hardware wrappers
/amber/trunk/hw/fpga/bin/xs6_source_files.prj
50,6 → 50,7
verilog work ../../vlog/system/wishbone_arbiter.v
verilog work ../../vlog/system/afifo.v
verilog work ../../vlog/system/ddr3_afifo.v
verilog work ../../vlog/system/ethmac_wb.v
 
# EthMac
verilog work ../../vlog/ethmac/eth_clockgen.v
93,6 → 94,7
# Amber 25
verilog work ../../vlog/amber25/a25_alu.v
verilog work ../../vlog/amber25/a25_barrel_shift.v
verilog work ../../vlog/amber25/a25_shifter.v
verilog work ../../vlog/amber25/a25_coprocessor.v
verilog work ../../vlog/amber25/a25_core.v
verilog work ../../vlog/amber25/a25_dcache.v
104,6 → 106,7
verilog work ../../vlog/amber25/a25_multiply.v
verilog work ../../vlog/amber25/a25_register_bank.v
verilog work ../../vlog/amber25/a25_wishbone.v
verilog work ../../vlog/amber25/a25_wishbone_buf.v
verilog work ../../vlog/amber25/a25_write_back.v
 
# Xilinx Spartan-6 FPGA Hardware wrappers
/amber/trunk/hw/fpga/bin/Makefile
93,7 → 93,7
else
# The spartan6 device used on SP605 Development board
XILINX_FPGA = xc6slx45tfgg484-3
XST_DEFINES = XILINX_FPGA XILINX_SPARTAN6_FPGA $(AMBER_CORE) AMBER_CLK_DIVIDER=20
XST_DEFINES = XILINX_FPGA XILINX_SPARTAN6_FPGA $(AMBER_CORE) AMBER_CLK_DIVIDER=18
# Xilinx placement and timing constraints
XST_CONST_FILE = xs6_constraints.ucf
# List of verilog source files for Xilinx Spartan-6 device
201,7 → 201,7
$(WORK_FOLDER)/$(RTL_TOP).trc.twr : $(WORK_FOLDER)/$(RTL_TOP).ncd
\
cd $(WORK_FOLDER); \
trce -v 20 -l 20 -n 5 -xml $(RTL_TOP) $(RTL_TOP).ncd \
trce -v 5 -l 5 -n 5 -xml $(RTL_TOP) $(RTL_TOP).ncd \
-o $(WORK_FOLDER)/$(RTL_TOP).trc.twr \
$(RTL_TOP).pcf
cp $(WORK_FOLDER)/$(RTL_TOP).trc.twr $(LOG_FOLDER)/$(RTL_TOP).trc.$(RUN_ID).twr
245,7 → 245,6
-detail \
-timing \
-register_duplication \
-global_opt off \
-lc auto \
-xe c -mt off -ir off \
-pr off -power off \

powered by: WebSVN 2.1.0

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