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 \ |