URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 562 to Rev 563
- ↔ Reverse comparison
Rev 562 → Rev 563
/trunk/mp3/bench/verilog/wb_master.v
0,0 → 1,306
`include "timescale.v" |
|
// -*- Mode: Verilog -*- |
// Filename : wb_master.v |
// Description : Wishbone Master Behavorial |
// Author : Winefred Washington |
// Created On : Thu Jan 11 21:18:41 2001 |
// Last Modified By: . |
// Last Modified On: . |
// Update Count : 0 |
// Status : Unknown, Use with caution! |
|
// Description Specification |
// General Description: 8, 16, 32-bit WISHBONE Master |
// Supported cycles: MASTER, READ/WRITE |
// MASTER, BLOCK READ/WRITE |
// MASTER, RMW |
// Data port, size: 8, 16, 32-bit |
// Data port, granularity 8-bit |
// Data port, Max. operand size 32-bit |
// Data transfer ordering: little endian |
// Data transfer sequencing: undefined |
// |
|
module wb_master(CLK_I, RST_I, TAG_I, TAG_O, |
ACK_I, ADR_O, CYC_O, DAT_I, DAT_O, ERR_I, RTY_I, SEL_O, STB_O, WE_O); |
|
input CLK_I; |
input RST_I; |
input [3:0] TAG_I; |
output [3:0] TAG_O; |
input ACK_I; |
output [31:0] ADR_O; |
output CYC_O; |
input [31:0] DAT_I; |
output [31:0] DAT_O; |
input ERR_I; |
input RTY_I; |
output [3:0] SEL_O; |
output STB_O; |
output WE_O; |
|
reg [31:0] ADR_O; |
reg [3:0] SEL_O; |
reg CYC_O; |
reg STB_O; |
reg WE_O; |
reg [31:0] DAT_O; |
|
wire [15:0] mem_sizes; // determines the data width of an address range |
reg [31:0] write_burst_buffer[0:7]; |
reg [31:0] read_burst_buffer[0:7]; |
|
reg GO; |
integer cycle_end; |
integer address; |
integer data; |
integer selects; |
integer write_flag; |
|
// |
// mem_sizes determines the data widths of memory space |
// The memory space is divided into eight regions. Each |
// region is controlled by a two bit field. |
// |
// Bits |
// 00 = 8 bit memory space |
// 01 = 16 bit |
// 10 = 32 bit |
// 11 = 64 bit (not supported in this model |
// |
|
assign mem_sizes = 16'b10_10_10_10_10_10_10_10; |
|
function [1:0] data_width; |
input [31:0] adr; |
begin |
casex (adr[31:29]) |
3'b000: data_width = mem_sizes[15:14]; |
3'b001: data_width = mem_sizes[13:12]; |
3'b010: data_width = mem_sizes[11:10]; |
3'b011: data_width = mem_sizes[9:8]; |
3'b100: data_width = mem_sizes[7:6]; |
3'b101: data_width = mem_sizes[5:4]; |
3'b110: data_width = mem_sizes[3:2]; |
3'b111: data_width = mem_sizes[1:0]; |
3'bxxx: data_width = 2'bxx; |
endcase // casex (adr[31:29]) |
end |
endfunction |
|
always @(posedge CLK_I or posedge RST_I) |
begin |
if (RST_I) |
begin |
GO = 1'b0; |
end |
end |
|
// read single |
task rd; |
input [31:0] adr; |
output [31:0] result; |
|
begin |
cycle_end = 1; |
address = adr; |
selects = 255; |
write_flag = 0; |
|
GO <= 1; |
@(posedge CLK_I); |
// GO <= 0; |
|
// wait for cycle to start |
while (~CYC_O) |
@(posedge CLK_I); |
|
// wait for cycle to end |
while (CYC_O) |
@(posedge CLK_I); |
|
result = data; |
// $display(" Reading %h from address %h", result, address); |
|
end |
endtask // read |
|
task wr; |
input [31:0] adr; |
input [31:0] dat; |
input [3:0] sel; |
begin |
cycle_end = 1; |
address = adr; |
selects = sel; |
write_flag = 1; |
data = dat; |
|
GO <= 1; |
@(posedge CLK_I); |
// GO <= 0; |
|
// wait for cycle to start |
while (~CYC_O) |
@(posedge CLK_I); |
|
// wait for cycle to end |
while (CYC_O) |
@(posedge CLK_I); |
// $display(" Writing %h to address %h", data, address); |
|
end |
endtask // wr |
|
// block read |
task blkrd; |
input [31:0] adr; |
input end_flag; |
output [31:0] result; |
|
begin |
write_flag = 0; |
cycle_end = end_flag; |
address = adr; |
GO <= 1; |
@(posedge CLK_I); |
// GO <= 0; |
|
while (~(ACK_I & STB_O)) |
@(posedge CLK_I); |
|
result = data; |
end |
endtask // blkrd |
|
// block write |
task blkwr; |
input [31:0] adr; |
input [31:0] dat; |
input [3:0] sel; |
input end_flag; |
begin |
write_flag = 1; |
cycle_end = end_flag; |
address = adr; |
data = dat; |
selects = sel; |
GO <= 1; |
@(posedge CLK_I); |
// GO <= 0; |
|
while (~(ACK_I & STB_O)) |
@(posedge CLK_I); |
|
end |
endtask // blkwr |
|
// RMW |
task rmw; |
input [31:0] adr; |
input [31:0] dat; |
input [3:0] sel; |
output [31:0] result; |
|
begin |
// read phase |
write_flag = 0; |
cycle_end = 0; |
address = adr; |
GO <= 1; |
@(posedge CLK_I); |
// GO <= 0; |
|
while (~(ACK_I & STB_O)) |
@(posedge CLK_I); |
|
result = data; |
|
// write phase |
write_flag = 1; |
address = adr; |
selects = sel; |
GO <= 1; |
data <= dat; |
cycle_end <= 1; |
@(posedge CLK_I); |
// GO <= 0; |
|
while (~(ACK_I & STB_O)) |
@(posedge CLK_I); |
|
end |
endtask // rmw |
|
always @(posedge CLK_I) |
begin |
if (RST_I) |
ADR_O <= 32'h0000_0000; |
else |
ADR_O <= address; |
end |
|
always @(posedge CLK_I) |
begin |
if (RST_I | ERR_I | RTY_I) |
CYC_O <= 1'b0; |
else if ((cycle_end == 1) & ACK_I) |
CYC_O <= 1'b0; |
else if (GO | CYC_O) begin |
CYC_O <= 1'b1; |
GO <= 1'b0; |
end |
end |
|
// stb control |
always @(posedge CLK_I) |
begin |
if (RST_I | ERR_I | RTY_I) |
STB_O <= 1'b0; |
else if (STB_O & ACK_I) |
STB_O <= 1'b0; |
else if (GO | STB_O) |
STB_O <= 1'b1; |
end |
|
// selects & data |
always @(posedge CLK_I) |
begin |
if (write_flag == 0) begin |
SEL_O <= 4'b1111; |
if (STB_O & ACK_I) |
data <= DAT_I; |
end |
else begin |
case (data_width(address)) |
2'b00: begin |
SEL_O <= {3'b000, selects[0]}; |
DAT_O <= {data[7:0], data[7:0], data[7:0], data[7:0]}; |
end |
2'b01: begin |
SEL_O <= {2'b00, selects[1:0]}; |
DAT_O <= {data[15:0], data[15:0]}; |
end |
2'b10: begin |
SEL_O <= selects; |
DAT_O <= data; |
end |
endcase |
end |
end |
|
always @(posedge CLK_I) |
begin |
if (RST_I) |
WE_O <= 1'b0; |
else if (GO) |
WE_O <= write_flag; |
end |
|
endmodule |
|
|
|
|
|
/trunk/mp3/bench/verilog/or1200_monitor.v
44,6 → 44,9
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.4 2002/01/03 08:40:15 lampret |
// Added second clock as RISC main clock. Updated or120_monitor. |
// |
// Revision 1.3 2001/11/23 08:50:35 lampret |
// Typos. |
// |
81,6 → 84,8
integer fexe; |
reg [23:0] ref; |
integer fspr; |
integer fnop; |
integer r3; |
|
// |
// Initialization |
90,9 → 95,37
fexe = $fopen("executed.log"); |
$timeformat (-9, 2, " ns", 12); |
fspr = $fopen("sprs.log"); |
fnop = $fopen("nop.log"); |
end |
|
// |
// Get GPR |
// |
task get_gpr; |
input [4:0] gpr_no; |
output [31:0] gpr; |
integer j; |
begin |
`ifdef OR1200_XILINX_RAMB4 |
for(j = 0; j < 16; j = j + 1) begin |
gpr[j] = `OR1200_TOP.or1200_cpu.or1200_rf.rf_a.ramb4_s16_0.mem[gpr_no*16+j]; |
end |
for(j = 0; j < 16; j = j + 1) begin |
gpr[j+16] = `OR1200_TOP.or1200_cpu.or1200_rf.rf_a.ramb4_s16_1.mem[gpr_no*16+j]; |
end |
`else |
`ifdef OR1200_XILINX_RAM32X1D |
`else |
`ifdef OR1200_ARTISAN_SDP |
`else |
gpr = `OR1200_TOP.or1200_cpu.or1200_rf.rf_a.mem[gpr_no]); |
`endif |
`endif |
`endif |
end |
endtask |
|
// |
// Write state of the OR1200 registers into a file |
// |
// Limitation: only a small subset of register file RAMs |
109,24 → 142,8
for(i = 0; i < 32; i = i + 1) begin |
if (i % 4 == 0) |
$fdisplay(fexe); |
`ifdef OR1200_XILINX_RAMB4 |
r = 32'h0000_0000; |
for(j = 0; j < 16; j = j + 1) begin |
r[j] = `OR1200_TOP.or1200_cpu.or1200_rf.rf_a.ramb4_s16_0.mem[i*16+j]; |
end |
for(j = 0; j < 16; j = j + 1) begin |
r[j+16] = `OR1200_TOP.or1200_cpu.or1200_rf.rf_a.ramb4_s16_1.mem[i*16+j]; |
end |
get_gpr(i, r); |
$fwrite(fexe, "GPR%d: %h ", i, r); |
`else |
`ifdef OR1200_XILINX_RAM32X1D |
`else |
`ifdef OR1200_ARTISAN_SDP |
`else |
$fwrite(fexe, "GPR%d: %h ", i, `OR1200_TOP.or1200_cpu.or1200_rf.rf_a.mem[i]); |
`endif |
`endif |
`endif |
end |
$fdisplay(fexe); |
r = `OR1200_TOP.or1200_cpu.or1200_sprs.sr; |
153,8 → 170,19
if (((`OR1200_TOP.or1200_cpu.or1200_ctrl.wb_insn[31:26] != `OR1200_OR32_NOP) || !`OR1200_TOP.or1200_cpu.or1200_ctrl.wb_insn[0]) |
&& !(`OR1200_TOP.or1200_cpu.or1200_except.except_flushpipe && `OR1200_TOP.or1200_cpu.or1200_except.ex_dslot)) |
display_arch_state; |
if (`OR1200_TOP.or1200_cpu.or1200_ctrl.wb_insn == 32'h200000cb) // small hack to stop simulation (l.sys 203) |
if (`OR1200_TOP.or1200_cpu.or1200_ctrl.wb_insn == 32'h1500_0001) begin // small hack to stop simulation (l.nop 1) |
get_gpr(3, r3); |
$fdisplay(fnop, "%t: l.nop exit (%h)", $time, r3); |
$finish; |
end |
if (`OR1200_TOP.or1200_cpu.or1200_ctrl.wb_insn == 32'h1500_0002) begin // simulation reports (l.nop 2) |
get_gpr(3, r3); |
$fdisplay(fnop, "%t: l.nop report (%h)", $time, r3); |
end |
if (`OR1200_TOP.or1200_cpu.or1200_ctrl.wb_insn == 32'h1500_0003) begin // simulation printfs (l.nop 3) |
get_gpr(3, r3); |
$fdisplay(fnop, "%t: l.nop printf (%h)", $time, r3); |
end |
if (`OR1200_TOP.or1200_cpu.or1200_sprs.sprs_op == `OR1200_ALUOP_MTSR) // l.mtspr |
$fdisplay(fspr, "%t: Write to SPR : [%h] <- %h", $time, |
`OR1200_TOP.or1200_cpu.or1200_sprs.spr_addr, `OR1200_TOP.or1200_cpu.or1200_sprs.spr_dataout); |
/trunk/mp3/bench/verilog/dbg_if_model.v
0,0 → 1,442
////////////////////////////////////////////////////////////////////// |
//// //// |
//// dbg_if_model.v //// |
//// //// |
//// //// |
//// This file is part of the OpenRISC test bench. //// |
//// http://www.opencores.org/ //// |
//// //// |
//// //// |
//// Author(s): //// |
//// Damjan Lampret //// |
//// lampret@opencores.org //// |
//// //// |
//// //// |
//// All additional information is avaliable in the README.txt //// |
//// file. //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000,2001 Authors //// |
//// //// |
//// 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 //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// |
// |
|
`include "dbg_defines.v" |
|
// Top module |
module dbg_if_model( |
// JTAG pins |
tms_pad_i, tck_pad_i, trst_pad_i, tdi_pad_i, tdo_pad_o, |
|
// Boundary Scan signals |
capture_dr_o, shift_dr_o, update_dr_o, extest_selected_o, bs_chain_i, |
|
// RISC signals |
risc_clk_i, risc_addr_o, risc_data_i, risc_data_o, wp_i, |
bp_i, opselect_o, lsstatus_i, istatus_i, risc_stall_o, reset_o, |
|
// WISHBONE common signals |
wb_rst_i, wb_clk_i, |
|
// WISHBONE master interface |
wb_adr_o, wb_dat_o, wb_dat_i, wb_cyc_o, wb_stb_o, wb_sel_o, |
wb_we_o, wb_ack_i, wb_cab_o, wb_err_i |
|
|
); |
|
parameter Tp = 1; |
|
// JTAG pins |
input tms_pad_i; // JTAG test mode select pad |
input tck_pad_i; // JTAG test clock pad |
input trst_pad_i; // JTAG test reset pad |
input tdi_pad_i; // JTAG test data input pad |
output tdo_pad_o; // JTAG test data output pad |
|
|
// Boundary Scan signals |
output capture_dr_o; |
output shift_dr_o; |
output update_dr_o; |
output extest_selected_o; |
input bs_chain_i; |
|
|
// RISC signals |
input risc_clk_i; // Master clock (RISC clock) |
input [31:0] risc_data_i; // RISC data inputs (data that is written to the RISC registers) |
input [10:0] wp_i; // Watchpoint inputs |
input bp_i; // Breakpoint input |
input [3:0] lsstatus_i; // Load/store status inputs |
input [1:0] istatus_i; // Instruction status inputs |
output [31:0] risc_addr_o; // RISC address output (for adressing registers within RISC) |
output [31:0] risc_data_o; // RISC data output (data read from risc registers) |
output [`OPSELECTWIDTH-1:0] opselect_o; // Operation selection (selecting what kind of data is set to the risc_data_i) |
output risc_stall_o; // Stalls the RISC |
output reset_o; // Resets the RISC |
|
|
// WISHBONE common signals |
input wb_rst_i; // WISHBONE reset |
input wb_clk_i; // WISHBONE clock |
|
// WISHBONE master interface |
output [31:0] wb_adr_o; |
output [31:0] wb_dat_o; |
input [31:0] wb_dat_i; |
output wb_cyc_o; |
output wb_stb_o; |
output [3:0] wb_sel_o; |
output wb_we_o; |
input wb_ack_i; |
output wb_cab_o; |
input wb_err_i; |
|
reg [31:0] risc_addr_o; |
reg [31:0] risc_data_o; |
reg [`OPSELECTWIDTH-1:0] opselect_o; |
reg risc_stall_a; |
reg risc_stall_r; |
integer i, npc, ppc, r1, insn, result; |
|
assign tdo_pad_o = 1'b0; |
assign capture_dr_o = 1'b0; |
assign shift_dr_o = 1'b0; |
assign update_dr_o = 1'b0; |
assign extest_selected_o = 1'b0; |
assign reset_o = 1'b0; |
assign risc_stall_o = risc_stall_r | risc_stall_a; |
assign wb_cab_o = 1'b0; |
|
always @(posedge wb_rst_i or posedge bp_i) |
if (wb_rst_i) |
risc_stall_r <= #1 1'b0; |
else if (bp_i) |
risc_stall_r <= #1 1'b1; |
initial begin |
risc_addr_o = 0; |
risc_data_o = 0; |
opselect_o = 0; |
risc_stall_a = 1'b0; |
#100; |
while (!bp_i) @(posedge risc_clk_i); |
stall; |
wb_master.wr(32'h8000_0004, 32'h9c200000, 4'b1111); /* l.addi r1,r0,0x0 */ |
wb_master.wr(32'h8000_0008, 32'h18408008, 4'b1111); /* l.movhi r2,0x8008 */ |
wb_master.wr(32'h8000_000c, 32'h9c210001, 4'b1111); /* l.addi r1,r1,1 */ |
wb_master.wr(32'h8000_0010, 32'h9c210001, 4'b1111); /* l.addi r1,r1,1 */ |
wb_master.wr(32'h8000_0014, 32'hd4020800, 4'b1111); /* l.sw 0(r2),r1 */ |
wb_master.wr(32'h8000_0018, 32'h9c210001, 4'b1111); /* l.addi r1,r1,1 */ |
wb_master.wr(32'h8000_001c, 32'h84620000, 4'b1111); /* l.lwz r3,0(r2) */ |
wb_master.wr(32'h8000_0020, 32'h03fffffb, 4'b1111); /* l.j loop2 */ |
wb_master.wr(32'h8000_0024, 32'he0211800, 4'b1111); /* l.add r1,r1,r3 */ |
wb_master.wr(32'h8000_0028, 32'he0211800, 4'b1111); /* l.add r1,r1,r3 */ |
|
// Enable exceptions in SR |
wr_reg(17, 3); |
|
// Set trap bit in DSR |
wr_reg((6 << 11) + 20, 32'h2000); |
|
// Set NPC |
wr_npc(32'h8000_0004); |
|
// Set DMR1[ST] |
wr_reg((6 << 11) + 16, 1 << 22); |
|
// Single-step |
for (i = 1; i < 10; i = i + 1) |
unstall; |
|
// Read NPC |
rd_reg((0 << 11) + 16, npc); |
|
// Read PPC |
rd_reg((0 << 11) + 18, ppc); |
|
// Read R1 |
rd_reg(32'h401, r1); |
|
$display("Read npc = %h ppc = %h r1 = %h", npc, ppc, r1); |
$display("Expected npc = %h ppc = %h r1 = %h\n", 32'h8000000c, 32'h80000024, 5); |
result = npc + ppc + r1; |
|
|
/* Reset step bit */ |
wr_reg ((6 << 11) + 16, 0); |
|
/* Set trap insn in delay slot */ |
wb_master.rd (32'h8000_0024, insn); |
wb_master.wr (32'h8000_0024, 32'h21000001, 4'b1111); |
|
/* Unstall */ |
unstall; |
|
/* Read NPC */ |
rd_reg((0 << 11) + 16, npc); |
|
/* Read PPC */ |
rd_reg((0 << 11) + 18, ppc); |
|
/* Read R1 */ |
rd_reg(32'h401, r1); |
|
/* Set back original insn */ |
wb_master.wr (32'h8000_0024, insn, 4'b1111); |
|
$display("Read npc = %h ppc = %h r1 = %h", npc, ppc, r1); |
$display("Expected npc = %h ppc = %h r1 = %h\n", 32'h8000000c, 32'h80000024, 8); |
result = npc + ppc + r1 + result; |
|
|
/* Set trap insn in place of branch insn */ |
wb_master.rd (32'h8000_0020, insn); |
wb_master.wr (32'h8000_0020, 32'h21000001, 4'b1111); |
|
/* Set PC */ |
wr_npc(32'h8000_000c); |
|
/* Unstall */ |
unstall; |
|
/* Read NPC */ |
rd_reg((0 << 11) + 16, npc); |
|
/* Read PPC */ |
rd_reg((0 << 11) + 18, ppc); |
|
/* Read R1 */ |
rd_reg(32'h401, r1); |
|
/* Set back original insn */ |
wb_master.wr (32'h8000_0020, insn, 4'b1111); |
|
$display("Read npc = %h ppc = %h r1 = %h", npc, ppc, r1); |
$display("Expected npc = %h ppc = %h r1 = %h\n", 32'h80000024, 32'h80000020, 11); |
result = npc + ppc + r1 + result; |
|
/* Set trap insn before branch insn */ |
wb_master.rd (32'h8000_001c, insn); |
wb_master.wr (32'h8000_001c, 32'h21000001, 4'b1111); |
|
/* Set PC */ |
wr_npc(32'h8000_0020); |
|
/* Unstall */ |
unstall; |
|
/* Read NPC */ |
rd_reg((0 << 11) + 16, npc); |
|
/* Read PPC */ |
rd_reg((0 << 11) + 18, ppc); |
|
/* Read R1 */ |
rd_reg(32'h401, r1); |
|
/* Set back original insn */ |
wb_master.wr (32'h8000_001c, insn, 4'b1111); |
|
$display("Read npc = %h ppc = %h r1 = %h", npc, ppc, r1); |
$display("Expected npc = %h ppc = %h r1 = %h\n", 32'h80000020, 32'h8000001c, 24); |
result = npc + ppc + r1 + result; |
|
|
/* Set trap insn behind lsu insn */ |
wb_master.rd (32'h8000_0018, insn); |
wb_master.wr (32'h8000_0018, 32'h21000001, 4'b1111); |
|
/* Set PC */ |
wr_npc(32'h8000_001c); |
|
/* Unstall */ |
unstall; |
|
/* Read NPC */ |
rd_reg((0 << 11) + 16, npc); |
|
/* Read PPC */ |
rd_reg((0 << 11) + 18, ppc); |
|
/* Read R1 */ |
rd_reg(32'h401, r1); |
|
/* Set back original insn */ |
wb_master.wr (32'h8000_0018, insn, 4'b1111); |
|
$display("Read npc = %h ppc = %h r1 = %h", npc, ppc, r1); |
$display("Expected npc = %h ppc = %h r1 = %h\n", 32'h8000001c, 32'h80000018, 49); |
result = npc + ppc + r1 + result; |
|
/* Set trap insn very near previous one */ |
wb_master.rd (32'h8000_001c, insn); |
wb_master.wr (32'h8000_001c, 32'h21000001, 4'b1111); |
|
/* Set PC */ |
wr_npc(32'h8000_0018); |
|
/* Unstall */ |
unstall; |
|
/* Read NPC */ |
rd_reg((0 << 11) + 16, npc); |
|
/* Read PPC */ |
rd_reg((0 << 11) + 18, ppc); |
|
/* Read R1 */ |
rd_reg(32'h401, r1); |
|
/* Set back original insn */ |
wb_master.wr (32'h8000_001c, insn, 4'b1111); |
|
$display("Read npc = %h ppc = %h r1 = %h", npc, ppc, r1); |
$display("Expected npc = %h ppc = %h r1 = %h\n", 32'h80000020, 32'h8000001c, 50); |
result = npc + ppc + r1 + result; |
|
/* Set trap insn to the start */ |
wb_master.rd (32'h8000_000c, insn); |
wb_master.wr (32'h8000_000c, 32'h21000001, 4'b1111); |
|
/* Set PC */ |
wr_npc(32'h8000_001c); |
|
/* Unstall */ |
unstall; |
|
/* Read NPC */ |
rd_reg((0 << 11) + 16, npc); |
|
/* Read PPC */ |
rd_reg((0 << 11) + 18, ppc); |
|
/* Read R1 */ |
rd_reg(32'h401, r1); |
|
/* Set back original insn */ |
wb_master.wr (32'h8000_000c, insn, 4'b1111); |
|
$display("Read npc = %h ppc = %h r1 = %h", npc, ppc, r1); |
$display("Expected npc = %h ppc = %h r1 = %h\n", 32'h80000010, 32'h8000000c, 99); |
result = npc + ppc + r1 + result; |
|
$display("result = %h\n", result + 32'h5eaddc4b); |
|
#100 $finish; |
end |
|
task stall; |
begin |
risc_stall_r = 1'b1; |
@(posedge risc_clk_i); |
@(posedge risc_clk_i); |
end |
endtask |
|
task unstall; |
begin |
risc_stall_r = 1'b0; |
@(posedge risc_clk_i); |
while (!bp_i) @(posedge risc_clk_i); |
end |
endtask |
|
task wr_npc; |
input [31:0] npc; |
begin |
npc = npc - 0; |
wr_reg((0 << 11) + 16, npc); |
end |
endtask |
|
task wr_reg; |
input [31:0] addr; |
input [31:0] data; |
begin |
risc_stall_a = 1'b1; |
@(posedge risc_clk_i); |
risc_addr_o = addr; |
risc_data_o = data; |
opselect_o = 5; |
@(posedge risc_clk_i); |
risc_addr_o = 0; |
risc_data_o = 0; |
opselect_o = 0; |
@(posedge risc_clk_i); |
@(posedge risc_clk_i); |
@(posedge risc_clk_i); |
risc_stall_a = 1'b0; |
end |
endtask |
|
task rd_reg; |
input [31:0] addr; |
output [31:0] data; |
begin |
risc_stall_a = 1'b1; |
@(posedge risc_clk_i); |
risc_addr_o = addr; |
opselect_o = 4; |
@(posedge risc_clk_i); |
@(posedge risc_clk_i); |
data = risc_data_i; |
@(posedge risc_clk_i); |
risc_addr_o = 0; |
risc_data_o = 0; |
opselect_o = 0; |
@(posedge risc_clk_i); |
@(posedge risc_clk_i); |
@(posedge risc_clk_i); |
risc_stall_a = 1'b0; |
end |
endtask |
|
// |
// Instantiation of Master WISHBONE BFM |
// |
wb_master wb_master( |
// WISHBONE Interface |
.CLK_I(wb_clk_i), |
.RST_I(wb_rst_i), |
.CYC_O(wb_cyc_o), |
.ADR_O(wb_adr_o), |
.DAT_O(wb_dat_o), |
.SEL_O(wb_sel_o), |
.WE_O(wb_we_o), |
.STB_O(wb_stb_o), |
.DAT_I(wb_dat_i), |
.ACK_I(wb_ack_i), |
.ERR_I(wb_err_i), |
.RTY_I(0), |
.TAG_I(4'b0) |
); |
|
endmodule |