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

Subversion Repositories or1k

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /or1k/tags/first/mp3/rtl
    from Rev 769 to Rev 1765
    Reverse comparison

Rev 769 → Rev 1765

/verilog/audio/audio_codec_if.v
0,0 → 1,144
//////////////////////////////////////////////////////////////////////
//// ////
//// MP3 demo Audio CODEC interface ////
//// ////
//// This file is part of the MP3 demo application ////
//// http://www.opencores.org/cores/or1k/mp3/ ////
//// ////
//// Description ////
//// Connects Audio block to XSV board AK4520 codec chip. ////
//// ////
//// To Do: ////
//// - nothing really ////
//// ////
//// Author(s): ////
//// - Lior Shtram, lior.shtram@flextronicssemi.com ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 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 $
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
module audio_codec_if (
rstn,
clk,
fifo_clk,
fifo_data,
fifo_rd_en,
 
sclk,
mclk,
lrclk,
sdout,
sdin
);
 
parameter fifo_width = 16;
parameter count_bits = 11;
 
input rstn;
input clk;
output fifo_clk;
input [fifo_width-1:0] fifo_data;
output fifo_rd_en;
 
output sclk;
output mclk;
output lrclk;
input sdout;
output sdin;
 
 
reg [count_bits-1:0] counter;
reg [16:0] shift_reg;
reg f_rd_en;
reg sd_sig;
 
always @(posedge clk or negedge rstn)
begin
if(!rstn)
counter <= 0;
else
counter <= #1 counter + 1;
end
 
assign fifo_clk = clk ;
assign fifo_rd_en = f_rd_en ;
assign mclk = counter[0]; // mclk = clk/2 = 256fs
assign sclk = counter[2]; // sclk = mclk/4 = 64fs
assign lrclk = counter[8]; //lrclk = sclk/64
 
always @(posedge clk or negedge rstn)
begin
if(!rstn)
begin
sd_sig <= 1'b0;
shift_reg <= 0;
end
else
begin
if(counter[7:3] < 5'd16)
begin
if( counter[2:0] == 3'b101)
shift_reg[fifo_width:1] <= #1 shift_reg[fifo_width-1:0];
else
shift_reg <= #1 shift_reg;
sd_sig <= #1 shift_reg[16];
end
else
begin
sd_sig <= #1 1'b0;
if(counter[7:0] == 8'h80)
shift_reg[16:0] <= { fifo_data[fifo_width-1:0], 1'b0 };
end
end
end
 
// To je nase. Sve ostalo je garbidz.
always @(posedge clk or negedge rstn)
begin
if(!rstn)
f_rd_en <= 1'b0;
else
if(counter[9:0] == 10'h200)
f_rd_en <= #1 1'b1;
else
f_rd_en <= #1 1'b0;
end
 
 
assign sdin = sd_sig;
 
 
endmodule
/verilog/audio/audio_top.v
0,0 → 1,230
//////////////////////////////////////////////////////////////////////
//// ////
//// MP3 demo Audio Interface Top Level ////
//// ////
//// This file is part of the MP3 demo application ////
//// http://www.opencores.org/cores/or1k/mp3/ ////
//// ////
//// Description ////
//// Audio interface top level for XSV board instantiating ////
//// FIFOs, WISHBONE interface and XSV CODEC interface. ////
//// ////
//// To Do: ////
//// - nothing really ////
//// ////
//// Author(s): ////
//// - Lior Shtram, lior.shtram@flextronicssemi.com ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 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 $
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
module audio_top (
clk, rstn,
 
wb_dat_i, wb_dat_o, wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i,
wb_stb_i, wb_ack_o, wb_err_o,
 
mclk, lrclk, sclk, sdin, sdout,
 
audio_dreq,
igor, simon, USB_VPO, USB_VMO
 
);
 
input clk;
input rstn;
 
input [31:0] wb_dat_i;
output [31:0] wb_dat_o;
input [31:0] wb_adr_i;
input [3:0] wb_sel_i;
input wb_we_i;
input wb_cyc_i;
input wb_stb_i;
output wb_ack_o;
output wb_err_o;
 
output mclk;
output lrclk;
output sclk;
output sdin;
input sdout;
 
output audio_dreq;
 
input igor;
input simon;
output USB_VPO;
output USB_VMO;
 
parameter fifo_width = 16;
 
wire [fifo_width-1:0] fifo_data_i;
wire [fifo_width-1:0] fifo_data_o;
wire fifo_clk_wr;
wire fifo_clk_rd;
wire fifo_full;
wire fifo_empty;
wire fifo_almost_full;
wire fifo_almost_empty;
wire fifo_rd_en;
wire fifo_wr_en;
 
assign audio_dreq = fifo_almost_empty;
assign USB_VPO = fifo_almost_full;
assign USB_VMO = fifo_almost_empty;
 
 
 
audio_wb_if i_audio_wb_if(
.rstn( rstn ),
.clk( clk ),
.wb_dat_i( wb_dat_i ),
.wb_dat_o( wb_dat_o ),
.wb_adr_i( wb_adr_i ),
.wb_sel_i( wb_sel_i ),
.wb_we_i( wb_we_i ),
.wb_cyc_i( wb_cyc_i ),
.wb_stb_i( wb_stb_i ),
.wb_ack_o( wb_ack_o ),
.wb_err_o( wb_err_o ),
.fifo_dat_o( fifo_data_i ),
.fifo_clk_o( fifo_clk_wr ),
.fifo_wr_en( fifo_wr_en ),
.fifo_full( fifo_full ),
.fifo_empty( fifo_empty ),
.fifo_almost_full( fifo_almost_full ),
.fifo_almost_empty( fifo_almost_empty ),
.simon(igor),
.igor(simon)
 
);
 
`ifdef AUDIO_NO_FIFO
fifo_empty_16 i_audio_fifo (
.AINIT( !rstn ),
.DIN( fifo_data_i ),
.DOUT( fifo_data_o ),
// .WR_CLK( fifo_clk_rd ),
// .RD_CLK( fifo_clk_wr ),
.WR_CLK( fifo_clk_wr ),
.RD_CLK( fifo_clk_rd ),
.RD_EN( fifo_rd_en ),
.WR_EN( fifo_wr_en ),
.EMPTY( fifo_empty ),
.FULL( fifo_full ),
.ALMOST_EMPTY( fifo_almost_empty ),
.ALMOST_FULL( fifo_almost_full )
);
`else
/*
fifo8kx16 i_audio_fifo (
.AINIT( !rstn ),
.DIN( fifo_data_i ),
.DOUT( fifo_data_o ),
// .WR_CLK( fifo_clk_rd ),
// .RD_CLK( fifo_clk_wr ),
.WR_CLK( fifo_clk_wr ),
.RD_CLK( fifo_clk_rd ),
.RD_EN( fifo_rd_en ),
.WR_EN( fifo_wr_en ),
.EMPTY( fifo_empty ),
.FULL( fifo_full ),
.ALMOST_EMPTY( fifo_almost_empty ),
.ALMOST_FULL( fifo_almost_full )
);
*/
 
fifo_4095_16 i_audio_fifo (
.AINIT( !rstn ),
.DIN( fifo_data_i ),
.DOUT( fifo_data_o ),
// .WR_CLK( fifo_clk_rd ),
// .RD_CLK( fifo_clk_wr ),
.WR_CLK( fifo_clk_wr ),
.RD_CLK( fifo_clk_rd ),
.RD_EN( fifo_rd_en ),
.WR_EN( fifo_wr_en ),
.EMPTY( fifo_empty ),
.FULL( fifo_full ),
.ALMOST_EMPTY( fifo_almost_empty ),
.ALMOST_FULL( fifo_almost_full )
);
 
 
`endif
/*
fifo_1023_16 i_audio_fifo (
.AINIT( !rstn ),
.DIN( fifo_data_i ),
.DOUT( fifo_data_o ),
.WR_CLK( clk ),
.RD_CLK( clk ),
.RD_EN( fifo_rd_en ),
.WR_EN( fifo_wr_en ),
.EMPTY( fifo_empty ),
.FULL( fifo_full ),
.ALMOST_EMPTY( fifo_almost_empty ),
.ALMOST_FULL( fifo_almost_full )
); // synthesis black_box
*/
 
 
 
 
`ifdef UNUSED
assign fifo_data_o = fifo_data_i;
assign fifo_full = 1'b0;
assign fifo_empty = 1'b0;
assign fifo_almost_full = 1'b0;
assign fifo_almost_empty = 1'b0;
`endif
 
audio_codec_if i_audio_codec_if (
.rstn( rstn ),
.clk( clk ),
.fifo_clk( fifo_clk_rd ),
.fifo_data( fifo_data_o ),
.fifo_rd_en( fifo_rd_en ),
.sclk( sclk ),
.mclk( mclk ),
.lrclk( lrclk ),
.sdout( sdout ),
.sdin( sdin )
);
endmodule
/verilog/audio/audio_wb_if.v
0,0 → 1,132
//////////////////////////////////////////////////////////////////////
//// ////
//// MP3 demo WISHBONE i/f of Audio block ////
//// ////
//// This file is part of the MP3 demo application ////
//// http://www.opencores.org/cores/or1k/mp3/ ////
//// ////
//// Description ////
//// Connect the audio block to the WISHBONE bus. ////
//// ////
//// To Do: ////
//// - nothing really ////
//// ////
//// Author(s): ////
//// - Lior Shtram, lior.shtram@flextronicssemi.com ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 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 $
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
module audio_wb_if (
rstn,
clk,
wb_dat_i,
wb_dat_o,
wb_adr_i,
wb_sel_i,
wb_we_i,
wb_cyc_i,
wb_stb_i,
wb_ack_o,
wb_err_o,
 
fifo_dat_o,
fifo_clk_o,
fifo_wr_en,
fifo_full,
fifo_empty,
fifo_almost_full,
fifo_almost_empty,
simon,
igor
);
 
parameter fifo_width = 16;
 
input rstn;
input clk;
input [31:0] wb_dat_i;
output [31:0] wb_dat_o;
input [31:0] wb_adr_i;
input [3:0] wb_sel_i;
input wb_we_i;
input wb_cyc_i;
input wb_stb_i;
output wb_ack_o;
output wb_err_o;
 
output [fifo_width-1:0] fifo_dat_o;
output fifo_clk_o;
output fifo_wr_en;
input fifo_full;
input fifo_empty;
input fifo_almost_full;
input fifo_almost_empty;
 
input simon;
input igor;
 
reg [3:0] fifo_status;
reg f_wr_en;
 
always @(posedge clk or negedge rstn)
if (!rstn) fifo_status <= 4'b0;
else
fifo_status <= #1 { fifo_full, fifo_empty,
fifo_almost_full, fifo_almost_empty };
 
assign fifo_dat_o = wb_dat_i[fifo_width-1:0];
assign wb_dat_o = { simon, igor, 26'b0, fifo_status };
//assign wb_ack_o = wb_cyc_i & !fifo_almost_full;
assign wb_err_o = 1'b0;
assign fifo_clk_o = clk;
 
always @(posedge clk or negedge rstn)
begin
if(!rstn)
f_wr_en <= 1'b0;
else
if(wb_cyc_i & wb_we_i & !fifo_almost_full & ~f_wr_en)
f_wr_en <= #1 1'b1;
else
f_wr_en <= #1 1'b0;
end
 
assign fifo_wr_en = f_wr_en;
//assign wb_ack_o = f_wr_en;
assign wb_ack_o = f_wr_en | (wb_cyc_i & wb_stb_i & ~wb_we_i);
 
endmodule
/verilog/audio/fifo_empty_16.v
0,0 → 1,35
`include "timescale.v"
 
module fifo_empty_16 (
DIN,
WR_EN,
WR_CLK,
RD_EN,
RD_CLK,
AINIT,
DOUT,
FULL,
EMPTY,
ALMOST_FULL,
ALMOST_EMPTY);
 
input [15 : 0] DIN;
input WR_EN;
input WR_CLK;
input RD_EN;
input RD_CLK;
input AINIT;
output [15 : 0] DOUT;
output FULL;
output EMPTY;
output ALMOST_FULL;
output ALMOST_EMPTY;
 
 
assign DOUT = DIN;
assign FULL = 1'b0;
assign EMPTY = 1'b0;
assign ALMOST_FULL = 1'b0;
assign ALMOST_EMPTY = 1'b0;
 
endmodule
/verilog/audio/fifo_4095_16.v
0,0 → 1,101
/*******************************************************************
* This file was created by the Xilinx CORE Generator tool, and *
* is (c) Xilinx, Inc. 1998, 1999. No part of this file may be *
* transmitted to any third party (other than intended by Xilinx) *
* or used without a Xilinx programmable or hardwire device without *
* Xilinx's prior written permission. *
*******************************************************************/
 
// The following line must appear at the top of the file in which
// the core instantiation will be made. Ensure that the translate_off/_on
// compiler directives are correct for your synthesis tool(s)
 
// Your Verilog compiler/interpreter might require the following
// option or it's equivalent to help locate the Xilinx Core Library
// +incdir+${XILINX}/verilog/src
// Here ${XILINX} refers to the XILINX software installation directory.
 
//----------- Begin Cut here for LIBRARY inclusion --------// LIB_TAG
 
// synopsys translate_off
 
//`include "XilinxCoreLib/async_fifo_v3_0.v"
 
// synopsys translate_on
 
// LIB_TAG_END ------- End LIBRARY inclusion --------------
 
// The following code must appear after the module in which it
// is to be instantiated. Ensure that the translate_off/_on compiler
// directives are correct for your synthesis tool(s).
 
//----------- Begin Cut here for MODULE Declaration -------// MOD_TAG
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
module fifo_4095_16 (
DIN,
WR_EN,
WR_CLK,
RD_EN,
RD_CLK,
AINIT,
DOUT,
FULL,
EMPTY,
ALMOST_FULL,
ALMOST_EMPTY);
 
input [15 : 0] DIN;
input WR_EN;
input WR_CLK;
input RD_EN;
input RD_CLK;
input AINIT;
output [15 : 0] DOUT;
output FULL;
output EMPTY;
output ALMOST_FULL;
output ALMOST_EMPTY;
 
// synopsys translate_off
 
ASYNC_FIFO_V3_0 #(
16,
0,
100,
1,
1,
0,
0,
0,
0,
0,
0,
0,
2,
0,
1,
0,
2,
0)
inst (
.DIN(DIN),
.WR_EN(WR_EN),
.WR_CLK(WR_CLK),
.RD_EN(RD_EN),
.RD_CLK(RD_CLK),
.AINIT(AINIT),
.DOUT(DOUT),
.FULL(FULL),
.EMPTY(EMPTY),
.ALMOST_FULL(ALMOST_FULL),
.ALMOST_EMPTY(ALMOST_EMPTY));
 
// synopsys translate_on
 
endmodule
 
// MOD_TAG_END ------- End MODULE Declaration -------------
/verilog/or1200.xcv/pic.v
0,0 → 1,250
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Programmable Interrupt Controller ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// PIC according to OR1K architectural specification. ////
//// ////
//// To Do: ////
//// None ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:21 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module pic(
// RISC Internal Interface
clk, rst, spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o,
pic_wakeup, int_low, int_high,
// PIC Interface
pic_int
);
 
//
// RISC Internal Interface
//
input clk; // Clock
input rst; // Reset
input spr_cs; // SPR CS
input spr_write; // SPR Write
input [31:0] spr_addr; // SPR Address
input [31:0] spr_dat_i; // SPR Write Data
output [31:0] spr_dat_o; // SPR Read Data
output pic_wakeup; // Wakeup to the PM
output int_low; // Low priority interrupt
// exception request
output int_high; // High priority interrupt
// exception request
 
//
// PIC Interface
//
input [`PIC_INTS-1:0] pic_int;// Interrupt inputs
 
`ifdef PIC_IMPLEMENTED
 
//
// PIC Mask Register bits (or no register)
//
`ifdef PIC_PICMR
reg [`PIC_INTS-1:2] picmr; // PICMR bits
`else
wire [`PIC_INTS-1:2] picmr; // No PICMR register
`endif
 
//
// PIC Priority Register bits (or no register)
//
`ifdef PIC_PICPR
reg [`PIC_INTS-1:2] picpr; // PICPR bits
`else
wire [`PIC_INTS-1:2] picpr; // No PICPR register
`endif
 
//
// PIC Status Register bits (or no register)
//
`ifdef PIC_PICSR
reg [`PIC_INTS-1:0] picsr; // PICSR bits
`else
wire [`PIC_INTS-1:0] picsr; // No PICSR register
`endif
 
//
// Internal wires & regs
//
wire picmr_sel; // PICMR select
wire picpr_sel; // PICPR select
wire picsr_sel; // PICSR select
wire [`PIC_INTS-1:0] um_ints;// Unmasked interrupts
reg [31:0] spr_dat_o; // SPR data out
 
//
// PIC registers address decoder
//
assign picmr_sel = (spr_cs && (spr_addr[`PICOFS_BITS] == `PIC_OFS_PICMR)) ? 1'b1 : 1'b0;
assign picpr_sel = (spr_cs && (spr_addr[`PICOFS_BITS] == `PIC_OFS_PICPR)) ? 1'b1 : 1'b0;
assign picsr_sel = (spr_cs && (spr_addr[`PICOFS_BITS] == `PIC_OFS_PICSR)) ? 1'b1 : 1'b0;
 
//
// Write to PICMR
//
`ifdef PIC_PICMR
always @(posedge clk or posedge rst)
if (rst)
// picmr <= {`PIC_INTS-2{1'b0}};
picmr <= {1'b1, {`PIC_INTS-3{1'b0}}};
else if (picmr_sel && spr_write) begin
picmr <= #1 spr_dat_i[`PIC_INTS-1:2];
end
`else
assign picpr = (`PIC_INTS)'b1;
`endif
 
//
// Write to PICPR
//
`ifdef PIC_PICPR
always @(posedge clk or posedge rst)
if (rst)
picpr <= {`PIC_INTS-2{1'b0}};
else if (picpr_sel && spr_write) begin
picpr <= #1 spr_dat_i[`PIC_INTS-1:2];
end
`else
assign picpr = 0;
`endif
 
//
// Write to PICSR, both CPU and external ints
//
`ifdef PIC_PICSR
always @(posedge clk or posedge rst)
if (rst)
picsr <= {`PIC_INTS-2{1'b0}};
else if (picsr_sel && spr_write) begin
picsr <= #1 spr_dat_i[`PIC_INTS-1:0] | um_ints;
end else
picsr <= #1 picsr | um_ints;
`else
assign picsr = pic_int;
`endif
 
//
// Read PIC registers
//
always @(spr_addr or picmr or picpr or picsr)
case (spr_addr[`PICOFS_BITS]) // synopsys full_case parallel_case
`ifdef PIC_READREGS
`PIC_OFS_PICMR: begin
spr_dat_o[`PIC_INTS-1:0] = {picmr, 2'b0};
`ifdef PIC_UNUSED_ZERO
spr_dat_o[31:`PIC_INTS] = {32-`PIC_INTS{1'b0}};
`endif
end
`PIC_OFS_PICPR: begin
spr_dat_o[`PIC_INTS-1:0] = {picpr, 2'b0};
`ifdef PIC_UNUSED_ZERO
spr_dat_o[31:`PIC_INTS] = {32-`PIC_INTS{1'b0}};
`endif
end
`endif
default: begin
spr_dat_o[`PIC_INTS-1:0] = picsr;
`ifdef PIC_UNUSED_ZERO
spr_dat_o[31:`PIC_INTS] = {32-`PIC_INTS{1'b0}};
`endif
end
endcase
 
//
// Unmasked interrupts
//
assign um_ints = pic_int & {picmr, 2'b11};
 
//
// Generate int_low
//
assign int_low = (um_ints & {~picpr, 2'b10}) ? 1'b1 : 1'b0;
 
//
// Generate int_high
//
assign int_high = (um_ints & {picpr, 2'b01}) ? 1'b1 : 1'b0;
 
//
// Assert pic_wakeup when either intlow or int_high is asserted
//
assign pic_wakeup = int_low | int_high;
 
`else
 
//
// When PIC is not implemented, drive all outputs as would when PIC is disabled
//
assign int_low = pic_int[1];
assign int_high = pic_int[0];
assign pic_wakeup= int_low | int_high;
 
//
// Read PIC registers
//
`ifdef PIC_READREGS
assign spr_dat_o[`PIC_INTS-1:0] = `PIC_INTS'b0;
`ifdef PIC_UNUSED_ZERO
assign spr_dat_o[31:`PIC_INTS] = 32-`PIC_INTS'b0;
`endif
`endif
 
`endif
 
endmodule
/verilog/or1200.xcv/pm.v
0,0 → 1,209
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Power Management ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// PM according to OR1K architectural specification. ////
//// ////
//// To Do: ////
//// - add support for dynamic clock gating ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:35 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:21 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module pm(
// RISC Internal Interface
clk, rst, pic_wakeup, spr_write, spr_addr, spr_dat_i, spr_dat_o,
// Power Management Interface
pm_clksd, pm_cpustall, pm_dc_gate, pm_ic_gate, pm_dmmu_gate,
pm_immu_gate, pm_tt_gate, pm_cpu_gate, pm_wakeup, pm_lvolt
);
 
//
// RISC Internal Interface
//
input clk; // Clock
input rst; // Reset
input pic_wakeup; // Wakeup from the PIC
input spr_write; // SPR Read/Write
input [31:0] spr_addr; // SPR Address
input [31:0] spr_dat_i; // SPR Write Data
output [31:0] spr_dat_o; // SPR Read Data
 
//
// Power Management Interface
//
input pm_cpustall; // Stall the CPU
output [3:0] pm_clksd; // Clock Slowdown factor
output pm_dc_gate; // Gate DCache clock
output pm_ic_gate; // Gate ICache clock
output pm_dmmu_gate; // Gate DMMU clock
output pm_immu_gate; // Gate IMMU clock
output pm_tt_gate; // Gate Tick Timer clock
output pm_cpu_gate; // Gate main RISC/CPU clock
output pm_wakeup; // Activate (de-gate) all clocks
output pm_lvolt; // Lower operating voltage
 
`ifdef PM_IMPLEMENTED
 
//
// Power Management Register bits
//
reg [3:0] sdf; // Slow-down factor
reg dme; // Doze Mode Enable
reg sme; // Sleep Mode Enable
reg dcge; // Dynamic Clock Gating Enable
 
//
// Internal wires
//
wire pmr_sel; // PMR select
 
//
// PMR address decoder (partial decoder)
//
`ifdef PM_PARTIAL_DECODING
assign pmr_sel = (spr_addr[`SPRGRP_BITS] == `SPRGRP_PM) ? 1'b1 : 1'b0;
`else
assign pmr_sel = ((spr_addr[`SPRGRP_BITS] == `SPRGRP_PM) &&
(spr_addr[`SPROFS_BITS] == `PM_OFS_PMR)) ? 1'b1 : 1'b0;
`endif
 
//
// Write to PMR and also PMR[DME]/PMR[SME] reset when
// pic_wakeup is asserted
//
always @(posedge clk or posedge rst)
if (rst)
{dcge, sme, dme, sdf} <= 7'b0;
else if (pmr_sel && spr_write) begin
sdf <= #1 spr_dat_i[`PM_PMR_SDF];
dme <= #1 spr_dat_i[`PM_PMR_DME];
sme <= #1 spr_dat_i[`PM_PMR_SME];
dcge <= #1 spr_dat_i[`PM_PMR_DCGE];
end
else if (pic_wakeup) begin
dme <= #1 1'b0;
sme <= #1 1'b0;
end
 
//
// Read PMR
//
`ifdef PM_READREGS
assign spr_dat_o[`PM_PMR_SDF] = sdf;
assign spr_dat_o[`PM_PMR_DME] = dme;
assign spr_dat_o[`PM_PMR_SME] = sme;
assign spr_dat_o[`PM_PMR_DCGE] = dcge;
`ifdef PM_UNUSED_ZERO
assign spr_dat_o[`PM_PMR_UNUSED] = 25'b0;
`endif
`endif
 
//
// Generate pm_clksd
//
assign pm_clksd = sdf;
 
//
// Statically generate all clock gate outputs
// TODO: add dynamic clock gating feature
//
assign pm_cpu_gate = (dme | sme) & ~pic_wakeup;
assign pm_dc_gate = pm_cpu_gate;
assign pm_ic_gate = pm_cpu_gate;
assign pm_dmmu_gate = pm_cpu_gate;
assign pm_immu_gate = pm_cpu_gate;
assign pm_tt_gate = sme & ~pic_wakeup;
 
//
// Assert pm_wakeup when pic_wakeup is asserted
//
assign pm_wakeup = pic_wakeup;
 
//
// Assert pm_lvolt when pm_cpu_gate or pm_cpustall are asserted
//
assign pm_lvolt = pm_cpu_gate | pm_cpustall;
 
`else
 
//
// When PM is not implemented, drive all outputs as would when PM is disabled
//
assign pm_clksd = 4'b0;
assign pm_cpu_gate = 1'b0;
assign pm_dc_gate = 1'b0;
assign pm_ic_gate = 1'b0;
assign pm_dmmu_gate = 1'b0;
assign pm_immu_gate = 1'b0;
assign pm_tt_gate = 1'b0;
assign pm_wakeup = 1'b1;
assign pm_lvolt = 1'b0;
 
//
// Read PMR
//
`ifdef PM_READREGS
assign spr_dat_o[`PM_PMR_SDF] = 4'b0;
assign spr_dat_o[`PM_PMR_DME] = 1'b0;
assign spr_dat_o[`PM_PMR_SME] = 1'b0;
assign spr_dat_o[`PM_PMR_DCGE] = 1'b0;
`ifdef PM_UNUSED_ZERO
assign spr_dat_o[`PM_PMR_UNUSED] = 25'b0;
`endif
`endif
 
`endif
 
endmodule
/verilog/or1200.xcv/frz_logic.v
0,0 → 1,181
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Freeze logic ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Generates all freezes and stalls inside RISC ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
`define NO_FREEZE 3'd0
`define FREEZE_BYDC 3'd1
`define FREEZE_BYMULTICYCLE 3'd2
`define WAIT_LSU_TO_FINISH 3'd3
`define WAIT_IC 3'd4
 
//
// Freeze logic (stalls CPU pipeline, ifetcher etc.)
//
module frz_logic(
// Clock and reset
clk, rst,
 
// Internal i/f
multicycle, except_flushpipe, lsu_stall, if_stall,
dclsu_unstall, branch_stall, du_stall, mac_stall,
force_dslot_fetch,
if_freeze, id_freeze, ex_freeze, wb_freeze
);
 
//
// I/O
//
input clk;
input rst;
input [`MULTICYCLE_WIDTH-1:0] multicycle;
input except_flushpipe;
input lsu_stall;
input if_stall;
input dclsu_unstall;
input branch_stall;
input force_dslot_fetch;
input du_stall;
input mac_stall;
output if_freeze;
output id_freeze;
output ex_freeze;
output wb_freeze;
 
//
// Internal wires and regs
//
reg multicycle_freeze;
reg [2:0] state2;
reg [2:0] multicycle_cnt;
reg done_once;
 
//
// Pipeline freeze
//
// Rules how to create freeze signals:
// 1. Not overwriting pipeline stages:
// Frreze signals at the beginning of pipeline (such as if_freeze) can be asserted more
// often than freeze signals at the of pipeline (such as wb_freeze). In other words, wb_freeze must never
// be asserted when ex_freeze is not. ex_freeze must never be asserted when id_freeze is not etc.
//
// 2. Inserting NOPs in the middle of pipeline only if supported:
// At this time, only ex_freeze (and wb_freeze) can be deassrted when id_freeze (and if_freeze) are asserted.
// This way NOP is asserted from stage ID into EX stage.
//
assign if_freeze = id_freeze;
assign id_freeze = (lsu_stall | (~dclsu_unstall & if_stall) | multicycle_freeze | force_dslot_fetch) & ~except_flushpipe | du_stall;
assign ex_freeze = wb_freeze;
assign wb_freeze = (lsu_stall | (~dclsu_unstall & if_stall) | multicycle_freeze) & ~except_flushpipe | du_stall | mac_stall;
 
//
// Freeze FSM2
//
always @(posedge clk or posedge rst) begin
if (rst) begin
state2 <= #1 `NO_FREEZE;
multicycle_freeze <= #1 1'b1;
multicycle_cnt <= #1 3'b0;
done_once <= #1 1'b0;
end
else
case (state2) // synopsys full_case parallel_case
`NO_FREEZE :
if (done_once && ex_freeze)
done_once <= #1 1'b1;
else if (multicycle) begin
state2 <= #1 `FREEZE_BYMULTICYCLE;
multicycle_freeze <= #1 1'b1;
multicycle_cnt <= #1 multicycle - 'd1;
done_once <= #1 1'b0;
end
else
multicycle_freeze <= #1 1'b0;
`FREEZE_BYMULTICYCLE :
if (multicycle_cnt) begin
multicycle_cnt <= #1 multicycle_cnt - 'd1;
state2 <= #1 `FREEZE_BYMULTICYCLE;
end
else if (lsu_stall) begin
state2 <= #1 `WAIT_LSU_TO_FINISH;
multicycle_freeze <= #1 1'b0;
end
else if (if_stall) begin
state2 <= #1 `NO_FREEZE;
done_once <= #1 1'b1;
multicycle_freeze <= #1 1'b0;
end
else begin
state2 <= #1 `NO_FREEZE;
multicycle_freeze <= #1 1'b0;
end
`WAIT_LSU_TO_FINISH:
if (!lsu_stall && !(|multicycle)) begin
state2 <= #1 `NO_FREEZE;
end
else if (!lsu_stall & (|multicycle)) begin
state2 <= #1 `FREEZE_BYMULTICYCLE;
multicycle_freeze <= #1 1'b1;
multicycle_cnt <= #1 multicycle - 'd1;
end
endcase
end
 
endmodule
/verilog/or1200.xcv/generic_tpram_32x32.v
0,0 → 1,284
//////////////////////////////////////////////////////////////////////
//// ////
//// Generic Two-Port Synchronous RAM ////
//// ////
//// This file is part of memory library available from ////
//// http://www.opencores.org/cvsweb.shtml/generic_memories/ ////
//// ////
//// Description ////
//// This block is a wrapper with common two-port ////
//// synchronous memory interface for different ////
//// types of ASIC and FPGA RAMs. Beside universal memory ////
//// interface it also provides behavioral model of generic ////
//// two-port synchronous RAM. ////
//// It should be used in all OPENCORES designs that want to be ////
//// portable accross different target technologies and ////
//// independent of target memory. ////
//// ////
//// Supported ASIC RAMs are: ////
//// - Artisan Double-Port Sync RAM ////
//// - Avant! Two-Port Sync RAM (*) ////
//// - Virage 2-port Sync RAM ////
//// ////
//// Supported FPGA RAMs are: ////
//// - Xilinx Virtex RAMB4_S16_S16 ////
//// ////
//// To Do: ////
//// - fix Avant! ////
//// - xilinx rams need external tri-state logic ////
//// - add additional RAMs (Altera, VS etc) ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.1 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/30 05:38:02 lampret
// Adding empty directories required by HDL coding guidelines
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module generic_tpram_32x32(
// Generic synchronous two-port RAM interface
clk_a, rst_a, ce_a, we_a, oe_a, addr_a, di_a, do_a,
clk_b, rst_b, ce_b, we_b, oe_b, addr_b, di_b, do_b
);
 
//
// Default address and data buses width
//
parameter aw = 5;
parameter dw = 32;
 
//
// Generic synchronous two-port RAM interface
//
input clk_a; // Clock
input rst_a; // Reset
input ce_a; // Chip enable input
input we_a; // Write enable input
input oe_a; // Output enable input
input [aw-1:0] addr_a; // address bus inputs
input [dw-1:0] di_a; // input data bus
output [dw-1:0] do_a; // output data bus
input clk_b; // Clock
input rst_b; // Reset
input ce_b; // Chip enable input
input we_b; // Write enable input
input oe_b; // Output enable input
input [aw-1:0] addr_b; // address bus inputs
input [dw-1:0] di_b; // input data bus
output [dw-1:0] do_b; // output data bus
 
//
// Internal wires and registers
//
 
 
`ifdef ARTISAN_SDP
 
//
// Instantiation of ASIC memory:
//
// Artisan Synchronous Double-Port RAM (ra2sh)
//
art_hsdp_32x32 #(dw, 1<<aw, aw) artisan_sdp(
.qa(do_a),
.clka(clk_a),
.cena(~ce_a),
.wena(~we_a),
.aa(addr_a),
.da(di_a),
.oena(~oe_a),
.qb(do_b),
.clkb(clk_b),
.cenb(~ce_b),
.wenb(~we_b),
.ab(addr_b),
.db(di_b),
.oenb(~oe_b)
);
 
`else
 
`ifdef AVANT_ATP
 
//
// Instantiation of ASIC memory:
//
// Avant! Asynchronous Two-Port RAM
//
avant_atp avant_atp(
.web(~we),
.reb(),
.oeb(~oe),
.rcsb(),
.wcsb(),
.ra(addr),
.wa(addr),
.di(di),
.do(do)
);
 
`else
 
`ifdef VIRAGE_STP
 
//
// Instantiation of ASIC memory:
//
// Virage Synchronous 2-port R/W RAM
//
virage_stp virage_stp(
.QA(do_a),
.QB(do_b),
 
.ADRA(addr_a),
.DA(di_a),
.WEA(we_a),
.OEA(oe_a),
.MEA(ce_a),
.CLKA(clk_a),
 
.ADRB(adr_b),
.DB(di_b),
.WEB(we_b),
.OEB(oe_b),
.MEB(ce_b),
.CLKB(clk_b)
);
 
`else
 
`ifdef XILINX_RAMB4
 
//
// Instantiation of FPGA memory:
//
// Virtex/Spartan2
//
 
//
// Block 0
//
RAMB4_S16_S16 ramb4_s16_s16_0(
.CLKA(clk_a),
.RSTA(rst_a),
.ADDRA(addr_a),
.DIA(di_a[15:0]),
.ENA(ce_a),
.WEA(we_a),
.DOA(do_a[15:0]),
 
.CLKB(clk_b),
.RSTB(rst_b),
.ADDRB(addr_b),
.DIB(di_b[15:0]),
.ENB(ce_b),
.WEB(we_b),
.DOB(do_b[15:0])
);
 
//
// Block 1
//
RAMB4_S16_S16 ramb4_s16_s16_1(
.CLKA(clk_a),
.RSTA(rst_a),
.ADDRA(addr_a),
.DIA(di_a[31:16]),
.ENA(ce_a),
.WEA(we_a),
.DOA(do_a[31:16]),
 
.CLKB(clk_b),
.RSTB(rst_b),
.ADDRB(addr_b),
.DIB(di_b[31:16]),
.ENB(ce_b),
.WEB(we_b),
.DOB(do_b[31:16])
);
 
`else
 
//
// Generic two-port synchronous RAM model
//
 
//
// Generic RAM's registers and wires
//
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
reg [dw-1:0] do_reg_a; // RAM data output register
reg [dw-1:0] do_reg_b; // RAM data output register
 
//
// Data output drivers
//
assign do_a = (oe_a) ? do_reg_a : {dw{1'bz}};
assign do_b = (oe_b) ? do_reg_b : {dw{1'bz}};
 
//
// RAM read and write
//
always @(posedge clk_a)
if (ce_a && !we_a)
do_reg_a <= #1 mem[addr_a];
else if (ce_a && we_a)
mem[addr_a] <= #1 di_a;
 
//
// RAM read and write
//
always @(posedge clk_b)
if (ce_b && !we_b)
do_reg_b <= #1 mem[addr_b];
else if (ce_b && we_b)
mem[addr_b] <= #1 di_b;
 
`endif // !XILINX_RAMB4_S16_S16
`endif // !VIRAGE_STP
`endif // !AVANT_ATP
`endif // !ARTISAN_SDP
 
endmodule
/verilog/or1200.xcv/generic_multp2_32x32.v
0,0 → 1,93
//////////////////////////////////////////////////////////////////////
//// ////
//// Generic 32x32 multiplier ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Generic 32x32 multiplier with pipeline stages. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
`include "timescale.v"
`include "defines.v"
 
// 32x32 multiplier, no input/output registers
// Registers inside Wallace trees every 8 full adder levels,
// with first pipeline after level 4
 
`define W 32
`define WW 64
 
module multp2_32x32 ( X, Y, CLK, RST, P );
 
input [`W-1:0] X;
input [`W-1:0] Y;
input CLK;
input RST;
output [`WW-1:0] P;
 
reg [`WW-1:0] p0;
reg [`WW-1:0] p1;
 
always @(posedge CLK or posedge RST)
if (RST)
p0 <= `WW'b0;
else
p0 <= #1 X * Y;
 
always @(posedge CLK or posedge RST)
if (RST)
p1 <= `WW'b0;
else
p1 <= #1 p0;
 
assign P = p1;
 
endmodule
/verilog/or1200.xcv/cfgr.v
0,0 → 1,221
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's VR, UPR and Configuration Registers ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// According to OR1K architectural and OR1200 specifications. ////
//// ////
//// To Do: ////
//// - done ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:35 igorm
// no message
//
// Revision 1.1 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:21 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module cfgr(
// RISC Internal Interface
clk, rst, spr_addr, spr_dat_o
);
 
//
// RISC Internal Interface
//
input clk; // Clock
input rst; // Reset
input [31:0] spr_addr; // SPR Address
output [31:0] spr_dat_o; // SPR Read Data
 
//
// Internal wires & registers
//
reg [31:0] spr_dat_o; // SPR Read Data
 
`ifdef CFGR_IMPLEMENTED
 
//
// Implementation of VR, UPR and configuration registers
//
always @(spr_addr)
`ifdef SYS_FULL_DECODE
if (!spr_addr[31:4])
`endif
case(spr_addr[3:0])
`SPRGRP_SYS_VR: begin
spr_dat_o[`VR_REV_BITS] = `VR_REV;
spr_dat_o[`VR_RES1_BITS] = `VR_RES1;
spr_dat_o[`VR_CFG_BITS] = `VR_CFG;
spr_dat_o[`VR_VER_BITS] = `VR_VER;
end
`SPRGRP_SYS_UPR: begin
spr_dat_o[`UPR_UP_BITS] = `UPR_UP;
spr_dat_o[`UPR_DCP_BITS] = `UPR_DCP;
spr_dat_o[`UPR_ICP_BITS] = `UPR_ICP;
spr_dat_o[`UPR_DMP_BITS] = `UPR_DMP;
spr_dat_o[`UPR_IMP_BITS] = `UPR_IMP;
spr_dat_o[`UPR_MP_BITS] = `UPR_MP;
spr_dat_o[`UPR_DUP_BITS] = `UPR_DUP;
spr_dat_o[`UPR_PCUP_BITS] = `UPR_PCUP;
spr_dat_o[`UPR_PMP_BITS] = `UPR_PMP;
spr_dat_o[`UPR_PICP_BITS] = `UPR_PICP;
spr_dat_o[`UPR_TTP_BITS] = `UPR_TTP;
spr_dat_o[`UPR_RES1_BITS] = `UPR_RES1;
spr_dat_o[`UPR_CUP_BITS] = `UPR_CUP;
end
`SPRGRP_SYS_CPUCFGR: begin
spr_dat_o[`CPUCFGR_NSGF_BITS] = `CPUCFGR_NSGF;
spr_dat_o[`CPUCFGR_HGF_BITS] = `CPUCFGR_HGF;
spr_dat_o[`CPUCFGR_OB32S_BITS] = `CPUCFGR_OB32S;
spr_dat_o[`CPUCFGR_OB64S_BITS] = `CPUCFGR_OB64S;
spr_dat_o[`CPUCFGR_OF32S_BITS] = `CPUCFGR_OF32S;
spr_dat_o[`CPUCFGR_OF64S_BITS] = `CPUCFGR_OF64S;
spr_dat_o[`CPUCFGR_OV64S_BITS] = `CPUCFGR_OV64S;
spr_dat_o[`CPUCFGR_RES1_BITS] = `CPUCFGR_RES1;
end
`SPRGRP_SYS_DMMUCFGR: begin
spr_dat_o[`DMMUCFGR_NTW_BITS] = `DMMUCFGR_NTW;
spr_dat_o[`DMMUCFGR_NTS_BITS] = `DMMUCFGR_NTS;
spr_dat_o[`DMMUCFGR_NAE_BITS] = `DMMUCFGR_NAE;
spr_dat_o[`DMMUCFGR_CRI_BITS] = `DMMUCFGR_CRI;
spr_dat_o[`DMMUCFGR_PRI_BITS] = `DMMUCFGR_PRI;
spr_dat_o[`DMMUCFGR_TEIRI_BITS] = `DMMUCFGR_TEIRI;
spr_dat_o[`DMMUCFGR_HTR_BITS] = `DMMUCFGR_HTR;
spr_dat_o[`DMMUCFGR_RES1_BITS] = `DMMUCFGR_RES1;
end
`SPRGRP_SYS_IMMUCFGR: begin
spr_dat_o[`IMMUCFGR_NTW_BITS] = `IMMUCFGR_NTW;
spr_dat_o[`IMMUCFGR_NTS_BITS] = `IMMUCFGR_NTS;
spr_dat_o[`IMMUCFGR_NAE_BITS] = `IMMUCFGR_NAE;
spr_dat_o[`IMMUCFGR_CRI_BITS] = `IMMUCFGR_CRI;
spr_dat_o[`IMMUCFGR_PRI_BITS] = `IMMUCFGR_PRI;
spr_dat_o[`IMMUCFGR_TEIRI_BITS] = `IMMUCFGR_TEIRI;
spr_dat_o[`IMMUCFGR_HTR_BITS] = `IMMUCFGR_HTR;
spr_dat_o[`IMMUCFGR_RES1_BITS] = `IMMUCFGR_RES1;
end
`SPRGRP_SYS_DCCFGR: begin
spr_dat_o[`DCCFGR_NCW_BITS] = `DCCFGR_NCW;
spr_dat_o[`DCCFGR_NCS_BITS] = `DCCFGR_NCS;
spr_dat_o[`DCCFGR_CBS_BITS] = `DCCFGR_CBS;
spr_dat_o[`DCCFGR_CWS_BITS] = `DCCFGR_CWS;
spr_dat_o[`DCCFGR_CCRI_BITS] = `DCCFGR_CCRI;
spr_dat_o[`DCCFGR_CBIRI_BITS] = `DCCFGR_CBIRI;
spr_dat_o[`DCCFGR_CBPRI_BITS] = `DCCFGR_CBPRI;
spr_dat_o[`DCCFGR_CBLRI_BITS] = `DCCFGR_CBLRI;
spr_dat_o[`DCCFGR_CBFRI_BITS] = `DCCFGR_CBFRI;
spr_dat_o[`DCCFGR_CBWBRI_BITS] = `DCCFGR_CBWBRI;
spr_dat_o[`DCCFGR_RES1_BITS] = `DCCFGR_RES1;
end
`SPRGRP_SYS_ICCFGR: begin
spr_dat_o[`ICCFGR_NCW_BITS] = `ICCFGR_NCW;
spr_dat_o[`ICCFGR_NCS_BITS] = `ICCFGR_NCS;
spr_dat_o[`ICCFGR_CBS_BITS] = `ICCFGR_CBS;
spr_dat_o[`ICCFGR_CWS_BITS] = `ICCFGR_CWS;
spr_dat_o[`ICCFGR_CCRI_BITS] = `ICCFGR_CCRI;
spr_dat_o[`ICCFGR_CBIRI_BITS] = `ICCFGR_CBIRI;
spr_dat_o[`ICCFGR_CBPRI_BITS] = `ICCFGR_CBPRI;
spr_dat_o[`ICCFGR_CBLRI_BITS] = `ICCFGR_CBLRI;
spr_dat_o[`ICCFGR_CBFRI_BITS] = `ICCFGR_CBFRI;
spr_dat_o[`ICCFGR_CBWBRI_BITS] = `ICCFGR_CBWBRI;
spr_dat_o[`ICCFGR_RES1_BITS] = `ICCFGR_RES1;
end
`SPRGRP_SYS_DCFGR: begin
spr_dat_o[`DCFGR_NDP_BITS] = `DCFGR_NDP;
spr_dat_o[`DCFGR_WPCI_BITS] = `DCFGR_WPCI;
spr_dat_o[`DCFGR_RES1_BITS] = `DCFGR_RES1;
end
default: spr_dat_o = 32'h0000_0000;
endcase
`ifdef SYS_FULL_DECODE
else
spr_dat_o = 32'h0000_0000;
`endif
 
`else
 
//
// When configuration registers are not implemented, only
// implement VR and UPR
//
always @(spr_addr)
`ifdef SYS_FULL_DECODE
if (!spr_addr[31:4])
`endif
case(spr_addr[3:0])
`SPRGRP_SYS_VR: begin
spr_dat_o[`VR_REV_BITS] = `VR_REV;
spr_dat_o[`VR_RES1_BITS] = `VR_RES1;
spr_dat_o[`VR_CFG_BITS] = `VR_CFG;
spr_dat_o[`VR_VER_BITS] = `VR_VER;
end
`SPRGRP_SYS_UPR: begin
spr_dat_o[`UPR_UP_BITS] = `UPR_UP;
spr_dat_o[`UPR_DCP_BITS] = `UPR_DCP;
spr_dat_o[`UPR_ICP_BITS] = `UPR_ICP;
spr_dat_o[`UPR_DMP_BITS] = `UPR_DMP;
spr_dat_o[`UPR_IMP_BITS] = `UPR_IMP;
spr_dat_o[`UPR_MP_BITS] = `UPR_MP;
spr_dat_o[`UPR_DUP_BITS] = `UPR_DUP;
spr_dat_o[`UPR_PCUP_BITS] = `UPR_PCUP;
spr_dat_o[`UPR_PMP_BITS] = `UPR_PMP;
spr_dat_o[`UPR_PICP_BITS] = `UPR_PICP;
spr_dat_o[`UPR_TTP_BITS] = `UPR_TTP;
spr_dat_o[`UPR_RES1_BITS] = `UPR_RES1;
spr_dat_o[`UPR_CUP_BITS] = `UPR_CUP;
end
default: spr_dat_o = 32'h0000_0000;
endcase
`ifdef SYS_FULL_DECODE
else
spr_dat_o = 32'h0000_0000;
`endif
 
`endif
 
endmodule
/verilog/or1200.xcv/dc_tag.v
0,0 → 1,112
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's DC TAG RAMs ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Instatiation of data cache tag rams. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module dc_tag(
// Clock and reset
clk, rst,
 
// Internal i/f
addr, en, we, datain, tag_v, tag
);
 
parameter dw = 20;
parameter aw = 9;
 
//
// I/O
//
input clk;
input rst;
input [aw-1:0] addr;
input en;
input we;
input [dw-1:0] datain;
output tag_v;
output [dw-2:0] tag;
 
`ifdef OR1200_NO_DC
 
//
// Data cache not implemented
//
assign tag = {dw-1{1'b0}};
assign tag_v = 1'b0;
 
`else
 
//
// Instantiation of TAG RAM block
//
generic_spram_512x20 dc_tag0(
.clk(clk),
.rst(rst),
.ce(en),
.we(we),
.oe(1'b1),
.addr(addr),
.di(datain),
.do({tag_v, tag})
);
 
`endif
 
endmodule
/verilog/or1200.xcv/or1200.v
0,0 → 1,628
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200 Top Level ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// OR1200 Top Level ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:35 igorm
// no message
//
// Revision 1.4 2001/08/13 03:36:20 lampret
// Added cfg regs. Moved all defines into one defines.v file. More cleanup.
//
// Revision 1.3 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/22 03:31:54 lampret
// Fixed RAM's oen bug. Cache bypass under development.
//
// Revision 1.1 2001/07/20 00:46:21 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module or1200(
// System
clk, rst, pic_ints, clkdiv_by_2,
 
// Instruction WISHBONE INTERFACE
iwb_clk_i, iwb_rst_i, iwb_ack_i, iwb_err_i, iwb_rty_i, iwb_dat_i,
iwb_cyc_o, iwb_adr_o, iwb_stb_o, iwb_we_o, iwb_sel_o, iwb_dat_o,
 
// Data WISHBONE INTERFACE
dwb_clk_i, dwb_rst_i, dwb_ack_i, dwb_err_i, dwb_rty_i, dwb_dat_i,
dwb_cyc_o, dwb_adr_o, dwb_stb_o, dwb_we_o, dwb_sel_o, dwb_dat_o,
 
// External Debug Interface
dbg_stall_i, dbg_dat_i, dbg_adr_i, dbg_op_i, dbg_ewt_i,
dbg_lss_o, dbg_is_o, dbg_wp_o, dbg_bp_o, dbg_dat_o,
// Power Management
pm_clksd, pm_cpustall, pm_dc_gate, pm_ic_gate, pm_dmmu_gate,
pm_immu_gate, pm_tt_gate, pm_cpu_gate, pm_wakeup, pm_lvolt
 
);
 
parameter dw = `OPERAND_WIDTH;
parameter aw = `OPERAND_WIDTH;
parameter ppic_ints = `PIC_INTS;
 
//
// I/O
//
 
//
// System
//
input clk;
input rst;
input clkdiv_by_2;
input [ppic_ints-1:0] pic_ints;
 
//
// Instruction WISHBONE interface
//
input iwb_clk_i; // clock input
input iwb_rst_i; // reset input
input iwb_ack_i; // normal termination
input iwb_err_i; // termination w/ error
input iwb_rty_i; // termination w/ retry
input [dw-1:0] iwb_dat_i; // input data bus
output iwb_cyc_o; // cycle valid output
output [aw-1:0] iwb_adr_o; // address bus outputs
output iwb_stb_o; // strobe output
output iwb_we_o; // indicates write transfer
output [3:0] iwb_sel_o; // byte select outputs
output [dw-1:0] iwb_dat_o; // output data bus
 
//
// Data WISHBONE interface
//
input dwb_clk_i; // clock input
input dwb_rst_i; // reset input
input dwb_ack_i; // normal termination
input dwb_err_i; // termination w/ error
input dwb_rty_i; // termination w/ retry
input [dw-1:0] dwb_dat_i; // input data bus
output dwb_cyc_o; // cycle valid output
output [aw-1:0] dwb_adr_o; // address bus outputs
output dwb_stb_o; // strobe output
output dwb_we_o; // indicates write transfer
output [3:0] dwb_sel_o; // byte select outputs
output [dw-1:0] dwb_dat_o; // output data bus
 
//
// External Debug Interface
//
input dbg_stall_i; // External Stall Input
input [dw-1:0] dbg_dat_i; // External Data Input
input [aw-1:0] dbg_adr_i; // External Address Input
input [2:0] dbg_op_i; // External Operation Select Input
input dbg_ewt_i; // External Watchpoint Trigger Input
output [3:0] dbg_lss_o; // External Load/Store Unit Status
output [1:0] dbg_is_o; // External Insn Fetch Status
output [10:0] dbg_wp_o; // Watchpoints Outputs
output dbg_bp_o; // Breakpoint Output
output [dw-1:0] dbg_dat_o; // External Data Output
 
//
// Power Management
//
input pm_cpustall;
output [3:0] pm_clksd;
output pm_dc_gate;
output pm_ic_gate;
output pm_dmmu_gate;
output pm_immu_gate;
output pm_tt_gate;
output pm_cpu_gate;
output pm_wakeup;
output pm_lvolt;
 
 
//
// Internal wires and regs
//
 
//
// DC to BIU
//
wire dcbiu_rdy;
wire [dw-1:0] dcbiu_from_biu;
wire [dw-1:0] dcbiu_to_biu;
wire [aw-1:0] dcbiu_addr;
wire dcbiu_read;
wire dcbiu_write;
wire [3:0] dcbiu_sel;
 
//
// IC to BIU
//
wire icbiu_rdy;
wire [dw-1:0] icbiu_from_biu;
wire [aw-1:0] icbiu_addr;
wire icbiu_read;
wire [3:0] icbiu_sel;
 
//
// CPU's SPR access to various RISC units (shared wires)
//
wire supv;
wire [aw-1:0] spr_addr;
wire [dw-1:0] spr_dat_cpu;
wire [31:0] spr_cs;
wire spr_we;
 
//
// DMMU and CPU
//
wire dmmu_en;
wire dmmuexcept_miss;
wire dmmuexcept_fault;
wire [31:0] spr_dat_dmmu;
 
//
// DMMU and DC
//
wire [aw-1:0] dcdmmu_paddr;
 
//
// DC and CPU's LSU
//
wire dclsu_stall;
wire dclsu_unstall;
wire [aw-1:0] dclsu_addr;
wire [aw-1:0] dclsu_from_dc;
wire [aw-1:0] dclsu_to_dc;
wire [`LSUOP_WIDTH-1:0] dclsu_lsuop;
wire dc_en;
 
//
// IMMU and CPU
//
wire immu_en;
wire immuexcept_miss;
wire immuexcept_fault;
wire [31:0] spr_dat_immu;
 
//
// IC and CPU's ifetch
//
wire icfetch_stall;
wire [aw-1:0] icfetch_addr;
wire [dw-1:0] icfetch_dataout;
wire [`FETCHOP_WIDTH-1:0] icfetch_op;
wire ic_en;
 
//
// IMMU and IC
//
wire [aw-1:0] icimmu_paddr;
 
//
// Connection between CPU and PIC
//
wire [dw-1:0] spr_dat_pic;
wire pic_wakeup;
wire int_low;
wire int_high;
wire int_high_tt;
 
//
// Connection between CPU and PM
//
wire [dw-1:0] spr_dat_pm;
 
//
// CPU and TT
//
wire [dw-1:0] spr_dat_tt;
wire tt_int;
 
//
// Trace port and caches/MMUs
//
wire [dw-1:0] spr_dat_du;
wire du_stall;
wire [dw-1:0] du_addr;
wire [dw-1:0] du_dat_du;
wire du_read;
wire du_write;
wire [`EXCEPT_WIDTH-1:0] du_except;
 
wire ex_freeze;
wire [`BRANCHOP_WIDTH-1:0] branch_op;
 
//
// Assignments
//
assign int_high_tt = int_high | tt_int;
 
//
// Instantiation of Instruction WISHBONE BIU
//
wb_biu iwb_biu(
// WISHBONE interface
.wb_clk_i(iwb_clk_i),
.wb_rst_i(iwb_rst_i),
.wb_ack_i(iwb_ack_i),
.wb_err_i(iwb_err_i),
.wb_rty_i(iwb_rty_i),
.wb_dat_i(iwb_dat_i),
.wb_cyc_o(iwb_cyc_o),
.wb_adr_o(iwb_adr_o),
.wb_stb_o(iwb_stb_o),
.wb_we_o(iwb_we_o),
.wb_sel_o(iwb_sel_o),
.wb_dat_o(iwb_dat_o),
 
// Internal RISC bus
.biu_to_biu(32'b0),
.biu_addr(icbiu_addr),
.biu_read(icbiu_read),
.biu_write(1'b0),
.biu_rdy(icbiu_rdy),
.biu_from_biu(icbiu_from_biu),
.biu_sel(icbiu_sel)
);
 
//
// Instantiation of Data WISHBONE BIU
//
wb_biu dwb_biu(
// WISHBONE interface
.wb_clk_i(dwb_clk_i),
.wb_rst_i(dwb_rst_i),
.wb_ack_i(dwb_ack_i),
.wb_err_i(dwb_err_i),
.wb_rty_i(dwb_rty_i),
.wb_dat_i(dwb_dat_i),
.wb_cyc_o(dwb_cyc_o),
.wb_adr_o(dwb_adr_o),
.wb_stb_o(dwb_stb_o),
.wb_we_o(dwb_we_o),
.wb_sel_o(dwb_sel_o),
.wb_dat_o(dwb_dat_o),
 
// Internal RISC bus
.biu_to_biu(dcbiu_to_biu),
.biu_addr(dcbiu_addr),
.biu_read(dcbiu_read),
.biu_write(dcbiu_write),
.biu_rdy(dcbiu_rdy),
.biu_from_biu(dcbiu_from_biu),
.biu_sel(dcbiu_sel)
);
 
//
// Instantiation of IMMU
//
immu immu(
// Rst and clk
.clk(clk),
.rst(rst),
 
// Fetch i/f
.immu_en(immu_en),
.supv(supv),
.immufetch_vaddr(icfetch_addr),
.immufetch_op(icfetch_op),
.immufetch_stall(),
 
// Except I/F
.immuexcept_miss(immuexcept_miss),
.immuexcept_fault(immuexcept_fault),
 
// SPR access
.spr_cs(spr_cs[`SPR_GROUP_IMMU]),
.spr_write(spr_we),
.spr_addr(spr_addr),
.spr_dat_i(spr_dat_cpu),
.spr_dat_o(spr_dat_immu),
 
// IC i/f
.icimmu_paddr(icimmu_paddr)
);
 
//
// Instantiation of Instruction Cache
//
ic ic(
.clk(clk),
.rst(rst),
.clkdiv_by_2(clkdiv_by_2),
 
// These connect IC to CPU's ifetch
.icfetch_addr(icimmu_paddr),
.icfetch_op(icfetch_op),
.icfetch_dataout(icfetch_dataout),
.icfetch_stall(icfetch_stall),
.ic_en(ic_en),
 
// SPR access
.spr_cs(spr_cs[`SPR_GROUP_IC]),
.spr_write(spr_we),
.spr_addr(spr_addr),
.spr_dat_i(spr_dat_cpu),
 
// These connect IC to BIU
.icbiu_rdy(icbiu_rdy),
.icbiu_datain(icbiu_from_biu),
.icbiu_addr(icbiu_addr),
.icbiu_read(icbiu_read),
.icbiu_sel(icbiu_sel)
);
 
//
// Instantiation of Instruction Cache
//
cpu cpu(
.clk(clk),
.rst(rst),
 
// Connection IC and IFETCHER inside CPU
.ic_insn(icfetch_dataout),
.ic_addr(icfetch_addr),
.ic_stall(icfetch_stall),
.ic_fetchop(icfetch_op),
.ic_en(ic_en),
 
// Connection CPU to external Trace port
.ex_freeze(ex_freeze),
.branch_op(branch_op),
.du_stall(du_stall),
.du_addr(du_addr),
.du_dat_du(du_dat_du),
.du_read(du_read),
.du_write(du_write),
.du_except(du_except),
 
// Connection IMMU and CPU internally
.immu_en(immu_en),
.immuexcept_miss(immuexcept_miss),
.immuexcept_fault(immuexcept_fault),
 
// Connection DMMU and CPU internally
.dmmu_en(dmmu_en),
.dmmuexcept_miss(dmmuexcept_miss),
.dmmuexcept_fault(dmmuexcept_fault),
 
// Connection DC and CPU's LSU
.dclsu_stall(dclsu_stall),
.dclsu_unstall(dclsu_unstall),
.dclsu_addr(dclsu_addr),
.dclsu_datain(dclsu_from_dc),
.dclsu_dataout(dclsu_to_dc),
.dclsu_lsuop(dclsu_lsuop),
.dc_en(dc_en),
 
// Connection PIC and CPU's EXCEPT
.int_high(int_high_tt),
.int_low(int_low),
 
// SPRs
.supv(supv),
.spr_addr(spr_addr),
.spr_dataout(spr_dat_cpu),
.spr_dat_pic(spr_dat_pic),
.spr_dat_tt(spr_dat_tt),
.spr_dat_pm(spr_dat_pm),
.spr_dat_dmmu(spr_dat_dmmu),
.spr_dat_immu(spr_dat_immu),
.spr_dat_du(spr_dat_du),
.spr_cs(spr_cs),
.spr_we(spr_we)
);
 
//
// Instantiation of DMMU
//
dmmu dmmu(
// Rst and clk
.clk(clk),
.rst(rst),
 
// LSU i/f
.dmmu_en(dmmu_en),
.supv(supv),
.dmmulsu_vaddr(dclsu_addr),
.dmmulsu_lsuop(dclsu_lsuop),
.dmmulsu_stall(),
 
// Except I/F
.dmmuexcept_miss(dmmuexcept_miss),
.dmmuexcept_fault(dmmuexcept_fault),
 
// SPR access
.spr_cs(spr_cs[`SPR_GROUP_DMMU]),
.spr_write(spr_we),
.spr_addr(spr_addr),
.spr_dat_i(spr_dat_cpu),
.spr_dat_o(spr_dat_dmmu),
 
// DC i/f
.dcdmmu_paddr(dcdmmu_paddr)
);
 
//
// Instantiation of Data Cache
//
dc dc(
.clk(clk),
.rst(rst),
.clkdiv_by_2(clkdiv_by_2),
 
// These connect DC to CPU's LSU
.dclsu_addr(dcdmmu_paddr),
.dclsu_lsuop(dclsu_lsuop),
.dclsu_datain(dclsu_to_dc),
.dclsu_dataout(dclsu_from_dc),
.dclsu_stall(dclsu_stall),
.dclsu_unstall(dclsu_unstall),
.dc_en(dc_en),
 
// SPR access
.spr_cs(spr_cs[`SPR_GROUP_DC]),
.spr_write(spr_we),
.spr_addr(spr_addr),
.spr_dat_i(spr_dat_cpu),
 
// These connect DC to BIU
.dcbiu_rdy(dcbiu_rdy),
.dcbiu_datain(dcbiu_from_biu),
.dcbiu_dataout(dcbiu_to_biu),
.dcbiu_addr(dcbiu_addr),
.dcbiu_read(dcbiu_read),
.dcbiu_write(dcbiu_write),
.dcbiu_sel(dcbiu_sel)
);
 
//
// Instantiation of Debug Unit
//
du du(
// RISC Internal Interface
.clk(clk),
.rst(rst),
.dclsu_lsuop(dclsu_lsuop),
.icfetch_op(icfetch_op),
.ex_freeze(ex_freeze),
.branch_op(branch_op),
 
// DU's access to SPR unit
.du_stall(du_stall),
.du_addr(du_addr),
.du_dat_i(spr_dat_cpu),
.du_dat_o(du_dat_du),
.du_read(du_read),
.du_write(du_write),
.du_except(du_except),
 
// Access to DU's SPRs
.spr_cs(spr_cs[`SPR_GROUP_DU]),
.spr_write(spr_we),
.spr_addr(spr_addr),
.spr_dat_i(spr_dat_cpu),
.spr_dat_o(spr_dat_du),
 
// External Debug Interface
.dbg_stall_i(dbg_stall_i),
.dbg_dat_i(dbg_dat_i),
.dbg_adr_i(dbg_adr_i),
.dbg_op_i(dbg_op_i),
.dbg_ewt_i(dbg_ewt_i),
.dbg_lss_o(dbg_lss_o),
.dbg_is_o(dbg_is_o),
.dbg_wp_o(dbg_wp_o),
.dbg_bp_o(dbg_bp_o),
.dbg_dat_o(dbg_dat_o)
);
 
//
// Programmable interrupt controller
//
pic pic(
// RISC Internal Interface
.clk(clk),
.rst(rst),
.spr_cs(spr_cs[`SPR_GROUP_PIC]),
.spr_write(spr_we),
.spr_addr(spr_addr),
.spr_dat_i(spr_dat_cpu),
.spr_dat_o(spr_dat_pic),
.pic_wakeup(pic_wakeup),
.int_low(int_low),
.int_high(int_high),
 
// PIC Interface
.pic_int(pic_ints)
);
 
//
// Instantiation of Tick timer
//
tt tt(
// RISC Internal Interface
.clk(clk),
.rst(rst),
.spr_cs(spr_cs[`SPR_GROUP_TT]),
.spr_write(spr_we),
.spr_addr(spr_addr),
.spr_dat_i(spr_dat_cpu),
.spr_dat_o(spr_dat_tt),
.int(tt_int)
);
 
//
// Instantiation of Power Management
//
pm pm(
// RISC Internal Interface
.clk(clk),
.rst(rst),
.pic_wakeup(pic_wakeup),
.spr_write(spr_we),
.spr_addr(spr_addr),
.spr_dat_i(spr_dat_cpu),
.spr_dat_o(spr_dat_pm),
 
// Power Management Interface
.pm_clksd(pm_clksd),
.pm_cpustall(pm_cpustall),
.pm_dc_gate(pm_dc_gate),
.pm_ic_gate(pm_ic_gate),
.pm_dmmu_gate(pm_dmmu_gate),
.pm_immu_gate(pm_immu_gate),
.pm_tt_gate(pm_tt_gate),
.pm_cpu_gate(pm_cpu_gate),
.pm_wakeup(pm_wakeup),
.pm_lvolt(pm_lvolt)
);
 
 
endmodule
/verilog/or1200.xcv/generic_spram_64x14.v
0,0 → 1,240
//////////////////////////////////////////////////////////////////////
//// ////
//// Generic Single-Port Synchronous RAM ////
//// ////
//// This file is part of memory library available from ////
//// http://www.opencores.org/cvsweb.shtml/generic_memories/ ////
//// ////
//// Description ////
//// This block is a wrapper with common single-port ////
//// synchronous memory interface for different ////
//// types of ASIC and FPGA RAMs. Beside universal memory ////
//// interface it also provides behavioral model of generic ////
//// single-port synchronous RAM. ////
//// It should be used in all OPENCORES designs that want to be ////
//// portable accross different target technologies and ////
//// independent of target memory. ////
//// ////
//// Supported ASIC RAMs are: ////
//// - Artisan Single-Port Sync RAM ////
//// - Avant! Two-Port Sync RAM (*) ////
//// - Virage Single-Port Sync RAM ////
//// - Virtual Silicon Single-Port Sync RAM ////
//// ////
//// Supported FPGA RAMs are: ////
//// - Xilinx Virtex RAMB4_S16 ////
//// ////
//// To Do: ////
//// - xilinx rams need external tri-state logic ////
//// - fix avant! two-port ram ////
//// - add additional RAMs (Altera etc) ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.1 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/30 05:38:02 lampret
// Adding empty directories required by HDL coding guidelines
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module generic_spram_64x14(
// Generic synchronous single-port RAM interface
clk, rst, ce, we, oe, addr, di, do
);
 
//
// Default address and data buses width
//
parameter aw = 6;
parameter dw = 14;
 
//
// Generic synchronous single-port RAM interface
//
input clk; // Clock
input rst; // Reset
input ce; // Chip enable input
input we; // Write enable input
input oe; // Output enable input
input [aw-1:0] addr; // address bus inputs
input [dw-1:0] di; // input data bus
output [dw-1:0] do; // output data bus
 
//
// Internal wires and registers
//
wire [1:0] unconnected;
 
`ifdef ARTISAN_SSP
 
//
// Instantiation of ASIC memory:
//
// Artisan Synchronous Single-Port RAM (ra1sh)
//
art_hssp_64x14 #(dw, 1<<aw, aw) artisan_ssp(
.clk(clk),
.cen(~ce),
.wen(~we),
.a(addr),
.d(di),
.oen(~oe),
.q(do)
);
 
`else
 
`ifdef AVANT_ATP
 
//
// Instantiation of ASIC memory:
//
// Avant! Asynchronous Two-Port RAM
//
avant_atp avant_atp(
.web(~we),
.reb(),
.oeb(~oe),
.rcsb(),
.wcsb(),
.ra(addr),
.wa(addr),
.di(di),
.do(do)
);
 
`else
 
`ifdef VIRAGE_SSP
 
//
// Instantiation of ASIC memory:
//
// Virage Synchronous 1-port R/W RAM
//
virage_ssp virage_ssp(
.clk(clk),
.adr(addr),
.d(di),
.we(we),
.oe(oe),
.me(ce),
.q(do)
);
 
`else
 
`ifdef VIRTUALSILICON_SSP
 
//
// Instantiation of ASIC memory:
//
// Virtual Silicon Single-Port Synchronous SRAM
//
virtualsilicon_ssp #(1<<aw, aw-1, dw-1) virtualsilicon_ssp(
.CK(clk),
.ADR(addr),
.DI(di),
.WEN(~we),
.CEN(~ce),
.OEN(~oe),
.DOUT(do)
);
 
`else
 
`ifdef XILINX_RAMB4
 
//
// Instantiation of FPGA memory:
//
// Virtex/Spartan2
//
 
//
// Block 0
//
RAMB4_S16 ramb4_s16_0(
.CLK(clk),
.RST(rst),
.ADDR({2'b00, addr}),
.DI({unconnected, di[13:0]}),
.EN(ce),
.WE(we),
.DO({unconnected, do[13:0]})
);
 
`else
 
//
// Generic single-port synchronous RAM model
//
 
//
// Generic RAM's registers and wires
//
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
reg [dw-1:0] do_reg; // RAM data output register
 
//
// Data output drivers
//
assign do = (oe) ? do_reg : {dw{1'bz}};
 
//
// RAM read and write
//
always @(posedge clk)
if (ce && !we)
do_reg <= #1 mem[addr];
else if (ce && we)
mem[addr] <= #1 di;
 
`endif // !XILINX_RAMB4_S16
`endif // !VIRTUALSILICON_SSP
`endif // !VIRAGE_SSP
`endif // !AVANT_ATP
`endif // !ARTISAN_SSP
 
endmodule
/verilog/or1200.xcv/dc_ram.v
0,0 → 1,153
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's DC RAMs ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Instatiation of DC RAM blocks. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module dc_ram(
// Reset and clock
clk, rst,
 
// Internal i/f
addr, en, we, datain, dataout
);
 
parameter dw = `OPERAND_WIDTH;
parameter aw = 11;
 
//
// I/O
//
input clk;
input rst;
input [aw-1:0] addr;
input en;
input [3:0] we;
input [dw-1:0] datain;
output [dw-1:0] dataout;
 
`ifdef OR1200_NO_DC
 
//
// Data cache not implemented
//
 
assign dataout = {dw{1'b0}};
 
`else
 
//
// Instantiation of RAM block 0
//
generic_spram_2048x8 dc_ram0(
.clk(clk),
.rst(rst),
.ce(en),
.we(we[0]),
.oe(1'b1),
.addr(addr),
.di(datain[7:0]),
.do(dataout[7:0])
);
 
//
// Instantiation of RAM block 1
//
generic_spram_2048x8 dc_ram1(
.clk(clk),
.rst(rst),
.ce(en),
.we(we[1]),
.oe(1'b1),
.addr(addr),
.di(datain[15:8]),
.do(dataout[15:8])
);
 
//
// Instantiation of RAM block 2
//
generic_spram_2048x8 dc_ram2(
.clk(clk),
.rst(rst),
.ce(en),
.we(we[2]),
.oe(1'b1),
.addr(addr),
.di(datain[23:16]),
.do(dataout[23:16])
);
 
//
// Instantiation of RAM block 3
//
generic_spram_2048x8 dc_ram3(
.clk(clk),
.rst(rst),
.ce(en),
.we(we[3]),
.oe(1'b1),
.addr(addr),
.di(datain[31:24]),
.do(dataout[31:24])
);
 
`endif
 
endmodule
/verilog/or1200.xcv/dtlb.v
0,0 → 1,221
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Data TLB ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Instantiation of DTLB. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
//
// Data TLB
//
 
module dtlb(
// Rst and clk
clk, rst,
 
// I/F for translation
tlb_en, vaddr, hit, ppn, uwe, ure, swe, sre,
 
// SPR access
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o
);
 
parameter dw = `OPERAND_WIDTH;
parameter aw = `OPERAND_WIDTH;
 
//
// I/O
//
 
//
// Clock and reset
//
input clk;
input rst;
 
//
// I/F for translation
//
input tlb_en;
input [aw-1:0] vaddr;
output hit;
output [31:13] ppn;
output uwe;
output ure;
output swe;
output sre;
 
//
// SPR access
//
input spr_cs;
input spr_write;
input [31:0] spr_addr;
input [31:0] spr_dat_i;
output [31:0] spr_dat_o;
 
//
// Internal wires and regs
//
wire [31:19] vpn;
wire v;
wire [5:0] tlb_index;
wire tlb_mr_en;
wire tlb_mr_we;
wire [13:0] tlb_mr_ram_in;
wire [13:0] tlb_mr_ram_out;
wire tlb_tr_en;
wire tlb_tr_we;
wire [22:0] tlb_tr_ram_in;
wire [22:0] tlb_tr_ram_out;
 
//
// Implemented bits inside match and translate registers
//
// dtlbwYmrX: vpn 31-19 v 0
// dtlbwYtrX: ppn 31-13 uwe 9 ure 8 swe 7 sre 6
//
// dtlb memory width:
// 19 bits for ppn
// 13 bits for vpn
// 1 bit for valid
// 4 bits for protection
 
//
// Enable for Match registers
//
assign tlb_mr_en = tlb_en | (spr_cs & !spr_addr[9]);
 
//
// Write enable for Match registers
//
assign tlb_mr_we = spr_cs & spr_write & !spr_addr[9];
 
//
// Enable for Translate registers
//
assign tlb_tr_en = tlb_en | (spr_cs & spr_addr[9]);
 
//
// Write enable for Translate registers
//
assign tlb_tr_we = spr_cs & spr_write & spr_addr[9];
 
//
// Output to SPRS unit
//
assign spr_dat_o = (spr_cs & !spr_write & !spr_addr[9]) ?
{vpn, {18{1'b1}}, v} :
(spr_cs & !spr_write & spr_addr[9]) ?
{ppn, 3'b000, uwe, ure, swe, sre, {6{1'b1}}} :
32'h00000000;
 
//
// Assign outputs from Match registers
//
assign {vpn, v} = tlb_mr_ram_out;
 
//
// Assign to Match registers inputs
//
assign tlb_mr_ram_in = {spr_dat_i[31:19], spr_dat_i[0]};
 
//
// Assign outputs from Translate registers
//
assign {ppn, uwe, ure, swe, sre} = tlb_tr_ram_out;
 
//
// Assign to Translate registers inputs
//
assign tlb_tr_ram_in = {spr_dat_i[31:13], spr_dat_i[9:6]};
 
//
// Generate hit
//
assign hit = (vpn == vaddr[31:19]) & v;
 
//
// TLB index is normally vaddr[18:13]. If it is SPR access then index is
// spr_addr[5:0].
//
assign tlb_index = spr_cs ? spr_addr[5:0] : vaddr[18:13];
 
//
// Instantiation of DTLB Match Registers
//
generic_spram_64x14 dtlb_mr_ram(
.clk(clk),
.rst(rst),
.ce(tlb_mr_en),
.we(tlb_mr_we),
.oe(1'b1),
.addr(tlb_index),
.di(tlb_mr_ram_in),
.do(tlb_mr_ram_out)
);
 
//
// Instantiation of DTLB Translate Registers
//
generic_spram_64x23 dtlb_tr_ram(
.clk(clk),
.rst(rst),
.ce(tlb_tr_en),
.we(tlb_tr_we),
.oe(1'b1),
.addr(tlb_index),
.di(tlb_tr_ram_in),
.do(tlb_tr_ram_out)
);
 
endmodule
/verilog/or1200.xcv/sprs.v
0,0 → 1,341
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's interface to SPRs ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Decoding of SPR addresses and access to SPRs ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.3 2001/08/13 03:36:20 lampret
// Added cfg regs. Moved all defines into one defines.v file. More cleanup.
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:21 lampret
// Development version of RTL. Libraries are missing.
//
//
 
`include "timescale.v"
`include "defines.v"
 
module sprs(
// Clk & Rst
clk, rst,
 
// Internal CPU interface
flag, addrbase, addrofs, dat_i, alu_op, branch_op,
epcr, eear, esr, except_start, except_started,
to_wbmux, epcr_we, eear_we, esr_we, pc_we, sr,
spr_dat_cfgr, spr_dat_rf, spr_dat_pc,
 
// From/to other RISC units
spr_dat_pic, spr_dat_tt, spr_dat_pm,
spr_dat_dmmu, spr_dat_immu, spr_dat_du,
spr_addr, spr_dataout, spr_cs, spr_we,
 
du_addr, du_dat_du, du_read,
du_write
 
);
 
parameter width = `OPERAND_WIDTH;
 
//
// I/O Ports
//
 
//
// Internal CPU interface
//
input clk; // Clock
input rst; // Reset
input flag; // From ALU
input [width-1:0] addrbase; // SPR base address
input [15:0] addrofs; // SPR offset
input [width-1:0] dat_i; // SPR write data
input [`ALUOP_WIDTH-1:0] alu_op; // ALU operation
input [`BRANCHOP_WIDTH-1:0] branch_op; // Branch operation
input [width-1:0] epcr; // EPCR0
input [width-1:0] eear; // EEAR0
input [`SR_WIDTH-1:0] esr; // ESR0
input except_start; // Start of exception
input except_started; // Exception was started
output [width-1:0] to_wbmux; // For l.mfspr
output epcr_we; // EPCR0 write enable
output eear_we; // EEAR0 write enable
output esr_we; // ESR0 write enable
output pc_we; // PC write enable
output [`SR_WIDTH-1:0] sr; // SR
input [31:0] spr_dat_cfgr; // Data from CFGR
input [31:0] spr_dat_rf; // Data from RF
input [31:0] spr_dat_pc; // Data from PC
 
//
// To/from other RISC units
//
input [31:0] spr_dat_pic; // Data from PIC
input [31:0] spr_dat_tt; // Data from TT
input [31:0] spr_dat_pm; // Data from PM
input [31:0] spr_dat_dmmu; // Data from DMMU
input [31:0] spr_dat_immu; // Data from IMMU
input [31:0] spr_dat_du; // Data from DU
output [31:0] spr_addr; // SPR Address
output [31:0] spr_dataout; // Data to unit
output [31:0] spr_cs; // Unit select
output spr_we; // SPR write enable
 
//
// To/from Debug Unit
//
input [width-1:0] du_addr; // Address
input [width-1:0] du_dat_du; // Data from DU to SPRS
input du_read; // Read qualifier
input du_write; // Write qualifier
 
//
// Internal regs & wires
//
reg [`SR_WIDTH-1:0] sr; // SR
reg write_spr; // Write SPR
reg read_spr; // Read SPR
reg [width-1:0] to_wbmux; // For l.mfspr
wire sr_we; // Write enable SR
wire cfgr_sel; // Select for cfg regs
wire rf_sel; // Select for RF
wire pc_sel; // Select for PC
wire sr_sel; // Select for SR
wire epcr_sel; // Select for EPCR0
wire eear_sel; // Select for EEAR0
wire esr_sel; // Select for ESR0
wire [31:0] sys_data; // Read data from system SPRs
wire [`SR_WIDTH-1:0] to_sr; // Data to SR
wire du_access; // Debug unit access
wire [`ALUOP_WIDTH-1:0] sprs_op; // ALU operation
reg [31:0] unqualified_cs; // Unqualified chip selects
 
//
// Decide if it is debug unit access
//
assign du_access = du_read | du_write;
 
//
// Generate sprs opcode
//
assign sprs_op = du_write ? `ALUOP_MTSR : du_read ? `ALUOP_MFSR : alu_op;
 
//
// Generate SPR address from base address and offset
// OR from debug unit address
//
assign spr_addr = du_access ? du_addr : addrbase + {16'h0000, addrofs};
 
//
// SPR is written with dat_i from l.mtspr
// OR by debug unit
//
assign spr_dataout = du_write ? du_dat_du : du_read ? to_wbmux : dat_i;
 
//
// Write into SPRs when l.mtspr
//
assign spr_we = du_write | write_spr;
 
//
// Qualify chip selects
//
assign spr_cs = unqualified_cs & {32{read_spr | write_spr}};
 
//
// Decoding of groups
//
always @(spr_addr)
case (spr_addr[`SPR_GROUP_BITS]) // synopsys parallel_case
`SPR_GROUP_WIDTH'd00: unqualified_cs = 32'b00000000_00000000_00000000_00000001;
`SPR_GROUP_WIDTH'd01: unqualified_cs = 32'b00000000_00000000_00000000_00000010;
`SPR_GROUP_WIDTH'd02: unqualified_cs = 32'b00000000_00000000_00000000_00000100;
`SPR_GROUP_WIDTH'd03: unqualified_cs = 32'b00000000_00000000_00000000_00001000;
`SPR_GROUP_WIDTH'd04: unqualified_cs = 32'b00000000_00000000_00000000_00010000;
`SPR_GROUP_WIDTH'd05: unqualified_cs = 32'b00000000_00000000_00000000_00100000;
`SPR_GROUP_WIDTH'd06: unqualified_cs = 32'b00000000_00000000_00000000_01000000;
`SPR_GROUP_WIDTH'd07: unqualified_cs = 32'b00000000_00000000_00000000_10000000;
`SPR_GROUP_WIDTH'd08: unqualified_cs = 32'b00000000_00000000_00000001_00000000;
`SPR_GROUP_WIDTH'd09: unqualified_cs = 32'b00000000_00000000_00000010_00000000;
`SPR_GROUP_WIDTH'd10: unqualified_cs = 32'b00000000_00000000_00000100_00000000;
`SPR_GROUP_WIDTH'd11: unqualified_cs = 32'b00000000_00000000_00001000_00000000;
`SPR_GROUP_WIDTH'd12: unqualified_cs = 32'b00000000_00000000_00010000_00000000;
`SPR_GROUP_WIDTH'd13: unqualified_cs = 32'b00000000_00000000_00100000_00000000;
`SPR_GROUP_WIDTH'd14: unqualified_cs = 32'b00000000_00000000_01000000_00000000;
`SPR_GROUP_WIDTH'd15: unqualified_cs = 32'b00000000_00000000_10000000_00000000;
`SPR_GROUP_WIDTH'd16: unqualified_cs = 32'b00000000_00000001_00000000_00000000;
`SPR_GROUP_WIDTH'd17: unqualified_cs = 32'b00000000_00000010_00000000_00000000;
`SPR_GROUP_WIDTH'd18: unqualified_cs = 32'b00000000_00000100_00000000_00000000;
`SPR_GROUP_WIDTH'd19: unqualified_cs = 32'b00000000_00001000_00000000_00000000;
`SPR_GROUP_WIDTH'd20: unqualified_cs = 32'b00000000_00010000_00000000_00000000;
`SPR_GROUP_WIDTH'd21: unqualified_cs = 32'b00000000_00100000_00000000_00000000;
`SPR_GROUP_WIDTH'd22: unqualified_cs = 32'b00000000_01000000_00000000_00000000;
`SPR_GROUP_WIDTH'd23: unqualified_cs = 32'b00000000_10000000_00000000_00000000;
`SPR_GROUP_WIDTH'd24: unqualified_cs = 32'b00000001_00000000_00000000_00000000;
`SPR_GROUP_WIDTH'd25: unqualified_cs = 32'b00000010_00000000_00000000_00000000;
`SPR_GROUP_WIDTH'd26: unqualified_cs = 32'b00000100_00000000_00000000_00000000;
`SPR_GROUP_WIDTH'd27: unqualified_cs = 32'b00001000_00000000_00000000_00000000;
`SPR_GROUP_WIDTH'd28: unqualified_cs = 32'b00010000_00000000_00000000_00000000;
`SPR_GROUP_WIDTH'd29: unqualified_cs = 32'b00100000_00000000_00000000_00000000;
`SPR_GROUP_WIDTH'd30: unqualified_cs = 32'b01000000_00000000_00000000_00000000;
`SPR_GROUP_WIDTH'd31: unqualified_cs = 32'b10000000_00000000_00000000_00000000;
endcase
 
//
// SPRs System Group
//
 
//
// What to write into SR
//
assign to_sr = (branch_op == `BRANCHOP_RFE) ? esr : spr_dataout[`SR_WIDTH-1:0];
 
//
// Selects for system SPRs
//
assign cfgr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:4] == `SPR_CFGR));
assign rf_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:5] == `SPR_RF));
assign pc_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:0] == `SPR_PC));
assign sr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:0] == `SPR_SR));
assign epcr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:0] == `SPR_EPCR));
assign eear_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:0] == `SPR_EEAR));
assign esr_sel = (spr_cs[`SPR_GROUP_SYS] && (spr_addr[10:0] == `SPR_ESR));
 
//
// Write enables for system SPRs
//
assign sr_we = (write_spr && sr_sel) | (branch_op == `BRANCHOP_RFE);
assign pc_we = (write_spr && pc_sel);
assign epcr_we = (write_spr && epcr_sel);
assign eear_we = (write_spr && eear_sel);
assign esr_we = (write_spr && esr_sel);
 
//
// Output from system SPRs
//
assign sys_data = (spr_dat_cfgr & {32{read_spr & cfgr_sel}}) |
(spr_dat_rf & {32{read_spr & rf_sel}}) |
(spr_dat_pc & {32{read_spr & pc_sel}}) |
({{32-`SR_WIDTH{1'b0}},sr} & {32{read_spr & sr_sel}}) |
(epcr & {32{read_spr & epcr_sel}}) |
(eear & {32{read_spr & eear_sel}}) |
({{32-`SR_WIDTH{1'b0}},esr} & {32{read_spr & esr_sel}});
 
//
// Supervision register
//
always @(posedge clk or posedge rst)
if (rst)
sr <= #1 `SR_WIDTH'b001;
else if (except_started) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display(" INFO: exception started. SR[SUPV] set and SR[EXR] cleared.");
// synopsys translate_on
`endif
sr[`SR_SUPV] <= #1 1'b1;
sr[`SR_EXR] <= #1 1'b0;
sr[`SR_WIDTH-1:2] <= #1 {`SR_WIDTH-2{1'b0}};
end
else if (sr_we) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display(" INFO: writing into SR register: %h", spr_dataout);
// synopsys translate_on
`endif
sr <= #1 to_sr;
end
 
//
// MTSPR/MFSPR interface
//
always @(sprs_op or spr_addr or spr_dataout or sys_data or spr_dat_pic or spr_dat_pm or
spr_dat_dmmu or spr_dat_immu or spr_dat_du or spr_dat_tt) begin
case (sprs_op) // synopsys full_case parallel_case
`ALUOP_MTSR : begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: SPRS: mtspr (%h) <- %h", $time, spr_addr, spr_dataout);
// synopsys translate_on
`endif
write_spr = 1'b1;
read_spr = 1'b0;
to_wbmux = 32'b0;
end
`ALUOP_MFSR : begin
casex (spr_addr[`SPR_GROUP_BITS])
`SPR_GROUP_TT:
to_wbmux = spr_dat_tt;
`SPR_GROUP_PIC:
to_wbmux = spr_dat_pic;
`SPR_GROUP_PM:
to_wbmux = spr_dat_pm;
`SPR_GROUP_DMMU:
to_wbmux = spr_dat_dmmu;
`SPR_GROUP_IMMU:
to_wbmux = spr_dat_immu;
`SPR_GROUP_DU:
to_wbmux = spr_dat_du;
`SPR_GROUP_SYS:
to_wbmux = sys_data;
default:
to_wbmux = 32'b0;
endcase
write_spr = 1'b0;
read_spr = 1'b1;
end
default : begin
write_spr = 1'b0;
read_spr = 1'b0;
to_wbmux = 32'b0;
end
endcase
end
 
endmodule
/verilog/or1200.xcv/tt.v
0,0 → 1,195
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Tick Timer ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// TT according to OR1K architectural specification. ////
//// ////
//// To Do: ////
//// None ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:35 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:23 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module tt(
// RISC Internal Interface
clk, rst, spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o,
int
);
 
//
// RISC Internal Interface
//
input clk; // Clock
input rst; // Reset
input spr_cs; // SPR CS
input spr_write; // SPR Write
input [31:0] spr_addr; // SPR Address
input [31:0] spr_dat_i; // SPR Write Data
output [31:0] spr_dat_o; // SPR Read Data
output int; // Interrupt output
 
`ifdef TT_IMPLEMENTED
 
//
// TT Mode Register bits (or no register)
//
`ifdef TT_TTMR
reg [31:0] ttmr; // TTMR bits
`else
wire [31:0] ttmr; // No TTMR register
`endif
 
//
// TT Count Register bits (or no register)
//
`ifdef TT_TTCR
reg [31:0] ttcr; // TTCR bits
`else
wire [31:0] ttcr; // No TTCR register
`endif
 
//
// Internal wires & regs
//
wire ttmr_sel; // TTMR select
wire ttcr_sel; // TTCR select
wire match; // Asserted when TTMR[TP]
// is equal to TTCR[27:0]
wire restart; // Restart counter when asserted
wire stop; // Stop counter when asserted
reg [31:0] spr_dat_o; // SPR data out
 
//
// TT registers address decoder
//
assign ttmr_sel = (spr_cs && (spr_addr[`TTOFS_BITS] == `TT_OFS_TTMR)) ? 1'b1 : 1'b0;
assign ttcr_sel = (spr_cs && (spr_addr[`TTOFS_BITS] == `TT_OFS_TTCR)) ? 1'b1 : 1'b0;
 
//
// Write to TTMR or update of TTMR[IP] bit
//
`ifdef TT_TTMR
always @(posedge clk or posedge rst)
if (rst)
ttmr <= 32'b0;
else if (ttmr_sel && spr_write)
ttmr <= #1 spr_dat_i;
else if (ttmr[`TT_TTMR_IE])
ttmr[`TT_TTMR_IP] <= #1 ttmr[`TT_TTMR_IP] | int;
`else
assign ttmr = {2'b11, 30'b0}; // TTMR[M] = 0x3
`endif
 
//
// Write to or increment of TTCR
//
`ifdef TT_TTCR
always @(posedge clk or posedge restart)
if (restart)
ttcr <= 32'b0;
else if (ttcr_sel && spr_write)
ttcr <= #1 spr_dat_i;
else if (!stop)
ttcr <= #1 ttcr + 1'd1;
`else
assign ttcr = 32'b0;
`endif
 
//
// Read TT registers
//
always @(spr_addr or ttmr or ttcr)
case (spr_addr[`TTOFS_BITS]) // synopsys full_case parallel_case
`ifdef TT_READREGS
`TT_OFS_TTMR: spr_dat_o = ttmr;
`endif
default: spr_dat_o = ttcr;
endcase
 
//
// A match when TTMR[TP] is equal to TTCR[27:0]
//
assign match = (ttmr[`TT_TTMR_TP] == ttcr[27:0]) ? 1'b1 : 1'b0;
 
//
// Restart when match and TTMR[M]==0x1 or when rst is asserted
//
assign restart = (match && (ttmr[`TT_TTMR_M] == 2'b01) || rst) ? 1'b1 : 1'b0;
 
//
// Stop when match and TTMR[M]==0x2 or when TTMR[M]==0x0
//
assign stop = (match && (ttmr[`TT_TTMR_M] == 2'b10) || (ttmr[`TT_TTMR_M] == 2'b00)) ? 1'b1 : 1'b0;
 
//
// Generate an interrupt request
//
assign int = match & ttmr[`TT_TTMR_IE];
 
`else
 
//
// When TT is not implemented, drive all outputs as would when TT is disabled
//
assign int = 1'b0;
 
//
// Read TT registers
//
`ifdef TT_READREGS
assign spr_dat_o = 32'b0;
`endif
 
`endif
 
endmodule
/verilog/or1200.xcv/generic_spram_64x37.v
0,0 → 1,266
//////////////////////////////////////////////////////////////////////
//// ////
//// Generic Single-Port Synchronous RAM ////
//// ////
//// This file is part of memory library available from ////
//// http://www.opencores.org/cvsweb.shtml/generic_memories/ ////
//// ////
//// Description ////
//// This block is a wrapper with common single-port ////
//// synchronous memory interface for different ////
//// types of ASIC and FPGA RAMs. Beside universal memory ////
//// interface it also provides behavioral model of generic ////
//// single-port synchronous RAM. ////
//// It should be used in all OPENCORES designs that want to be ////
//// portable accross different target technologies and ////
//// independent of target memory. ////
//// ////
//// Supported ASIC RAMs are: ////
//// - Artisan Single-Port Sync RAM ////
//// - Avant! Two-Port Sync RAM (*) ////
//// - Virage Single-Port Sync RAM ////
//// - Virtual Silicon Single-Port Sync RAM ////
//// ////
//// Supported FPGA RAMs are: ////
//// - Xilinx Virtex RAMB4_S16 ////
//// ////
//// To Do: ////
//// - xilinx rams need external tri-state logic ////
//// - fix avant! two-port ram ////
//// - add additional RAMs (Altera etc) ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.1 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/30 05:38:02 lampret
// Adding empty directories required by HDL coding guidelines
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module generic_spram_64x37(
// Generic synchronous single-port RAM interface
clk, rst, ce, we, oe, addr, di, do
);
 
//
// Default address and data buses width
//
parameter aw = 6;
parameter dw = 37;
 
//
// Generic synchronous single-port RAM interface
//
input clk; // Clock
input rst; // Reset
input ce; // Chip enable input
input we; // Write enable input
input oe; // Output enable input
input [aw-1:0] addr; // address bus inputs
input [dw-1:0] di; // input data bus
output [dw-1:0] do; // output data bus
 
//
// Internal wires and registers
//
 
 
`ifdef ARTISAN_SSP
 
//
// Instantiation of ASIC memory:
//
// Artisan Synchronous Single-Port RAM (ra1sh)
//
art_hssp_64x37 #(dw, 1<<aw, aw) artisan_ssp(
.clk(clk),
.cen(~ce),
.wen(~we),
.a(addr),
.d(di),
.oen(~oe),
.q(do)
);
 
`else
 
`ifdef AVANT_ATP
 
//
// Instantiation of ASIC memory:
//
// Avant! Asynchronous Two-Port RAM
//
avant_atp avant_atp(
.web(~we),
.reb(),
.oeb(~oe),
.rcsb(),
.wcsb(),
.ra(addr),
.wa(addr),
.di(di),
.do(do)
);
 
`else
 
`ifdef VIRAGE_SSP
 
//
// Instantiation of ASIC memory:
//
// Virage Synchronous 1-port R/W RAM
//
virage_ssp virage_ssp(
.clk(clk),
.adr(addr),
.d(di),
.we(we),
.oe(oe),
.me(ce),
.q(do)
);
 
`else
 
`ifdef VIRTUALSILICON_SSP
 
//
// Instantiation of ASIC memory:
//
// Virtual Silicon Single-Port Synchronous SRAM
//
virtualsilicon_ssp #(1<<aw, aw-1, dw-1) virtualsilicon_ssp(
.CK(clk),
.ADR(addr),
.DI(di),
.WEN(~we),
.CEN(~ce),
.OEN(~oe),
.DOUT(do)
);
 
`else
 
`ifdef XILINX_RAMB4
 
//
// Instantiation of FPGA memory:
//
// Virtex/Spartan2
//
 
//
// Block 0
//
RAMB4_S16 ramb4_s16_0(
.CLK(clk),
.RST(rst),
.ADDR({2'b00, addr}),
.DI(di[15:0]),
.EN(ce),
.WE(we),
.DO(do[15:0])
);
 
//
// Block 1
//
RAMB4_S16 ramb4_s16_1(
.CLK(clk),
.RST(rst),
.ADDR({2'b00, addr}),
.DI(di[31:16]),
.EN(ce),
.WE(we),
.DO(do[31:16])
);
 
//
// Block 2
//
RAMB4_S16 ramb4_s16_2(
.CLK(clk),
.RST(rst),
.ADDR({2'b00, addr}),
.DI(di[36:32]),
.EN(ce),
.WE(we),
.DO(do[36:32])
);
 
`else
 
//
// Generic single-port synchronous RAM model
//
 
//
// Generic RAM's registers and wires
//
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
reg [dw-1:0] do_reg; // RAM data output register
 
//
// Data output drivers
//
assign do = (oe) ? do_reg : {dw{1'bz}};
 
//
// RAM read and write
//
always @(posedge clk)
if (ce && !we)
do_reg <= #1 mem[addr];
else if (ce && we)
mem[addr] <= #1 di;
 
`endif // !XILINX_RAMB4_S16
`endif // !VIRTUALSILICON_SSP
`endif // !VIRAGE_SSP
`endif // !AVANT_ATP
`endif // !ARTISAN_SSP
 
endmodule
/verilog/or1200.xcv/ic.v
0,0 → 1,287
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Instruction Cache Top Level ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Instruction cache top level instantiating all IC blocks. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.4 2001/08/17 08:01:19 lampret
// IC enable/disable.
//
// Revision 1.3 2001/08/13 03:36:20 lampret
// Added cfg regs. Moved all defines into one defines.v file. More cleanup.
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module ic(
clk, rst, clkdiv_by_2,
 
// Internal i/f to fetcher
ic_en, icfetch_dataout, icfetch_addr, icfetch_op, icfetch_stall,
 
// SPRs
spr_cs, spr_write, spr_addr, spr_dat_i,
 
// External i/f to BIU
icbiu_rdy, icbiu_addr, icbiu_read, icbiu_datain, icbiu_sel
);
 
parameter dw = `OPERAND_WIDTH;
 
//
// I/O
//
 
//
// Clock and reset
//
input clk;
input rst;
input clkdiv_by_2;
 
//
// External I/F
//
input icbiu_rdy;
output [31:0] icbiu_addr;
output icbiu_read;
input [dw-1:0] icbiu_datain;
output [3:0] icbiu_sel;
 
//
// Internal I/F
//
input ic_en;
output [dw-1:0] icfetch_dataout;
input [31:0] icfetch_addr;
input [`FETCHOP_WIDTH-1:0] icfetch_op;
output icfetch_stall;
 
//
// SPR access
//
input spr_cs;
input spr_write;
input [31:0] spr_addr;
input [31:0] spr_dat_i;
 
//
// Internal wires and regs
//
wire tag_v;
wire [18:0] tag;
wire [dw-1:0] to_icram;
wire [dw-1:0] from_icram;
wire [31:0] saved_addr;
wire refill;
wire [3:0] icram_we;
wire ictag_we;
wire [31:0] ic_addr;
wire refill_first;
wire refill_prepare;
wire refill_start;
wire refill_rest;
reg [1:0] valid_div;
reg hit;
wire queue;
wire cntrbusy;
wire icbiu_valid;
wire [`FETCHOP_WIDTH-1:0] icfsm_op;
wire icfsm_read;
reg [1:0] bypass_wait;
wire [`ICINDXH:4] ictag_addr;
wire ictag_en;
wire ictag_v;
wire ic_inv;
 
//
// Simple assignments
//
assign ic_inv = spr_cs & spr_write;
assign icbiu_addr = ic_addr;
assign ictag_we = refill | ic_inv;
assign ictag_addr = ic_inv ? spr_dat_i[`ICINDXH:4] : ic_addr[`ICINDXH:4];
assign ictag_en = ic_inv | ic_en;
assign ictag_v = ~ic_inv;
 
//
// Bypass of IC when it is disabled
//
assign icfsm_op = (ic_en) ? icfetch_op : `FETCHOP_NOP;
assign icbiu_read = (ic_en) ? icfsm_read : (icfetch_op != `FETCHOP_NOP);
assign icbiu_sel = 4'b1111;
 
//
// Wait for IC bypass access
//
always @(posedge rst or posedge clk)
if (rst)
bypass_wait <= #1 2'b0;
// else if (icbiu_valid)
else if (icbiu_rdy)
bypass_wait <= #1 2'b0;
else if (icbiu_read)
bypass_wait <= #1 {bypass_wait[0], 1'b1};
else
bypass_wait <= #1 2'b00;
 
//
// Queue
//
assign queue = (refill && icfsm_op && !refill_first & !refill_rest) ? 1'b1 : 1'b0;
 
//
// IC fetch stall
//
//assign icfetch_stall = (ic_en & (refill | ~hit)) | (~ic_en & bypass_wait[1] & ~icbiu_valid);
//assign icfetch_stall = (ic_en & (refill | ~hit)) | (~ic_en & bypass_wait[1] & ~icbiu_rdy);
assign icfetch_stall = (ic_en & (refill | ~hit)) | (~ic_en & icbiu_read & ~icbiu_rdy);
 
//
// Select between claddr generated by IC FSM and addr[3:2] generated by IFETCH
//
assign ic_addr = (refill == 1'b1) ? saved_addr : icfetch_addr;
 
//
// Input data generated by BIU
//
assign to_icram = icbiu_datain;
 
//
// Select between data generated by ICRAM or passed by BIU
//
assign icfetch_dataout = (refill_first == 1'b1) | (~ic_en) ? icbiu_datain : from_icram;
 
//
// Tag comparison
//
always @(tag or saved_addr or tag_v) begin
if ((tag == saved_addr[31:`ICTAGL]) && tag_v)
hit = 1'b1;
else
hit = 1'b0;
end
 
//
// Valid_div counts RISC clock cycles by modulo 4
//
always @(posedge clk or posedge rst)
if (rst)
valid_div <= #1 2'b0;
else
valid_div <= #1 valid_div + 'd1;
 
//
// icbiu_valid is one RISC clock cycle long icbiu_rdy.
// icbiu_rdy is two/four RISC clock cycles long because memory
// controller works at 1/2 or 1/4 of RISC clock freq (at 1/2 if
// clkdiv_by_2 is asserted).
//
assign icbiu_valid = icbiu_rdy & (valid_div[1] | clkdiv_by_2) & valid_div[0];
 
//
// Generate refill_start that signals to frz_logic a cache linefill is about to begin
//
assign refill_start = (refill_prepare & ~hit) ? 1'b1 : 1'b0;
 
//
// Instantiation of IC FSM
//
ic_fsm ic_fsm(
.clk(clk),
.rst(rst),
.fetch_op(icfsm_op),
.miss(~hit),
.biudata_valid(icbiu_valid),
.start_addr(icfetch_addr),
.saved_addr(saved_addr),
.refill(refill),
.refill_first(refill_first),
.refill_prepare(refill_prepare),
.icram_we(icram_we),
.biu_read(icfsm_read),
.refill_rest(refill_rest),
.cntrbusy(cntrbusy)
);
 
//
// Instantiation of IC main memory
//
ic_ram ic_ram(
.clk(clk),
.rst(rst),
.addr(ic_addr[`ICINDXH:2]),
.en(ic_en),
.we(icram_we),
.datain(to_icram),
.dataout(from_icram)
);
 
//
// Instantiation of IC TAG memory
//
ic_tag ic_tag(
.clk(clk),
.rst(rst),
.addr(ictag_addr[`ICINDXH:4]),
.en(ictag_en),
.we(ictag_we),
.datain({ic_addr[31:`ICTAGL], ictag_v}),
.tag_v(tag_v),
.tag(tag)
);
 
endmodule
/verilog/or1200.xcv/dc_fsm.v
0,0 → 1,340
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's DC FSM ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Data cache state machine ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:35 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
`define DCFSM_IDLE 3'd0
`define DCFSM_DOLOAD 3'd1
`define DCFSM_LREFILL3 3'd2
`define DCFSM_DOSTORE 3'd3
`define DCFSM_SREFILL3 3'd4
`define DCFSM_SMEMWR 3'd5
 
//
// Data cache FSM for cache line of 16 bytes (4x singleword)
//
 
module dc_fsm(
// Clock and reset
clk, rst,
 
// Internal i/f to top level DC
lsu_op, miss, biudata_valid, start_addr, saved_addr,
refill, refill_first, refill_prepare, dcram_we,
biu_read, biu_write, refill_rest, cntrbusy
);
 
//
// I/O
//
input clk;
input rst;
input miss;
input biudata_valid;
input [31:0] start_addr;
input [`LSUOP_WIDTH-1:0] lsu_op;
output [31:0] saved_addr;
output refill;
output refill_first;
output refill_prepare;
output [3:0] dcram_we;
output biu_read;
output biu_write;
output refill_rest;
output cntrbusy;
 
//
// Internal wires and regs
//
wire dcache_off = 1'b0;
reg [31:0] saved_addr;
reg refill;
reg [3:0] dcram_we;
reg [2:0] state;
reg [2:0] cnt;
reg refill_first;
reg refill_prepare;
reg biu_read;
reg biu_write;
reg refill_rest;
reg cntrbusy;
 
//
// Generation of DCRAM write enable
//
always @(refill_first or refill or biudata_valid or lsu_op or start_addr or biu_write) begin
if (refill_first || !refill)
casex({lsu_op, start_addr[1:0]})
{`LSUOP_SB, 2'b00} : dcram_we = 4'b1000 ^ {4{refill_first}};
{`LSUOP_SB, 2'b01} : dcram_we = 4'b0100 ^ {4{refill_first}};
{`LSUOP_SB, 2'b10} : dcram_we = 4'b0010 ^ {4{refill_first}};
{`LSUOP_SB, 2'b11} : dcram_we = 4'b0001 ^ {4{refill_first}};
{`LSUOP_SH, 2'b00} : dcram_we = 4'b1100 ^ {4{refill_first}};
{`LSUOP_SH, 2'b10} : dcram_we = 4'b0011 ^ {4{refill_first}};
{`LSUOP_SW, 2'b00} : dcram_we = 4'b1111 ^ {4{refill_first}};
{`LSUOP_LWZ, 2'bxx}, {`LSUOP_LHZ, 2'bxx}, {`LSUOP_LHS, 2'bxx},
{`LSUOP_LBS, 2'bxx}, {`LSUOP_LBZ, 2'bxx} : dcram_we = 4'b0000 ^ {4{refill_first}};
default : dcram_we = 4'b0000;
endcase
else
dcram_we = {4{refill & biudata_valid & ~biu_write}};
end
 
//
// Main DC FSM
//
always @(posedge clk or posedge rst) begin
if (rst) begin
refill <= #1 1'b0;
state <= #1 `DCFSM_IDLE;
cnt <= #1 3'b000;
refill_first <= #1 1'b0;
biu_read <= #1 1'b0;
biu_write <= #1 1'b0;
saved_addr <= #1 32'b0;
refill_prepare <= #1 1'b0;
refill_rest <= #1 1'b0;
cntrbusy <= #1 1'b0;
end
else
case (state) // synopsys full_case parallel_case
`DCFSM_IDLE :
casex(lsu_op)
`LSUOP_LBZ, `LSUOP_LBS, `LSUOP_LHZ, `LSUOP_LHS, `LSUOP_LWZ: begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: DC_FSM Load op %h start_addr %h", $time, lsu_op, start_addr);
// synopsys translate_on
`endif
state <= #1 `DCFSM_DOLOAD;
refill <= #1 1'b0;
saved_addr <= #1 start_addr;
refill_first <= #1 1'b0;
refill_prepare <= #1 1'b1;
biu_read <= #1 1'b0;
biu_write <= #1 1'b0;
refill_rest <= #1 1'b0;
cntrbusy <= #1 1'b0;
end
`LSUOP_SB, `LSUOP_SH, `LSUOP_SW: begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: DC_FSM Store op %h start_addr %h", $time, lsu_op, start_addr);
// synopsys translate_on
`endif
state <= #1 `DCFSM_DOSTORE;
refill <= #1 1'b0;
saved_addr <= #1 start_addr;
refill_first <= #1 1'b0;
refill_prepare <= #1 1'b1;
biu_read <= #1 1'b0;
biu_write <= #1 1'b0;
refill_rest <= #1 1'b0;
cntrbusy <= #1 1'b0;
end
default: begin
state <= #1 `DCFSM_IDLE;
refill <= #1 1'b0;
refill_first <= #1 1'b0;
refill_prepare <= #1 1'b0;
refill_rest <= #1 1'b0;
biu_read <= #1 1'b0;
biu_write <= #1 1'b0;
cntrbusy <= #1 1'b0;
end
endcase
`DCFSM_DOLOAD:
if (dcache_off) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: DC_FSM DCache off", $time);
// synopsys translate_on
`endif
state <= #1 `DCFSM_DOLOAD;
refill <= #1 1'b1;
refill_first <= #1 1'b1;
refill_prepare <= #1 1'b0;
refill_rest <= #1 1'b0;
biu_read <= #1 1'b1;
if (biudata_valid) begin
state <= #1 `DCFSM_IDLE;
refill <= #1 1'b0;
refill_first <= #1 1'b0;
biu_read <= #1 1'b0;
saved_addr <= #1 start_addr;
end
end else
if (miss) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: DC_FSM Load miss", $time);
// synopsys translate_on
`endif
state <= #1 `DCFSM_LREFILL3;
refill <= #1 1'b1;
refill_first <= #1 1'b1;
refill_prepare <= #1 1'b0;
cnt <= #1 3'd3;
biu_read <= #1 1'b1;
end
else begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: DC_FSM Load hit", $time);
// synopsys translate_on
`endif
state <= #1 `DCFSM_IDLE;
refill <= #1 1'b0;
refill_first <= #1 1'b0;
refill_prepare <= #1 1'b0;
cntrbusy <= #1 (lsu_op) ? 1'b1 : 1'b0;
end
`DCFSM_LREFILL3 : begin
if (biudata_valid && (|cnt)) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: DC_FSM Load refill %d", $time, cnt);
// synopsys translate_on
`endif
cnt <= #1 cnt - 'd1;
saved_addr[3:2] <= #1 saved_addr[3:2] + 'd1;
refill_first <= #1 1'b0;
end
else if (biudata_valid) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: DC_FSM Load refill end", $time, cnt);
// synopsys translate_on
`endif
state <= #1 `DCFSM_IDLE;
refill <= #1 1'b0;
refill_first <= #1 1'b0;
biu_read <= #1 1'b0;
cntrbusy <= #1 (lsu_op) ? 1'b1 : 1'b0;
end
refill_rest <= #1 ~refill_first & refill;
end
`DCFSM_DOSTORE:
if (miss) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: DC_FSM Store miss", $time);
// synopsys translate_on
`endif
state <= #1 `DCFSM_SREFILL3;
refill <= #1 1'b1;
refill_first <= #1 1'b1;
refill_prepare <= #1 1'b0;
cnt <= #1 3'd3;
biu_read <= #1 1'b1;
end
else begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: DC_FSM Store hit", $time);
// synopsys translate_on
`endif
state <= #1 `DCFSM_SMEMWR;
refill <= #1 1'b1;
refill_first <= #1 1'b0;
refill_prepare <= #1 1'b0;
biu_write <= #1 1'b1;
biu_read <= #1 1'b0;
end
`DCFSM_SREFILL3 : begin
if (biudata_valid && (|cnt)) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: DC_FSM Store refill %d", $time, cnt);
// synopsys translate_on
`endif
cnt <= #1 cnt - 'd1;
saved_addr[3:2] <= #1 saved_addr[3:2] + 'd1;
refill_first <= #1 1'b0;
end
else if (biudata_valid) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: DC_FSM Store refill almost done", $time);
// synopsys translate_on
`endif
state <= #1 `DCFSM_SMEMWR;
saved_addr[3:2] <= #1 saved_addr[3:2] + 'd1;
biu_write <= #1 1'b1;
biu_read <= #1 1'b0;
end
refill_rest <= #1 ~refill_first & refill;
end
`DCFSM_SMEMWR :
if (biudata_valid) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: DC_FSM Store refill end (just finished store to external mem)", $time);
// synopsys translate_on
`endif
state <= #1 `DCFSM_IDLE;
refill <= #1 1'b0;
biu_write <= #1 1'b0;
cntrbusy <= #1 (lsu_op) ? 1'b1 : 1'b0;
end
endcase
end
 
endmodule
/verilog/or1200.xcv/id.v
0,0 → 1,886
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Instruction decode ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Majority of instruction decoding is performed here. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.2 2001/08/13 03:36:20 lampret
// Added cfg regs. Moved all defines into one defines.v file. More cleanup.
//
// Revision 1.1 2001/08/09 13:39:33 lampret
// Major clean-up.
//
//
 
`include "timescale.v"
`include "defines.v"
 
module id(
// Clock and reset
clk, rst,
 
// Internal i/f
id_freeze, ex_freeze, wb_freeze, except_flushpipe, if_insn, branch_op,
rf_addra, rf_addrb, alu_op, shrot_op, comp_op, rf_addrw, rfwb_op,
wb_insn, simm, branch_addrofs, lsu_addrofs, sel_a, sel_b, lsu_op,
multicycle, spr_addrimm, wbforw_valid, sig_syscall, sig_trap,
force_dslot_fetch, id_macrc_op, ex_macrc_op
);
 
//
// I/O
//
input clk;
input rst;
input id_freeze;
input ex_freeze;
input wb_freeze;
input except_flushpipe;
input [31:0] if_insn;
output [`BRANCHOP_WIDTH-1:0] branch_op;
output [`REGFILE_ADDR_WIDTH-1:0] rf_addrw;
output [`REGFILE_ADDR_WIDTH-1:0] rf_addra;
output [`REGFILE_ADDR_WIDTH-1:0] rf_addrb;
output [`ALUOP_WIDTH-1:0] alu_op;
output [`SHROTOP_WIDTH-1:0] shrot_op;
output [`RFWBOP_WIDTH-1:0] rfwb_op;
output [31:0] wb_insn;
output [31:0] simm;
output [31:2] branch_addrofs;
output [31:0] lsu_addrofs;
output [`SEL_WIDTH-1:0] sel_a;
output [`SEL_WIDTH-1:0] sel_b;
output [`LSUOP_WIDTH-1:0] lsu_op;
output [`COMPOP_WIDTH-1:0] comp_op;
output [`MULTICYCLE_WIDTH-1:0] multicycle;
output [15:0] spr_addrimm;
input wbforw_valid;
output sig_syscall;
output sig_trap;
output force_dslot_fetch;
output id_macrc_op;
output ex_macrc_op;
 
//
// Internal wires and regs
//
reg [`BRANCHOP_WIDTH-1:0] pre_branch_op;
reg [`BRANCHOP_WIDTH-1:0] branch_op;
reg [`ALUOP_WIDTH-1:0] alu_op;
reg [`SHROTOP_WIDTH-1:0] shrot_op;
reg [31:0] id_insn;
reg [31:0] ex_insn;
reg [31:0] wb_insn;
reg [`REGFILE_ADDR_WIDTH-1:0] rf_addrw;
reg [`REGFILE_ADDR_WIDTH-1:0] wb_rfaddrw;
reg [`RFWBOP_WIDTH-1:0] rfwb_op;
reg [31:0] lsu_addrofs;
reg [`SEL_WIDTH-1:0] sel_a;
reg [`SEL_WIDTH-1:0] sel_b;
reg sel_imm;
reg [`LSUOP_WIDTH-1:0] lsu_op;
reg [`COMPOP_WIDTH-1:0] comp_op;
reg [`MULTICYCLE_WIDTH-1:0] multicycle;
reg imm_signextend;
reg [15:0] spr_addrimm;
reg sig_syscall;
reg sig_trap;
wire rst_or_except_flushpipe;
reg ex_macrc_op;
 
//
// Register file read addresses
//
assign rf_addra = if_insn[20:16];
assign rf_addrb = if_insn[15:11];
 
//
// Force fetch of delay slot instruction when jump/branch is preceeded by load/store
// instructions
//
assign force_dslot_fetch = ((|pre_branch_op) & (|lsu_op));
 
//
// Sign/Zero extension of immediates
//
assign simm = (imm_signextend == `on) ? {{16{id_insn[15]}}, id_insn[15:0]} : {{16'b0}, id_insn[15:0]};
 
//
// Sign extension of branch offset
//
assign branch_addrofs = {{4{ex_insn[25]}}, ex_insn[25:0]};
 
//
// Async reset for most of pipeline flops
//
assign rst_or_except_flushpipe = rst | except_flushpipe;
 
//
// l.macrc in ID stage
//
assign id_macrc_op = (id_insn[31:26] == 6'b00_0110) & id_insn[16];
 
//
// Generation of sel_a
//
always @(rf_addrw or id_insn or rfwb_op or wbforw_valid or wb_rfaddrw)
if ((id_insn[20:16] == rf_addrw) && rfwb_op[0])
sel_a = `SEL_EX_FORW;
else if ((id_insn[20:16] == wb_rfaddrw) && wbforw_valid)
sel_a = `SEL_WB_FORW;
else
sel_a = `SEL_RF;
 
//
// Generation of sel_b
//
always @(rf_addrw or sel_imm or id_insn or rfwb_op or wbforw_valid or wb_rfaddrw)
if (sel_imm)
sel_b = `SEL_IMM;
else if ((id_insn[15:11] == rf_addrw) && rfwb_op[0])
sel_b = `SEL_EX_FORW;
else if ((id_insn[15:11] == wb_rfaddrw) && wbforw_valid)
sel_b = `SEL_WB_FORW;
else
sel_b = `SEL_RF;
 
//
// l.macrc in EX stage
//
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
ex_macrc_op <= #1 1'b0;
else if (!ex_freeze & id_freeze)
ex_macrc_op <= #1 1'b0;
else if (!ex_freeze)
ex_macrc_op <= #1 id_macrc_op;
end
 
//
// Decode of spr_addrimm
//
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
spr_addrimm <= #1 16'h0000;
else if (!ex_freeze & id_freeze)
spr_addrimm <= #1 16'h0000;
else if (!ex_freeze) begin
case (id_insn[31:26]) // synopsys full_case parallel_case
// l.mfspr
`OR32_MFSPR:
spr_addrimm <= #1 id_insn[15:0];
// l.mtspr
default:
spr_addrimm <= #1 {id_insn[25:21], id_insn[10:0]};
endcase
end
end
 
//
// Decode of multicycle
//
always @(id_insn) begin
case (id_insn[31:26]) // synopsys full_case parallel_case
 
// l.lwz
`OR32_LWZ:
multicycle = `TWO_CYCLES;
// l.lbz
`OR32_LBZ:
multicycle = `TWO_CYCLES;
// l.lbs
`OR32_LBS:
multicycle = `TWO_CYCLES;
// l.lhz
`OR32_LHZ:
multicycle = `TWO_CYCLES;
// l.lhs
`OR32_LHS:
multicycle = `TWO_CYCLES;
// l.sw
`OR32_SW:
multicycle = `TWO_CYCLES;
// l.sb
`OR32_SB:
multicycle = `TWO_CYCLES;
// l.sh
`OR32_SH:
multicycle = `TWO_CYCLES;
// ALU instructions except the one with immediate
`OR32_ALU:
multicycle = id_insn[`ALUMCYC_POS];
// Single cycle instructions
default: begin
multicycle = `ONE_CYCLE;
end
endcase
end
 
//
// Decode of imm_signextend
//
always @(id_insn) begin
case (id_insn[31:26]) // synopsys full_case parallel_case
 
// l.addi
`OR32_ADDI:
imm_signextend = `on;
 
// l.addic
`OR32_ADDIC:
imm_signextend = `on;
 
// l.xori
`OR32_XORI:
imm_signextend = `on;
 
// l.muli
`OR32_MULI:
imm_signextend = `on;
 
// l.maci
`OR32_MACI:
imm_signextend = `on;
 
// SFXX insns with immediate
`OR32_SFXXI:
imm_signextend = `on;
 
// Instructions with no or zero extended immediate
default: begin
imm_signextend = `off;
end
 
endcase
 
end
 
//
// LSU addr offset
//
always @(lsu_op or ex_insn) begin
lsu_addrofs[10:0] = ex_insn[10:0];
case(lsu_op) // synopsys parallel_case full_case
`LSUOP_SW, `LSUOP_SH, `LSUOP_SB :
lsu_addrofs[31:11] = {{16{ex_insn[25]}}, ex_insn[25:21]};
default :
lsu_addrofs[31:11] = {{16{ex_insn[15]}}, ex_insn[15:11]};
endcase
end
 
//
// Register file write address
//
always @(posedge clk or posedge rst) begin
if (rst)
rf_addrw <= #1 5'd0;
else if (!ex_freeze & id_freeze)
rf_addrw <= #1 5'd00;
else if (!ex_freeze)
case (pre_branch_op) // synopsys parallel_case full_case
`BRANCHOP_JR, `BRANCHOP_BAL:
rf_addrw <= #1 5'd09; // link register r9
default:
rf_addrw <= #1 id_insn[25:21];
endcase
end
 
//
// rf_addrw in wb stage (used in forwarding logic)
//
always @(posedge clk or posedge rst) begin
if (rst)
wb_rfaddrw <= #1 5'd0;
else if (!wb_freeze)
wb_rfaddrw <= #1 rf_addrw;
end
 
//
// Instruction latch in id_insn
//
always @(posedge clk or posedge rst) begin
if (rst) begin
id_insn[31:26] <= #1 `OR32_NOP;
id_insn[25:0] <= #1 26'd0;
end
else if (!id_freeze) begin
id_insn <= #1 if_insn;
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: id_insn <= %h", $time, if_insn);
// synopsys translate_on
`endif
end
end
 
//
// Instruction latch in ex_insn
//
always @(posedge clk or posedge rst) begin
if (rst) begin
ex_insn[31:26] <= #1 `OR32_NOP;
ex_insn[25:0] <= #1 26'd0;
end
else if (!ex_freeze & id_freeze)
ex_insn <= #1 {`OR32_NOP, 26'h000_4444};
else if (!ex_freeze) begin
ex_insn <= #1 id_insn;
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: ex_insn <= %h", $time, id_insn);
// synopsys translate_on
`endif
end
end
 
//
// Instruction latch in wb_insn
//
always @(posedge clk or posedge rst) begin
if (rst) begin
wb_insn[31:26] <= #1 `OR32_NOP;
wb_insn[25:0] <= #1 26'd0;
end
else if (!wb_freeze) begin
wb_insn <= #1 ex_insn;
end
end
 
//
// Decode of sel_imm
//
always @(posedge clk or posedge rst) begin
if (rst)
sel_imm <= #1 1'b0;
else if (!id_freeze) begin
case (if_insn[31:26]) // synopsys full_case parallel_case
 
// j.jalr
`OR32_JALR:
sel_imm <= #1 `off;
// l.jr
`OR32_JR:
sel_imm <= #1 `off;
// l.rfe
`OR32_RFE:
sel_imm <= #1 `off;
// l.mfspr
`OR32_MFSPR:
sel_imm <= #1 `off;
// l.mtspr
`OR32_MTSPR:
sel_imm <= #1 `off;
// l.sys, l.brk and all three sync insns
`OR32_XSYNC:
sel_imm <= #1 `off;
// l.sw
`OR32_SW:
sel_imm <= #1 `off;
// l.sb
`OR32_SB:
sel_imm <= #1 `off;
// l.sh
`OR32_SH:
sel_imm <= #1 `off;
// ALU instructions except the one with immediate
`OR32_ALU:
sel_imm <= #1 `off;
// SFXX instructions
`OR32_SFXX:
sel_imm <= #1 `off;
// l.nop
`OR32_NOP:
sel_imm <= #1 `off;
// All instructions with immediates
default: begin
sel_imm <= #1 `on;
end
endcase
end
end
 
 
//
// Decode of alu_op
//
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
alu_op <= #1 `ALUOP_NOP;
else if (!ex_freeze & id_freeze)
alu_op <= #1 `ALUOP_NOP;
else if (!ex_freeze) begin
case (id_insn[31:26]) // synopsys full_case parallel_case
// l.j
`OR32_J:
alu_op <= #1 `ALUOP_IMM;
// j.jal
`OR32_JAL:
alu_op <= #1 `ALUOP_IMM;
// j.jalr
`OR32_JALR:
alu_op <= #1 `ALUOP_OR;
// l.jr
`OR32_JR:
alu_op <= #1 `ALUOP_ADD;
// l.bnf
`OR32_BNF:
alu_op <= #1 `ALUOP_ADD;
// l.bf
`OR32_BF:
alu_op <= #1 `ALUOP_ADD;
// l.rfe
`OR32_RFE:
alu_op <= #1 `ALUOP_NOP;
// l.movhi
`OR32_MOVHI:
alu_op <= #1 `ALUOP_MOVHI;
// l.mfspr
`OR32_MFSPR:
alu_op <= #1 `ALUOP_MFSR;
// l.mtspr
`OR32_MTSPR:
alu_op <= #1 `ALUOP_MTSR;
// l.sys, l.brk and all three sync insns
`OR32_XSYNC:
alu_op <= #1 `ALUOP_NOP;
// l.lwz
`OR32_LWZ:
alu_op <= #1 `ALUOP_ADD;
// l.lbz
`OR32_LBZ:
alu_op <= #1 `ALUOP_ADD;
// l.lbs
`OR32_LBS:
alu_op <= #1 `ALUOP_ADD;
// l.lhz
`OR32_LHZ:
alu_op <= #1 `ALUOP_ADD;
// l.lhs
`OR32_LHS:
alu_op <= #1 `ALUOP_ADD;
// l.addi
`OR32_ADDI:
alu_op <= #1 `ALUOP_ADD;
// l.addic
`OR32_ADDIC:
alu_op <= #1 `ALUOP_ADD;
// l.andi
`OR32_ANDI:
alu_op <= #1 `ALUOP_AND;
// l.ori
`OR32_ORI:
alu_op <= #1 `ALUOP_OR;
// l.xori
`OR32_XORI:
alu_op <= #1 `ALUOP_XOR;
// l.muli
`OR32_MULI:
alu_op <= #1 `ALUOP_MUL;
// l.maci
`OR32_MACI:
alu_op <= #1 `ALUOP_MAC;
// Shift and rotate insns with immediate
`OR32_SH_ROTI:
alu_op <= #1 `ALUOP_SHROT;
// SFXX insns with immediate
`OR32_SFXXI:
alu_op <= #1 `ALUOP_COMP;
// l.sw
`OR32_SW:
alu_op <= #1 `ALUOP_ADD;
// l.sb
`OR32_SB:
alu_op <= #1 `ALUOP_ADD;
// l.sh
`OR32_SH:
alu_op <= #1 `ALUOP_ADD;
// ALU instructions except the one with immediate
`OR32_ALU:
alu_op <= #1 id_insn[3:0];
// SFXX instructions
`OR32_SFXX:
alu_op <= #1 `ALUOP_COMP;
// l.nop
`OR32_NOP:
alu_op <= #1 `ALUOP_NOP;
// Illegal and OR1200 unsupported instructions
default: begin
alu_op <= #1 `ALUOP_NOP;
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: Illegal insn.... insn %h", $time, id_insn);
// synopsys translate_on
`endif
end
endcase
end
end
 
//
// Decode of shrot_op
//
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
shrot_op <= #1 `SHROTOP_NOP;
else if (!ex_freeze & id_freeze)
shrot_op <= #1 `SHROTOP_NOP;
else if (!ex_freeze) begin
shrot_op <= #1 id_insn[`SHROTOP_POS];
end
end
 
//
// Decode of rfwb_op
//
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
rfwb_op <= #1 `RFWBOP_NOP;
else if (!ex_freeze & id_freeze)
rfwb_op <= #1 `RFWBOP_NOP;
else if (!ex_freeze) begin
case (id_insn[31:26]) // synopsys full_case parallel_case
 
// j.jal
`OR32_JAL:
rfwb_op <= #1 `RFWBOP_LR;
// j.jalr
`OR32_JALR:
rfwb_op <= #1 `RFWBOP_LR;
// l.movhi
`OR32_MOVHI:
rfwb_op <= #1 `RFWBOP_ALU;
// l.mfspr
`OR32_MFSPR:
rfwb_op <= #1 `RFWBOP_SPRS;
// l.lwz
`OR32_LWZ:
rfwb_op <= #1 `RFWBOP_LSU;
// l.lbz
`OR32_LBZ:
rfwb_op <= #1 `RFWBOP_LSU;
// l.lbs
`OR32_LBS:
rfwb_op <= #1 `RFWBOP_LSU;
// l.lhz
`OR32_LHZ:
rfwb_op <= #1 `RFWBOP_LSU;
// l.lhs
`OR32_LHS:
rfwb_op <= #1 `RFWBOP_LSU;
// l.addi
`OR32_ADDI:
rfwb_op <= #1 `RFWBOP_ALU;
// l.addic
`OR32_ADDIC:
rfwb_op <= #1 `RFWBOP_ALU;
// l.andi
`OR32_ANDI:
rfwb_op <= #1 `RFWBOP_ALU;
// l.ori
`OR32_ORI:
rfwb_op <= #1 `RFWBOP_ALU;
// l.xori
`OR32_XORI:
rfwb_op <= #1 `RFWBOP_ALU;
// l.muli
`OR32_MULI:
rfwb_op <= #1 `RFWBOP_ALU;
// l.maci
`OR32_MACI:
rfwb_op <= #1 `RFWBOP_ALU;
// Shift and rotate insns with immediate
`OR32_SH_ROTI:
rfwb_op <= #1 `RFWBOP_ALU;
// ALU instructions except the one with immediate
`OR32_ALU:
rfwb_op <= #1 `RFWBOP_ALU;
// Instructions w/o register-file write-back
default: begin
rfwb_op <= #1 `RFWBOP_NOP;
end
 
endcase
end
end
 
//
// Decode of pre_branch_op
//
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
pre_branch_op <= #1 `BRANCHOP_NOP;
else if (!id_freeze) begin
case (if_insn[31:26]) // synopsys full_case parallel_case
// l.j
`OR32_J:
pre_branch_op <= #1 `BRANCHOP_BAL;
// j.jal
`OR32_JAL:
pre_branch_op <= #1 `BRANCHOP_BAL;
// j.jalr
`OR32_JALR:
pre_branch_op <= #1 `BRANCHOP_JR;
// l.jr
`OR32_JR:
pre_branch_op <= #1 `BRANCHOP_JR;
// l.bnf
`OR32_BNF:
pre_branch_op <= #1 `BRANCHOP_BNF;
// l.bf
`OR32_BF:
pre_branch_op <= #1 `BRANCHOP_BF;
// l.rfe
`OR32_RFE:
pre_branch_op <= #1 `BRANCHOP_RFE;
// Non branch instructions
default: begin
pre_branch_op <= #1 `BRANCHOP_NOP;
end
endcase
end
end
 
//
// Generation of branch_op
//
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
branch_op <= #1 `BRANCHOP_NOP;
else if (!ex_freeze & id_freeze)
branch_op <= #1 `BRANCHOP_NOP;
else if (!ex_freeze) begin
branch_op <= #1 pre_branch_op;
end
end
 
//
// Decode of lsu_op
//
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
lsu_op <= #1 `LSUOP_NOP;
else if (!ex_freeze & id_freeze)
lsu_op <= #1 `LSUOP_NOP;
else if (!ex_freeze) begin
case (id_insn[31:26]) // synopsys full_case parallel_case
// l.lwz
`OR32_LWZ:
lsu_op <= #1 `LSUOP_LWZ;
// l.lbz
`OR32_LBZ:
lsu_op <= #1 `LSUOP_LBZ;
// l.lbs
`OR32_LBS:
lsu_op <= #1 `LSUOP_LBS;
// l.lhz
`OR32_LHZ:
lsu_op <= #1 `LSUOP_LHZ;
// l.lhs
`OR32_LHS:
lsu_op <= #1 `LSUOP_LHS;
// l.sw
`OR32_SW:
lsu_op <= #1 `LSUOP_SW;
// l.sb
`OR32_SB:
lsu_op <= #1 `LSUOP_SB;
// l.sh
`OR32_SH:
lsu_op <= #1 `LSUOP_SH;
// Non load/store instructions
default: begin
lsu_op <= #1 `LSUOP_NOP;
end
endcase
end
end
 
//
// Decode of comp_op
//
always @(posedge clk or posedge rst_or_except_flushpipe) begin
if (rst_or_except_flushpipe)
comp_op <= #1 4'd0;
else if (!ex_freeze & id_freeze)
comp_op <= #1 4'd0;
else if (!ex_freeze) begin
comp_op <= #1 id_insn[24:21];
end
end
 
//
// Decode of l.sys
//
always @(posedge clk or posedge rst) begin
if (rst)
sig_syscall <= #1 1'b0;
else if (!ex_freeze & id_freeze)
sig_syscall <= #1 1'b0;
else if (!ex_freeze) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
if (id_insn[31:23] == {`OR32_XSYNC, 3'b000})
$display("Generating sig_syscall");
// synopsys translate_on
`endif
sig_syscall <= #1 (id_insn[31:23] == {`OR32_XSYNC, 3'b000});
end
end
 
//
// Decode of l.trap
//
always @(posedge clk or posedge rst) begin
if (rst)
sig_trap <= #1 1'b0;
else if (!ex_freeze & id_freeze)
sig_trap <= #1 1'b0;
else if (!ex_freeze) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
if (id_insn[31:23] == {`OR32_XSYNC, 3'b010})
$display("Generating sig_trap");
// synopsys translate_on
`endif
sig_trap <= #1 (id_insn[31:23] == {`OR32_XSYNC, 3'b010});
end
end
 
endmodule
/verilog/or1200.xcv/mem2reg.v
0,0 → 1,296
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's mem2reg alignment ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Two versions of Memory to register data alignment. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module mem2reg(addr, lsu_op, memdata, regdata);
 
parameter width = `OPERAND_WIDTH;
 
//
// I/O
//
input [1:0] addr;
input [`LSUOP_WIDTH-1:0] lsu_op;
input [width-1:0] memdata;
output [width-1:0] regdata;
 
 
//
// Faster implementation of mem2reg
//
`ifdef MEM2REG_FAST
 
`define SEL_00 2'b00
`define SEL_01 2'b01
`define SEL_10 2'b10
`define SEL_11 2'b11
 
reg [width-1:0] regdata;
reg [width-1:0] aligned;
reg [1:0] sel_byte0, sel_byte1,
sel_byte2, sel_byte3;
 
//
// Byte select 0
//
always @(addr or lsu_op) begin
casex({lsu_op[2:0], addr})
{3'b01x, 2'b00}:
sel_byte0 = `SEL_11;
{3'b01x, 2'b01}:
sel_byte0 = `SEL_10;
{3'b01x, 2'b10}:
sel_byte0 = `SEL_01;
{3'b01x, 2'b11}:
sel_byte0 = `SEL_00;
{3'b10x, 2'b00}:
sel_byte0 = `SEL_10;
{3'b10x, 2'b10}:
sel_byte0 = `SEL_00;
default:
sel_byte0 = `SEL_00;
endcase
end
 
//
// Byte select 1
//
always @(addr or lsu_op) begin
casex({lsu_op[2:0], addr})
{3'b010, 2'bxx}:
sel_byte1 = `SEL_00; // zero extend
{3'b011, 2'bxx}:
sel_byte1 = `SEL_10; // sign extend byte
{3'b10x, 2'b00}:
sel_byte1 = `SEL_11;
default:
sel_byte1 = `SEL_01;
endcase
end
 
//
// Byte select 2
//
always @(addr or lsu_op) begin
casex({lsu_op[2:0], addr})
{3'b010, 2'bxx},
{3'b100, 2'bxx}:
sel_byte2 = `SEL_00; // zero extend
{3'b011, 2'bxx}:
sel_byte2 = `SEL_01; // sign extend byte
{3'b101, 2'bxx}:
sel_byte2 = `SEL_11; // sign extend halfword
default:
sel_byte2 = `SEL_10;
endcase
end
 
//
// Byte select 3
//
always @(addr or lsu_op) begin
casex({lsu_op[2:0], addr})
{3'b010, 2'bxx},
{3'b100, 2'bxx}:
sel_byte3 = `SEL_00; // zero extend
{3'b011, 2'bxx}:
sel_byte3 = `SEL_01; // sign extend byte
{3'b101, 2'bxx}:
sel_byte3 = `SEL_10; // sign extend halfword
default:
sel_byte3 = `SEL_11;
endcase
end
 
//
// Byte 0
//
always @(sel_byte0 or memdata) begin
case(sel_byte0) // synopsys full_case parallel_case infer_mux
`SEL_00: begin
regdata[7:0] = memdata[7:0];
end
`SEL_01: begin
regdata[7:0] = memdata[15:8];
end
`SEL_10: begin
regdata[7:0] = memdata[23:16];
end
`SEL_11: begin
regdata[7:0] = memdata[31:24];
end
endcase
end
 
//
// Byte 1
//
always @(sel_byte1 or memdata) begin
case(sel_byte1) // synopsys full_case parallel_case infer_mux
`SEL_00: begin
regdata[15:8] = 8'b0;
end
`SEL_01: begin
regdata[15:8] = memdata[15:8];
end
`SEL_10: begin
regdata[15:8] = {8{memdata[7]}};
end
`SEL_11: begin
regdata[15:8] = memdata[31:24];
end
endcase
end
 
//
// Byte 2
//
always @(sel_byte2 or memdata) begin
case(sel_byte2) // synopsys full_case parallel_case infer_mux
`SEL_00: begin
regdata[23:16] = 8'b0;
end
`SEL_01: begin
regdata[23:16] = {8{memdata[7]}};
end
`SEL_10: begin
regdata[23:16] = memdata[23:16];
end
`SEL_11: begin
regdata[23:16] = {8{memdata[15]}};
end
endcase
end
 
//
// Byte 3
//
always @(sel_byte3 or memdata) begin
case(sel_byte3) // synopsys full_case parallel_case infer_mux
`SEL_00: begin
regdata[31:24] = 8'b0;
end
`SEL_01: begin
regdata[31:24] = {8{memdata[7]}};
end
`SEL_10: begin
regdata[31:24] = {8{memdata[15]}};
end
`SEL_11: begin
regdata[31:24] = memdata[31:24];
end
endcase
end
 
`else
 
//
// Slow implementation of mem2reg
//
 
reg [width-1:0] regdata;
reg [width-1:0] aligned;
 
//
// Alignment
//
always @(addr or memdata) begin
case(addr) // synopsys infer_mux
2'b00:
aligned = memdata;
2'b01:
aligned = {memdata[23:0], 8'b0};
2'b10:
aligned = {memdata[15:0], 16'b0};
2'b11:
aligned = {memdata[7:0], 24'b0};
endcase
end
 
//
// Bytes
//
always @(lsu_op or aligned) begin
case(lsu_op) // synopsys infer_mux
`LSUOP_LBZ: begin
regdata[7:0] = aligned[31:24];
regdata[31:8] = 24'b0;
end
`LSUOP_LBS: begin
regdata[7:0] = aligned[31:24];
regdata[31:8] = {24{aligned[31]}};
end
`LSUOP_LHZ: begin
regdata[15:0] = aligned[31:16];
regdata[31:16] = 16'b0;
end
`LSUOP_LHS: begin
regdata[15:0] = aligned[31:16];
regdata[31:16] = {16{aligned[31]}};
end
default:
regdata = aligned;
endcase
end
 
`endif
 
endmodule
/verilog/or1200.xcv/reg2mem.v
0,0 → 1,117
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's reg2mem aligner ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Aligns register data to memory alignment. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:21 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module reg2mem(addr, lsu_op, regdata, memdata);
 
parameter width = `OPERAND_WIDTH;
 
//
// I/O
//
input [1:0] addr;
input [`LSUOP_WIDTH-1:0] lsu_op;
input [width-1:0] regdata;
output [width-1:0] memdata;
 
//
// Internal regs and wires
//
reg [width-1:0] memdata;
 
//
// Mux to memdata[31:24]
//
always @(lsu_op or addr or regdata) begin
casex({lsu_op, addr[1:0]}) // synopsys full_case parallel_case
{`LSUOP_SB, 2'b00} : memdata[31:24] = regdata[7:0];
{`LSUOP_SH, 2'b00} : memdata[31:24] = regdata[15:8];
default : memdata[31:24] = regdata[31:24];
endcase
end
 
//
// Mux to memdata[23:16]
//
always @(lsu_op or addr or regdata) begin
casex({lsu_op, addr[1:0]}) // synopsys full_case parallel_case
{`LSUOP_SW, 2'b00} : memdata[23:16] = regdata[23:16];
default : memdata[23:16] = regdata[7:0];
endcase
end
 
//
// Mux to memdata[15:8]
//
always @(lsu_op or addr or regdata) begin
casex({lsu_op, addr[1:0]}) // synopsys full_case parallel_case
{`LSUOP_SB, 2'b10} : memdata[15:8] = regdata[7:0];
default : memdata[15:8] = regdata[15:8];
endcase
end
 
//
// Mux to memdata[7:0]
//
always @(regdata)
memdata[7:0] = regdata[7:0];
 
endmodule
/verilog/or1200.xcv/mult_mac.v
0,0 → 1,162
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Top level multiplier and MAC ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Multiplier is 32x32 however multiply instructions only ////
//// use lower 32 bits of the result. MAC is 32x32=64+64. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:38 igorm
// no message
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module mult_mac(clk, rst, id_macrc_op, macrc_op, a, b, alu_op, result, mac_stall_r);
 
parameter width = `OPERAND_WIDTH;
 
//
// I/O
//
input clk;
input rst;
input id_macrc_op;
input macrc_op;
input [width-1:0] a;
input [width-1:0] b;
input [`ALUOP_WIDTH-1:0] alu_op;
output [width-1:0] result;
output mac_stall_r;
 
//
// Internal wires and regs
//
wire [width-1:0] result;
reg [2*width-1:0] mul_prod_r;
reg [2*width-1:0] mac_r;
wire [2*width-1:0] mul_prod;
wire mac_op;
reg mac_op_r1;
reg mac_op_r2;
reg mac_op_r3;
reg mac_stall_r;
 
//
// Combinatorial logic
//
assign result = (alu_op == `ALUOP_MUL) ? mul_prod_r[31:0] : mac_r[59:28];
assign mac_op = (alu_op == `ALUOP_MAC);
 
//
// Instantiation of the multiplier
//
multp2_32x32 multp2_32x32(
.X(a),
.Y(b),
.RST(rst),
.CLK(clk),
.P(mul_prod)
);
 
//
// Registered output from the multiplier
//
always @(posedge rst or posedge clk)
if (rst)
mul_prod_r <= #1 64'h0000_0000_0000_0000;
else
mul_prod_r <= #1 mul_prod[63:0];
 
//
// Propagation of l.mac opcode
//
always @(posedge clk or posedge rst)
if (rst)
mac_op_r1 <= #1 1'b0;
else
mac_op_r1 <= #1 mac_op;
 
//
// Propagation of l.mac opcode
//
always @(posedge clk or posedge rst)
if (rst)
mac_op_r2 <= #1 1'b0;
else
mac_op_r2 <= #1 mac_op_r1;
 
//
// Propagation of l.mac opcode
//
always @(posedge clk or posedge rst)
if (rst)
mac_op_r3 <= #1 1'b0;
else
mac_op_r3 <= #1 mac_op_r2;
 
//
// Implementation of MAC
//
always @(posedge rst or posedge clk)
if (rst)
mac_r <= #1 64'h0000_0000_0000_0000;
else if (mac_op_r3)
mac_r <= #1 mac_r + mul_prod_r;
else if (macrc_op)
mac_r <= #1 64'h0000_0000_0000_0000;
 
//
// Stall CPU if l.macrc is in ID and MAC still has to process l.mac instructions
// in EX stage (e.g. inside multiplier)
//
always @(posedge rst or posedge clk)
if (rst)
mac_stall_r <= #1 1'b0;
else
mac_stall_r <= #1 (mac_op | mac_op_r1 | mac_op_r2) & id_macrc_op;
 
endmodule
/verilog/or1200.xcv/lsu.v
0,0 → 1,115
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Load/Store unit ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Interface between CPU and DC. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module lsu(
// Clock and reset
clk, rst,
 
// Internal i/f
addrbase, addrofs, lsu_op, lsu_datain, lsu_dataout, lsu_stall,
 
// External i/f to DC
dc_stall, dc_addr, dc_datain, dc_dataout, dc_lsuop
);
 
parameter dw = `OPERAND_WIDTH;
parameter aw = `REGFILE_ADDR_WIDTH;
 
//
// I/O
//
 
//
// Clock and reset
//
input clk;
input rst;
 
//
// Internal i/f
//
input [31:0] addrbase;
input [31:0] addrofs;
input [`LSUOP_WIDTH-1:0] lsu_op;
input [dw-1:0] lsu_datain;
output [dw-1:0] lsu_dataout;
output lsu_stall;
 
//
// External i/f to DC
//
input dc_stall;
output [31:0] dc_addr;
input [dw-1:0] dc_datain;
output [dw-1:0] dc_dataout;
output [`LSUOP_WIDTH-1:0] dc_lsuop;
 
//
// Not much of a LSU right now
//
assign dc_addr = addrbase + addrofs;
assign dc_dataout = lsu_datain;
assign lsu_dataout = dc_datain;
assign lsu_stall = dc_stall;
assign dc_lsuop = lsu_op;
 
endmodule
/verilog/or1200.xcv/immu.v
0,0 → 1,231
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Insn MMU top level ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Instantiation of all IMMU blocks. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.1 2001/08/17 08:03:35 lampret
// *** empty log message ***
//
// Revision 1.2 2001/07/22 03:31:53 lampret
// Fixed RAM's oen bug. Cache bypass under development.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
//
// Insn MMU
//
 
module immu(
// Rst and clk
clk, rst,
 
// Fetch i/f
immu_en, supv, immufetch_vaddr, immufetch_op, immufetch_stall,
 
// Except I/F
immuexcept_miss, immuexcept_fault,
 
// SPR access
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o,
 
// IC i/f
icimmu_paddr
);
 
parameter dw = `OPERAND_WIDTH;
parameter aw = `OPERAND_WIDTH;
 
//
// I/O
//
 
//
// Clock and reset
//
input clk;
input rst;
 
//
// FETCH I/F
//
input immu_en;
input supv;
input [aw-1:0] immufetch_vaddr;
input immufetch_op;
output immufetch_stall;
 
//
// Exception I/F
//
output immuexcept_miss;
output immuexcept_fault;
 
//
// SPR access
//
input spr_cs;
input spr_write;
input [aw-1:0] spr_addr;
input [31:0] spr_dat_i;
output [31:0] spr_dat_o;
 
//
// IC I/F
//
output [aw-1:0] icimmu_paddr;
 
//
// Internal wires and regs
//
wire itlb_spr_access;
wire [31:13] itlb_ppn;
wire itlb_hit;
wire itlb_uxe;
wire itlb_sxe;
wire [31:0] itlb_dat_o;
 
//
// Implemented bits inside match and translate registers
//
// itlbwYmrX: vpn 31-10 v 0
// itlbwYtrX: ppn 31-10 uxe 7 sxe 6
//
// itlb memory width:
// 19 bits for ppn
// 13 bits for vpn
// 1 bit for valid
// 2 bits for protection
 
`ifdef OR1200_NO_IMMU
 
//
// Put all outputs in inactive state
//
assign immufetch_stall = 1'b0;
assign immuexcept_miss = 1'b0;
assign immuexcept_fault = 1'b0;
assign spr_dat_o = 32'h00000000;
assign icimmu_paddr = immufetch_vaddr;
 
`else
 
//
// ITLB SPR access
//
// 1400 - 1600 itlbmr w0-3
// 1400 - 1480 itlbmr w0
// 1400 - 1440 itlbmr w0 [63:0]
//
// 1600 - 1800 itlbtr w0-3
// 1600 - 1680 itlbtr w0
// 1600 - 1640 itlbtr w0 [63:0]
//
assign itlb_spr_access = spr_cs & spr_addr[10];
 
//
// Physical address is either translated virtual address or
// simply equal when IMMU is disabled
//
assign icimmu_paddr = immu_en ? {itlb_ppn, immufetch_vaddr[12:0]} : immufetch_vaddr;
 
//
// Output to SPRS unit
//
assign spr_dat_o = itlb_spr_access ? itlb_dat_o : 32'h00000000;
 
//
// IMMU stall
//
assign immufetch_stall = 1'b0;
 
//
// Page fault exception logic
//
assign immuexcept_fault = immu_en &&
( (immufetch_op & !supv & !itlb_uxe) // Fetch in user mode not enabled
|| (immufetch_op & supv & !itlb_sxe) ); // Fetch in supv mode not enabled
 
//
// TLB Miss exception logic
//
assign immuexcept_miss = immufetch_op && immu_en && !itlb_hit;
 
//
// Instantiation of ITLB
//
itlb itlb(
// Rst and clk
.clk(clk),
.rst(rst),
 
// I/F for translation
.tlb_en(immu_en),
.vaddr(immufetch_vaddr),
.hit(itlb_hit),
.ppn(itlb_ppn),
.uxe(itlb_uxe),
.sxe(itlb_sxe),
 
// SPR access
.spr_cs(itlb_spr_access),
.spr_write(spr_write),
.spr_addr(spr_addr),
.spr_dat_i(spr_dat_i),
.spr_dat_o(itlb_dat_o)
);
 
`endif
 
endmodule
/verilog/or1200.xcv/generic_spram_512x19.v
0,0 → 1,294
//////////////////////////////////////////////////////////////////////
//// ////
//// Generic Single-Port Synchronous RAM ////
//// ////
//// This file is part of memory library available from ////
//// http://www.opencores.org/cvsweb.shtml/generic_memories/ ////
//// ////
//// Description ////
//// This block is a wrapper with common single-port ////
//// synchronous memory interface for different ////
//// types of ASIC and FPGA RAMs. Beside universal memory ////
//// interface it also provides behavioral model of generic ////
//// single-port synchronous RAM. ////
//// It should be used in all OPENCORES designs that want to be ////
//// portable accross different target technologies and ////
//// independent of target memory. ////
//// ////
//// Supported ASIC RAMs are: ////
//// - Artisan Single-Port Sync RAM ////
//// - Avant! Two-Port Sync RAM (*) ////
//// - Virage Single-Port Sync RAM ////
//// - Virtual Silicon Single-Port Sync RAM ////
//// ////
//// Supported FPGA RAMs are: ////
//// - Xilinx Virtex RAMB4_S16 ////
//// ////
//// To Do: ////
//// - xilinx rams need external tri-state logic ////
//// - fix avant! two-port ram ////
//// - add additional RAMs (Altera etc) ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.1 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/30 05:38:02 lampret
// Adding empty directories required by HDL coding guidelines
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module generic_spram_512x19(
// Generic synchronous single-port RAM interface
clk, rst, ce, we, oe, addr, di, do
);
 
//
// Default address and data buses width
//
parameter aw = 9;
parameter dw = 19;
 
//
// Generic synchronous single-port RAM interface
//
input clk; // Clock
input rst; // Reset
input ce; // Chip enable input
input we; // Write enable input
input oe; // Output enable input
input [aw-1:0] addr; // address bus inputs
input [dw-1:0] di; // input data bus
output [dw-1:0] do; // output data bus
 
//
// Internal wires and registers
//
 
 
`ifdef ARTISAN_SSP
 
//
// Instantiation of ASIC memory:
//
// Artisan Synchronous Single-Port RAM (ra1sh)
//
art_hssp_512x19 #(dw, 1<<aw, aw) artisan_ssp(
.clk(clk),
.cen(~ce),
.wen(~we),
.a(addr),
.d(di),
.oen(~oe),
.q(do)
);
 
`else
 
`ifdef AVANT_ATP
 
//
// Instantiation of ASIC memory:
//
// Avant! Asynchronous Two-Port RAM
//
avant_atp avant_atp(
.web(~we),
.reb(),
.oeb(~oe),
.rcsb(),
.wcsb(),
.ra(addr),
.wa(addr),
.di(di),
.do(do)
);
 
`else
 
`ifdef VIRAGE_SSP
 
//
// Instantiation of ASIC memory:
//
// Virage Synchronous 1-port R/W RAM
//
virage_ssp virage_ssp(
.clk(clk),
.adr(addr),
.d(di),
.we(we),
.oe(oe),
.me(ce),
.q(do)
);
 
`else
 
`ifdef VIRTUALSILICON_SSP
 
//
// Instantiation of ASIC memory:
//
// Virtual Silicon Single-Port Synchronous SRAM
//
virtualsilicon_ssp #(1<<aw, aw-1, dw-1) virtualsilicon_ssp(
.CK(clk),
.ADR(addr),
.DI(di),
.WEN(~we),
.CEN(~ce),
.OEN(~oe),
.DOUT(do)
);
 
`else
 
`ifdef XILINX_RAMB4
 
//
// Instantiation of FPGA memory:
//
// Virtex/Spartan2
//
 
//
// Block 0
//
RAMB4_S4 ramb4_s4_0(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[3:0]),
.EN(ce),
.WE(we),
.DO(do[3:0])
);
 
//
// Block 1
//
RAMB4_S4 ramb4_s4_1(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[7:4]),
.EN(ce),
.WE(we),
.DO(do[7:4])
);
 
//
// Block 2
//
RAMB4_S4 ramb4_s4_2(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[11:8]),
.EN(ce),
.WE(we),
.DO(do[11:8])
);
 
wire x;
 
//
// Block 3
//
RAMB4_S4 ramb4_s4_3(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[15:12]),
.EN(ce),
.WE(we),
.DO(do[15:12])
);
 
//
// Block 4
//
RAMB4_S4 ramb4_s4_4(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI({1'b0, di[18:16]}),
.EN(ce),
.WE(we),
.DO({x, do[18:16]})
);
 
`else
 
//
// Generic single-port synchronous RAM model
//
 
//
// Generic RAM's registers and wires
//
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
reg [dw-1:0] do_reg; // RAM data output register
 
//
// Data output drivers
//
assign do = (oe) ? do_reg : {dw{1'bz}};
 
//
// RAM read and write
//
always @(posedge clk)
if (ce && !we)
do_reg <= #1 mem[addr];
else if (ce && we)
mem[addr] <= #1 di;
 
`endif // !XILINX_RAMB4_S16
`endif // !VIRTUALSILICON_SSP
`endif // !VIRAGE_SSP
`endif // !AVANT_ATP
`endif // !ARTISAN_SSP
 
endmodule
/verilog/or1200.xcv/operandmuxes.v
0,0 → 1,149
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's register file read operands mux ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Mux for two register file read operands. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:05 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module operandmuxes(
// Clock and reset
clk, rst,
 
// Internal i/f
ex_freeze, rf_dataa, rf_datab, ex_forw, wb_forw,
simm, sel_a, sel_b, operand_a, operand_b, muxed_b
);
 
parameter width = `OPERAND_WIDTH;
 
//
// I/O
//
input clk;
input rst;
input ex_freeze;
input [width-1:0] rf_dataa;
input [width-1:0] rf_datab;
input [width-1:0] ex_forw;
input [width-1:0] wb_forw;
input [width-1:0] simm;
input [`SEL_WIDTH-1:0] sel_a;
input [`SEL_WIDTH-1:0] sel_b;
output [width-1:0] operand_a;
output [width-1:0] operand_b;
output [width-1:0] muxed_b;
 
//
// Internal wires and regs
//
reg [width-1:0] operand_a;
reg [width-1:0] operand_b;
reg [width-1:0] muxed_a;
reg [width-1:0] muxed_b;
 
//
// Operand A register
//
always @(posedge clk or posedge rst) begin
if (rst)
operand_a <= #1 32'd0;
else if (!ex_freeze)
operand_a <= #1 muxed_a;
end
 
//
// Operand B register
//
always @(posedge clk or posedge rst) begin
if (rst)
operand_b <= #1 32'd0;
else if (!ex_freeze)
operand_b <= #1 muxed_b;
end
 
//
// Forwarding logic for operand A register
//
always @(ex_forw or wb_forw or rf_dataa or sel_a) begin
casex (sel_a) // synopsys full_case parallel_case infer_mux
`SEL_EX_FORW:
muxed_a = ex_forw;
`SEL_WB_FORW:
muxed_a = wb_forw;
default:
muxed_a = rf_dataa;
endcase
end
 
//
// Forwarding logic for operand B register
//
always @(simm or ex_forw or wb_forw or rf_datab or sel_b) begin
casex (sel_b) // synopsys full_case parallel_case infer_mux
`SEL_IMM:
muxed_b = simm;
`SEL_EX_FORW:
muxed_b = ex_forw;
`SEL_WB_FORW:
muxed_b = wb_forw;
default:
muxed_b = rf_datab;
endcase
end
 
endmodule
/verilog/or1200.xcv/generic_spram_2048x8.v
0,0 → 1,279
//////////////////////////////////////////////////////////////////////
//// ////
//// Generic Single-Port Synchronous RAM ////
//// ////
//// This file is part of memory library available from ////
//// http://www.opencores.org/cvsweb.shtml/generic_memories/ ////
//// ////
//// Description ////
//// This block is a wrapper with common single-port ////
//// synchronous memory interface for different ////
//// types of ASIC and FPGA RAMs. Beside universal memory ////
//// interface it also provides behavioral model of generic ////
//// single-port synchronous RAM. ////
//// It should be used in all OPENCORES designs that want to be ////
//// portable accross different target technologies and ////
//// independent of target memory. ////
//// ////
//// Supported ASIC RAMs are: ////
//// - Artisan Single-Port Sync RAM ////
//// - Avant! Two-Port Sync RAM (*) ////
//// - Virage Single-Port Sync RAM ////
//// - Virtual Silicon Single-Port Sync RAM ////
//// ////
//// Supported FPGA RAMs are: ////
//// - Xilinx Virtex RAMB4_S16 ////
//// ////
//// To Do: ////
//// - xilinx rams need external tri-state logic ////
//// - fix avant! two-port ram ////
//// - add additional RAMs (Altera etc) ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.1 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/30 05:38:02 lampret
// Adding empty directories required by HDL coding guidelines
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module generic_spram_2048x8(
// Generic synchronous single-port RAM interface
clk, rst, ce, we, oe, addr, di, do
);
 
//
// Default address and data buses width
//
parameter aw = 11;
parameter dw = 8;
 
//
// Generic synchronous single-port RAM interface
//
input clk; // Clock
input rst; // Reset
input ce; // Chip enable input
input we; // Write enable input
input oe; // Output enable input
input [aw-1:0] addr; // address bus inputs
input [dw-1:0] di; // input data bus
output [dw-1:0] do; // output data bus
 
//
// Internal wires and registers
//
 
 
`ifdef ARTISAN_SSP
 
//
// Instantiation of ASIC memory:
//
// Artisan Synchronous Single-Port RAM (ra1sh)
//
art_hssp_2048x8 #(dw, 1<<aw, aw) artisan_ssp(
.clk(clk),
.cen(~ce),
.wen(~we),
.a(addr),
.d(di),
.oen(~oe),
.q(do)
);
 
`else
 
`ifdef AVANT_ATP
 
//
// Instantiation of ASIC memory:
//
// Avant! Asynchronous Two-Port RAM
//
avant_atp avant_atp(
.web(~we),
.reb(),
.oeb(~oe),
.rcsb(),
.wcsb(),
.ra(addr),
.wa(addr),
.di(di),
.do(do)
);
 
`else
 
`ifdef VIRAGE_SSP
 
//
// Instantiation of ASIC memory:
//
// Virage Synchronous 1-port R/W RAM
//
virage_ssp virage_ssp(
.clk(clk),
.adr(addr),
.d(di),
.we(we),
.oe(oe),
.me(ce),
.q(do)
);
 
`else
 
`ifdef VIRTUALSILICON_SSP
 
//
// Instantiation of ASIC memory:
//
// Virtual Silicon Single-Port Synchronous SRAM
//
virtualsilicon_ssp #(1<<aw, aw-1, dw-1) virtualsilicon_ssp(
.CK(clk),
.ADR(addr),
.DI(di),
.WEN(~we),
.CEN(~ce),
.OEN(~oe),
.DOUT(do)
);
 
`else
 
`ifdef XILINX_RAMB4
 
//
// Instantiation of FPGA memory:
//
// Virtex/Spartan2
//
 
//
// Block 0
//
RAMB4_S2 ramb4_s2_0(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[1:0]),
.EN(ce),
.WE(we),
.DO(do[1:0])
);
 
//
// Block 1
//
RAMB4_S2 ramb4_s2_1(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[3:2]),
.EN(ce),
.WE(we),
.DO(do[3:2])
);
 
//
// Block 2
//
RAMB4_S2 ramb4_s2_2(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[5:4]),
.EN(ce),
.WE(we),
.DO(do[5:4])
);
 
//
// Block 3
//
RAMB4_S2 ramb4_s2_3(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[7:6]),
.EN(ce),
.WE(we),
.DO(do[7:6])
);
 
`else
 
//
// Generic single-port synchronous RAM model
//
 
//
// Generic RAM's registers and wires
//
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
reg [dw-1:0] do_reg; // RAM data output register
 
//
// Data output drivers
//
assign do = (oe) ? do_reg : {dw{1'bz}};
 
//
// RAM read and write
//
always @(posedge clk)
if (ce && !we)
do_reg <= #1 mem[addr];
else if (ce && we)
mem[addr] <= #1 di;
 
`endif // !XILINX_RAMB4_S16
`endif // !VIRTUALSILICON_SSP
`endif // !VIRAGE_SSP
`endif // !AVANT_ATP
`endif // !ARTISAN_SSP
 
endmodule
/verilog/or1200.xcv/defines.v
0,0 → 1,658
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's definitions ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Parameters of the OR1200 core ////
//// ////
//// To Do: ////
//// - add parameters that are missing ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.3 2001/08/17 08:01:19 lampret
// IC enable/disable.
//
// Revision 1.2 2001/08/13 03:36:20 lampret
// Added cfg regs. Moved all defines into one defines.v file. More cleanup.
//
// Revision 1.1 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/22 03:31:54 lampret
// Fixed RAM's oen bug. Cache bypass under development.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
`define XILINX_RAMB4
//`define XILINX_RAM32X1D
//`define ARTISAN_SSP
//`define ARTISAN_SDP
//`define ARTISAN_STP
 
// Dump VCD
`define VCD_DUMP
 
// Verbose
//`define OR1200_VERBOSE
 
//
// Data cache not implemented
//
`define OR1200_NO_DC
 
//
// Insn cache not implemented
//
`define OR1200_NO_IC
 
//
// Data MMU not implemented
//
`define OR1200_NO_DMMU
 
//
// Insn MMU not implemented
//
`define OR1200_NO_IMMU
 
//
// Register OR1200 outputs
//
//`define OR1200_REGISTERED_OUTPUTS
 
//
// Implement rotate in the ALU
//
`define IMPL_ALU_ROTATE
 
//
// Which type of compare to implement
//
//`define IMPL_ALU_COMP1
`define IMPL_ALU_COMP2
 
//
// Simulate l.div and l.divu
//
`define SIM_ALU_DIV
`define SIM_ALU_DIVU
 
`define ALUOP_NOP 4'd0
 
/* Order defined by arith insns that have two source operands both in regs
(see binutils/include/opcode/or32.h) */
`define ALUOP_ADD 4'd0
`define ALUOP_ADDC 4'd1
`define ALUOP_SUB 4'd2
`define ALUOP_AND 4'd3
`define ALUOP_OR 4'd4
`define ALUOP_XOR 4'd5
`define ALUOP_MUL 4'd6
`define ALUOP_MAC 4'd7
`define ALUOP_SHROT 4'd8
`define ALUOP_DIV 4'd9
`define ALUOP_DIVU 4'd10
 
/* Order not specifically defined. */
`define ALUOP_IMM 4'd11
`define ALUOP_MOVHI 4'd12
`define ALUOP_COMP 4'd13
`define ALUOP_MTSR 4'd14
`define ALUOP_MFSR 4'd15
 
`define ALUOP_WIDTH 4
 
/* Shift/rotate macros. */
`define SHROTOP_NOP 2'd0
`define SHROTOP_SLL 2'd0
`define SHROTOP_SRL 2'd1
`define SHROTOP_SRA 2'd2
`define SHROTOP_ROR 2'd3
 
`define SHROTOP_WIDTH 2
 
 
// 3 for 8 bytes, 4 for 16 bytes etc
`define IC_LINESIZE 4
 
// Insn cache specific
`define ICSIZE 13 // 8192
`define ICINDX `ICSIZE-2 // 11
`define ICINDXH `ICSIZE-1 // 12
`define ICTAGL `ICINDXH+1 // 13
 
`define OPERAND_WIDTH 32
`define REGFILE_ADDR_WIDTH 5
`define off 1'b0
`define on 1'b1
 
// Use fast (and bigger) version of mem2reg aligner
`define MEM2REG_FAST
 
// SHROT_OP position in machine word
`define SHROTOP_POS 7:6
 
// ALU instructions multicycle field in machine word
`define ALUMCYC_POS 9:8
 
// Execution cycles per instruction
`define MULTICYCLE_WIDTH 2
`define ONE_CYCLE 2'd0
`define TWO_CYCLES 2'd1
 
// Operand MUX selects
`define SEL_WIDTH 2
`define SEL_RF 2'd0
`define SEL_IMM 2'd1
`define SEL_EX_FORW 2'd2
`define SEL_WB_FORW 2'd3
 
// Branch ops
`define BRANCHOP_WIDTH 3
`define BRANCHOP_NOP 3'd0
`define BRANCHOP_J 3'd1
`define BRANCHOP_JR 3'd2
`define BRANCHOP_BAL 3'd3
`define BRANCHOP_BF 3'd4
`define BRANCHOP_BNF 3'd5
`define BRANCHOP_RFE 3'd6
 
// Bit 0: sign extend
// Bits 1-2: 00 doubleword, 01 byte, 10 halfword, 11 singleword
// Bit 3: 0 load, 1 store
`define LSUOP_WIDTH 4
`define LSUOP_NOP 4'b0000
`define LSUOP_LBZ 4'b0010
`define LSUOP_LBS 4'b0011
`define LSUOP_LHZ 4'b0100
`define LSUOP_LHS 4'b0101
`define LSUOP_LWZ 4'b0110
`define LSUOP_LWS 4'b0111
`define LSUOP_LD 4'b0001
`define LSUOP_SD 4'b1000
`define LSUOP_SB 4'b1010
`define LSUOP_SH 4'b1100
`define LSUOP_SW 4'b1110
 
// Fetch ops
`define FETCHOP_WIDTH 1
`define FETCHOP_NOP 1'b0
`define FETCHOP_LW 1'b1
 
// Bit 0: register file write enable
// Bits 2-1: write-back mux selects
`define RFWBOP_WIDTH 3
`define RFWBOP_NOP 3'b000
`define RFWBOP_ALU 3'b001
`define RFWBOP_LSU 3'b011
`define RFWBOP_SPRS 3'b101
`define RFWBOP_LR 3'b111
 
// Compare instructions
`define COP_SFEQ 3'b000
`define COP_SFNE 3'b001
`define COP_SFGT 3'b010
`define COP_SFGE 3'b011
`define COP_SFLT 3'b100
`define COP_SFLE 3'b101
`define COP_X 3'b0111
`define SIGNED_COMPARE 'd3
`define COMPOP_WIDTH 4
 
`define PAGEINDX_WIDTH 13
`define ITLBADDR_WIDTH 7
 
// Exceptions
`define EXCEPT_WIDTH 4
 
`define EXCEPT_UNUSED `EXCEPT_WIDTH'hf
`define EXCEPT_TRAP `EXCEPT_WIDTH'he
`define EXCEPT_BREAK `EXCEPT_WIDTH'hd
`define EXCEPT_SYSCALL `EXCEPT_WIDTH'hc
`define EXCEPT_RANGE `EXCEPT_WIDTH'hb
`define EXCEPT_ITLBMISS `EXCEPT_WIDTH'ha
`define EXCEPT_DTLBMISS `EXCEPT_WIDTH'h9
`define EXCEPT_HPINT `EXCEPT_WIDTH'h8
`define EXCEPT_ILLEGAL `EXCEPT_WIDTH'h7
`define EXCEPT_ALIGN `EXCEPT_WIDTH'h6
`define EXCEPT_LPINT `EXCEPT_WIDTH'h5
`define EXCEPT_IPF `EXCEPT_WIDTH'h4
`define EXCEPT_DPF `EXCEPT_WIDTH'h3
`define EXCEPT_BUSERR `EXCEPT_WIDTH'h2
`define EXCEPT_RESET `EXCEPT_WIDTH'h1
`define EXCEPT_NONE `EXCEPT_WIDTH'h0
 
`define SR_WIDTH 9
// SR bits (no CID)
`define SR_SUPV 0
`define SR_EXR 1
`define SR_EIR 2
`define SR_DCE 3
`define SR_ICE 4
`define SR_DME 5
`define SR_IME 6
`define SR_LEE 7
`define SR_CF 8
 
// Access types
`define ACCESS_WIDTH 2
`define ACCESS_USER_READ 2'b00
`define ACCESS_USER_WRITE 2'b01
`define ACCESS_SUPV_READ 2'b10
`define ACCESS_SUPV_WRITE 2'b11
 
// SPRS
// SIMON
//`define SPR_GROUP_BITS 31:27
`define SPR_GROUP_BITS 15:11
`define SPR_GROUP_WIDTH 5
`define SPR_GROUP_SYS 5'd00
`define SPR_GROUP_IMMU 5'd01
`define SPR_GROUP_DMMU 5'd02
`define SPR_GROUP_DC 5'd03
`define SPR_GROUP_IC 5'd04
`define SPR_GROUP_DU 5'd06
`define SPR_GROUP_PM 5'd08
`define SPR_GROUP_PIC 5'd09
`define SPR_GROUP_TT 5'd10
`define SPR_GROUP_MODA 5'd29
`define SPR_GROUP_MODD 5'd30
 
`define SPR_CFGR 7'd0
`define SPR_RF 6'd32 // 1024 >> 5
`define SPR_PC 11'd16
`define SPR_SR 11'd17
`define SPR_EPCR 11'd32
`define SPR_EEAR 11'd48
`define SPR_ESR 11'd64
 
 
// Bits that define the group
`define SPRGRP_BITS 15:11
 
// Bits that define offset inside the group
`define SPROFS_BITS 10:0
 
//
// Power Management
//
 
// Define it if you want PM implemented
`define PM_IMPLEMENTED
 
// Bit positions inside PMR (don't change)
`define PM_PMR_SDF 3:0
`define PM_PMR_DME 4
`define PM_PMR_SME 5
`define PM_PMR_DCGE 6
`define PM_PMR_UNUSED 31:7
 
// PMR offset inside PM group of registers
`define PM_OFS_PMR 11'b0
 
// PM group
`define SPRGRP_PM 5'd8
 
// Define if PMR can be read/written at any address inside PM group
`define PM_PARTIAL_DECODING
 
// Define if reading PMR is allowed
`define PM_READREGS
 
// Define if unused PMR bits should be zero
`define PM_UNUSED_ZERO
 
//
// Debug Unit
//
 
// Define it if you want DU implemented
`define DU_IMPLEMENTED
 
// Address offsets of DU registers inside DU group
`define DU_OFS_DMR1 5'd16
`define DU_OFS_DMR2 5'd17
`define DU_OFS_DSR 5'd20
`define DU_OFS_DRR 5'd21
 
// Position of offset bits inside SPR address
`define DUOFS_BITS 4:0
 
// Define if you want these DU registers to be implemented
`define DU_DMR1
`define DU_DMR2
`define DU_DSR
`define DU_DRR
 
// SIMON
`define DU_DMR1_ST 22
 
// Define if reading DU regs is allowed
`define DU_READREGS
 
// Define if unused DU registers bits should be zero
`define DU_UNUSED_ZERO
 
// DU operation commands
`define DU_OP_READSPR 3'd4
`define DU_OP_WRITESPR 3'd5
 
//
// Programmable Interrupt Controller
//
 
// Define it if you want PIC implemented
`define PIC_IMPLEMENTED
 
// Define number of interrupt inputs (2-31)
`define PIC_INTS 20
 
// Address offsets of PIC registers inside PIC group
`define PIC_OFS_PICMR 2'd0
`define PIC_OFS_PICPR 2'd1
`define PIC_OFS_PICSR 2'd2
 
// Position of offset bits inside SPR address
`define PICOFS_BITS 1:0
 
// Define if you want these PIC registers to be implemented
`define PIC_PICMR
`define PIC_PICPR
`define PIC_PICSR
 
// Define if reading PIC registers is allowed
`define PIC_READREGS
 
// Define if unused PIC register bits should be zero
`define PIC_UNUSED_ZERO
 
//
// Tick Timer
//
 
// Define it if you want TT implemented
`define TT_IMPLEMENTED
 
// Address offsets of TT registers inside TT group
`define TT_OFS_TTMR 1'd0
`define TT_OFS_TTCR 1'd1
 
// Position of offset bits inside SPR group
`define TTOFS_BITS 0
 
// Define if you want these TT registers to be implemented
`define TT_TTMR
`define TT_TTCR
 
// TTMR bits
`define TT_TTMR_TP 27:0
`define TT_TTMR_IP 28
`define TT_TTMR_IE 29
`define TT_TTMR_M 31:30
 
// Define if reading TT registers is allowed
`define TT_READREGS
 
 
//
// VR, UPR and Configuration Registers
//
 
// Define if you want configuration registers implemented
`define CFGR_IMPLEMENTED
 
// Define if you want full address decode inside SYS group
`define SYS_FULL_DECODE
 
// Offsets of VR, UPR and CFGR registers
`define SPRGRP_SYS_VR 4'h0
`define SPRGRP_SYS_UPR 4'h1
`define SPRGRP_SYS_CPUCFGR 4'h2
`define SPRGRP_SYS_DMMUCFGR 4'h3
`define SPRGRP_SYS_IMMUCFGR 4'h4
`define SPRGRP_SYS_DCCFGR 4'h5
`define SPRGRP_SYS_ICCFGR 4'h6
`define SPRGRP_SYS_DCFGR 4'h7
 
// VR fields
`define VR_REV_BITS 5:0
`define VR_RES1_BITS 15:6
`define VR_CFG_BITS 23:16
`define VR_VER_BITS 31:24
 
// VR values
`define VR_REV 6'h00
`define VR_RES1 10'h000
`define VR_CFG 8'h00
`define VR_VER 8'h12
 
// UPR fields
`define UPR_UP_BITS 0
`define UPR_DCP_BITS 1
`define UPR_ICP_BITS 2
`define UPR_DMP_BITS 3
`define UPR_IMP_BITS 4
`define UPR_MP_BITS 5
`define UPR_DUP_BITS 6
`define UPR_PCUP_BITS 7
`define UPR_PMP_BITS 8
`define UPR_PICP_BITS 9
`define UPR_TTP_BITS 10
`define UPR_RES1_BITS 23:11
`define UPR_CUP_BITS 31:24
 
// UPR values
`define UPR_UP 1'b1
`define UPR_DCP 1'b1
`define UPR_ICP 1'b1
`define UPR_DMP 1'b1
`define UPR_IMP 1'b1
`define UPR_MP 1'b1
`define UPR_DUP 1'b1
`define UPR_PCUP 1'b0
`define UPR_PMP 1'b1
`define UPR_PICP 1'b1
`define UPR_TTP 1'b1
`define UPR_RES1 13'h0000
`define UPR_CUP 8'h00
 
// CPUCFGR fields
`define CPUCFGR_NSGF_BITS 3:0
`define CPUCFGR_HGF_BITS 4
`define CPUCFGR_OB32S_BITS 5
`define CPUCFGR_OB64S_BITS 6
`define CPUCFGR_OF32S_BITS 7
`define CPUCFGR_OF64S_BITS 8
`define CPUCFGR_OV64S_BITS 9
`define CPUCFGR_RES1_BITS 31:10
 
// CPUCFGR values
`define CPUCFGR_NSGF 4'h0
`define CPUCFGR_HGF 1'b0
`define CPUCFGR_OB32S 1'b1
`define CPUCFGR_OB64S 1'b0
`define CPUCFGR_OF32S 1'b0
`define CPUCFGR_OF64S 1'b0
`define CPUCFGR_OV64S 1'b0
`define CPUCFGR_RES1 22'h000000
 
// DMMUCFGR fields
`define DMMUCFGR_NTW_BITS 1:0
`define DMMUCFGR_NTS_BITS 4:2
`define DMMUCFGR_NAE_BITS 7:5
`define DMMUCFGR_CRI_BITS 8
`define DMMUCFGR_PRI_BITS 9
`define DMMUCFGR_TEIRI_BITS 10
`define DMMUCFGR_HTR_BITS 11
`define DMMUCFGR_RES1_BITS 31:12
 
// DMMUCFGR values
`define DMMUCFGR_NTW 2'h0
`define DMMUCFGR_NTS 3'h5
`define DMMUCFGR_NAE 3'h0
`define DMMUCFGR_CRI 1'b0
`define DMMUCFGR_PRI 1'b0
`define DMMUCFGR_TEIRI 1'b1
`define DMMUCFGR_HTR 1'b0
`define DMMUCFGR_RES1 20'h00000
 
// IMMUCFGR fields
`define IMMUCFGR_NTW_BITS 1:0
`define IMMUCFGR_NTS_BITS 4:2
`define IMMUCFGR_NAE_BITS 7:5
`define IMMUCFGR_CRI_BITS 8
`define IMMUCFGR_PRI_BITS 9
`define IMMUCFGR_TEIRI_BITS 10
`define IMMUCFGR_HTR_BITS 11
`define IMMUCFGR_RES1_BITS 31:12
 
// IMMUCFGR values
`define IMMUCFGR_NTW 2'h0
`define IMMUCFGR_NTS 3'h5
`define IMMUCFGR_NAE 3'h0
`define IMMUCFGR_CRI 1'b0
`define IMMUCFGR_PRI 1'b0
`define IMMUCFGR_TEIRI 1'b1
`define IMMUCFGR_HTR 1'b0
`define IMMUCFGR_RES1 20'h00000
 
// DCCFGR fields
`define DCCFGR_NCW_BITS 2:0
`define DCCFGR_NCS_BITS 6:3
`define DCCFGR_CBS_BITS 7
`define DCCFGR_CWS_BITS 8
`define DCCFGR_CCRI_BITS 9
`define DCCFGR_CBIRI_BITS 10
`define DCCFGR_CBPRI_BITS 11
`define DCCFGR_CBLRI_BITS 12
`define DCCFGR_CBFRI_BITS 13
`define DCCFGR_CBWBRI_BITS 14
`define DCCFGR_RES1_BITS 31:15
 
// DCCFGR values
`define DCCFGR_NCW 3'h0
`define DCCFGR_NCS 4'h5
`define DCCFGR_CBS 1'b0
`define DCCFGR_CWS 1'b0
`define DCCFGR_CCRI 1'b1
`define DCCFGR_CBIRI 1'b1
`define DCCFGR_CBPRI 1'b0
`define DCCFGR_CBLRI 1'b0
`define DCCFGR_CBFRI 1'b0
`define DCCFGR_CBWBRI 1'b1
`define DCCFGR_RES1 17'h00000
 
// ICCFGR fields
`define ICCFGR_NCW_BITS 2:0
`define ICCFGR_NCS_BITS 6:3
`define ICCFGR_CBS_BITS 7
`define ICCFGR_CWS_BITS 8
`define ICCFGR_CCRI_BITS 9
`define ICCFGR_CBIRI_BITS 10
`define ICCFGR_CBPRI_BITS 11
`define ICCFGR_CBLRI_BITS 12
`define ICCFGR_CBFRI_BITS 13
`define ICCFGR_CBWBRI_BITS 14
`define ICCFGR_RES1_BITS 31:15
 
// ICCFGR values
`define ICCFGR_NCW 3'h0
`define ICCFGR_NCS 4'h5
`define ICCFGR_CBS 1'b0
`define ICCFGR_CWS 1'b0
`define ICCFGR_CCRI 1'b1
`define ICCFGR_CBIRI 1'b1
`define ICCFGR_CBPRI 1'b0
`define ICCFGR_CBLRI 1'b0
`define ICCFGR_CBFRI 1'b0
`define ICCFGR_CBWBRI 1'b1
`define ICCFGR_RES1 17'h00000
 
// DCFGR fields
`define DCFGR_NDP_BITS 2:0
`define DCFGR_WPCI_BITS 3
`define DCFGR_RES1_BITS 31:4
 
// DCFGR values
`define DCFGR_NDP 3'h0
`define DCFGR_WPCI 1'b0
`define DCFGR_RES1 28'h0000000
 
 
// Instruction opcode groups (basic)
`define OR32_J 6'b000000
`define OR32_JAL 6'b000001
`define OR32_BNF 6'b000011
`define OR32_BF 6'b000100
`define OR32_NOP 6'b000101
`define OR32_MOVHI 6'b000110
`define OR32_MFSPR 6'b000111
`define OR32_XSYNC 6'b001000
`define OR32_RFE 6'b001001
 
`define OR32_MTSPR 6'b010000
`define OR32_JR 6'b010001
`define OR32_JALR 6'b010010
 
`define OR32_LWZ 6'b100001
`define OR32_LBZ 6'b100011
`define OR32_LBS 6'b100100
`define OR32_LHZ 6'b100101
`define OR32_LHS 6'b100110
`define OR32_ADDI 6'b100111
`define OR32_ADDIC 6'b101000
`define OR32_ANDI 6'b101001
`define OR32_ORI 6'b101010
`define OR32_XORI 6'b101011
`define OR32_MULI 6'b101100
`define OR32_MACI 6'b101101
`define OR32_SH_ROTI 6'b101110
`define OR32_SFXXI 6'b101111
 
`define OR32_SW 6'b110101
`define OR32_SB 6'b110110
`define OR32_SH 6'b110111
`define OR32_ALU 6'b111000
`define OR32_SFXX 6'b111001
 
/verilog/or1200.xcv/alu.v
0,0 → 1,285
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's ALU ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// ALU ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:35 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module alu(clk, rst, a, b, mult_mac_result, macrc_op, alu_op, shrot_op, comp_op, result, flag);
 
parameter width = `OPERAND_WIDTH;
 
//
// I/O
//
input clk;
input rst;
input [width-1:0] a;
input [width-1:0] b;
input [width-1:0] mult_mac_result;
input macrc_op;
input [`ALUOP_WIDTH-1:0] alu_op;
input [`SHROTOP_WIDTH-1:0] shrot_op;
input [`COMPOP_WIDTH-1:0] comp_op;
output [width-1:0] result;
output flag;
 
//
// Internal wires and regs
//
reg [width-1:0] result;
reg [width-1:0] shifted_rotated;
reg flagforw;
reg flag_we;
reg flag;
integer d1;
integer d2;
wire [width-1:0] comp_a;
wire [width-1:0] comp_b;
wire a_eq_b;
wire a_lt_b;
 
//
// Combinatorial logic
//
assign comp_a = {a[width-1] ^ comp_op[3] , a[width-2:0]};
assign comp_b = {b[width-1] ^ comp_op[3] , b[width-2:0]};
assign a_eq_b = (comp_a == comp_b);
assign a_lt_b = (comp_a < comp_b);
 
//
// Simulation check for bad ALU behavior
//
`ifdef OR1200_WARNINGS
// synopsys translate_off
always @(result) begin
if (result === 32'bx)
$display("%t: WARNING: 32'bx detected on ALU result bus. Please check !", $time);
end
// synopsys translate_on
`endif
 
//
// Central part of the ALU
//
always @(alu_op or a or b or macrc_op or shifted_rotated or mult_mac_result) begin
casex (alu_op) // synopsys parallel_case full_case
`ALUOP_SHROT : begin
result = shifted_rotated;
flag_we = 1'b0;
end
`ALUOP_ADD : begin
result = a + b;
flag_we = 1'b0;
end
`ALUOP_SUB : begin
result = a - b;
flag_we = 1'b0;
end
`ALUOP_XOR : begin
result = a ^ b;
flag_we = 1'b0;
end
`ALUOP_OR : begin
result = a | b;
flag_we = 1'b0;
end
`ALUOP_AND : begin
result = a & b;
flag_we = 1'b0;
end
`ALUOP_IMM : begin
result = b;
flag_we = 1'b0;
end
`ALUOP_MOVHI : begin
if (macrc_op) begin
result = mult_mac_result;
flag_we = 1'b0;
end
else begin
result = b << 16;
flag_we = 1'b0;
end
end
`ALUOP_MUL : begin
result = mult_mac_result;
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: MUL operation: %h * %h = %h", $time, a, b, mult_mac_result);
// synopsys translate_on
`endif
flag_we = 1'b0;
end
// synopsys translate_off
`ifdef SIM_ALU_DIV
`ALUOP_DIV : begin
d1 = a;
d2 = b;
$display("DIV operation: %d / %d = %d", d1, d2, d1/d2);
if (d2)
result = d1 / d2;
else
result = 32'h00000000;
flag_we = 1'b0;
end
`endif
`ifdef SIM_ALU_DIVU
`ALUOP_DIVU : begin
if (b)
result = a / b;
else
result = 32'h00000000;
flag_we = 1'b0;
end
`endif
// synopsys translate_on
`ALUOP_COMP: begin
flag_we = 1'b1;
result = 32'd0;
end
endcase
end
 
//
// Shifts and rotation
//
always @(shrot_op or a or b) begin
case (shrot_op) // synopsys parallel_case full_case
`SHROTOP_SLL :
shifted_rotated = (a << b[4:0]);
`SHROTOP_SRL :
shifted_rotated = (a >> b[4:0]);
`ifdef IMPL_ALU_ROTATE
`SHROTOP_ROR :
shifted_rotated = (a << (6'd32-{1'b0, b[4:0]})) | (a >> b[4:0]);
`endif
default:
shifted_rotated = ({32{a[31]}} << (6'd32-{1'b0, b[4:0]})) | a >> b[4:0];
endcase
end
 
//
// First type of compare implementation
//
`ifdef IMPL_ALU_COMP1
always @(comp_op or a_eq_b or a_lt_b) begin
case(comp_op[2:0]) // synopsys parallel_case full_case
`COP_SFEQ:
flagforw = a_eq_b;
`COP_SFNE:
flagforw = ~a_eq_b;
`COP_SFGT:
flagforw = ~(a_eq_b | a_lt_b);
`COP_SFGE:
flagforw = ~a_lt_b;
`COP_SFLT:
flagforw = a_lt_b;
`COP_SFLE:
flagforw = a_eq_b | a_lt_b;
// synopsys translate_off
default:
flagforw = 1'bx;
// synopsys translate_on
endcase
end
`endif
 
//
// Second type of compare implementation
//
`ifdef IMPL_ALU_COMP2
always @(comp_op or a_eq_b or a_lt_b or comp_a or comp_b) begin
case(comp_op[2:0]) // synopsys parallel_case full_case
`COP_SFEQ:
flagforw = (comp_a == comp_b);
`COP_SFNE:
flagforw = (comp_a != comp_b);
`COP_SFGT:
flagforw = (comp_a > comp_b);
`COP_SFGE:
flagforw = (comp_a >= comp_b);
`COP_SFLT:
flagforw = (comp_a < comp_b);
`COP_SFLE:
flagforw = (comp_a <= comp_b);
// synopsys translate_off
default:
flagforw = 1'bx;
// synopsys translate_on
endcase
end
`endif
 
//
// Flag bit
//
always @(posedge clk or posedge rst) begin
if (rst)
flag <= #1 1'b0;
else if (flag_we) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("COMPARE: comp_a:%h comp_b:%h a_eq_b=%b a_lt_b=%b", comp_a, comp_b, a_eq_b, a_lt_b);
// synopsys translate_on
`endif
flag <= #1 flagforw;
end
end
 
endmodule
/verilog/or1200.xcv/generic_spram_64x21.v
0,0 → 1,253
//////////////////////////////////////////////////////////////////////
//// ////
//// Generic Single-Port Synchronous RAM ////
//// ////
//// This file is part of memory library available from ////
//// http://www.opencores.org/cvsweb.shtml/generic_memories/ ////
//// ////
//// Description ////
//// This block is a wrapper with common single-port ////
//// synchronous memory interface for different ////
//// types of ASIC and FPGA RAMs. Beside universal memory ////
//// interface it also provides behavioral model of generic ////
//// single-port synchronous RAM. ////
//// It should be used in all OPENCORES designs that want to be ////
//// portable accross different target technologies and ////
//// independent of target memory. ////
//// ////
//// Supported ASIC RAMs are: ////
//// - Artisan Single-Port Sync RAM ////
//// - Avant! Two-Port Sync RAM (*) ////
//// - Virage Single-Port Sync RAM ////
//// - Virtual Silicon Single-Port Sync RAM ////
//// ////
//// Supported FPGA RAMs are: ////
//// - Xilinx Virtex RAMB4_S16 ////
//// ////
//// To Do: ////
//// - xilinx rams need external tri-state logic ////
//// - fix avant! two-port ram ////
//// - add additional RAMs (Altera etc) ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.1 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/30 05:38:02 lampret
// Adding empty directories required by HDL coding guidelines
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module generic_spram_64x21(
// Generic synchronous single-port RAM interface
clk, rst, ce, we, oe, addr, di, do
);
 
//
// Default address and data buses width
//
parameter aw = 6;
parameter dw = 21;
 
//
// Generic synchronous single-port RAM interface
//
input clk; // Clock
input rst; // Reset
input ce; // Chip enable input
input we; // Write enable input
input oe; // Output enable input
input [aw-1:0] addr; // address bus inputs
input [dw-1:0] di; // input data bus
output [dw-1:0] do; // output data bus
 
//
// Internal wires and registers
//
wire [10:0] unconnected;
 
`ifdef ARTISAN_SSP
 
//
// Instantiation of ASIC memory:
//
// Artisan Synchronous Single-Port RAM (ra1sh)
//
art_hssp_64x21 #(dw, 1<<aw, aw) artisan_ssp(
.clk(clk),
.cen(~ce),
.wen(~we),
.a(addr),
.d(di),
.oen(~oe),
.q(do)
);
 
`else
 
`ifdef AVANT_ATP
 
//
// Instantiation of ASIC memory:
//
// Avant! Asynchronous Two-Port RAM
//
avant_atp avant_atp(
.web(~we),
.reb(),
.oeb(~oe),
.rcsb(),
.wcsb(),
.ra(addr),
.wa(addr),
.di(di),
.do(do)
);
 
`else
 
`ifdef VIRAGE_SSP
 
//
// Instantiation of ASIC memory:
//
// Virage Synchronous 1-port R/W RAM
//
virage_ssp virage_ssp(
.clk(clk),
.adr(addr),
.d(di),
.we(we),
.oe(oe),
.me(ce),
.q(do)
);
 
`else
 
`ifdef VIRTUALSILICON_SSP
 
//
// Instantiation of ASIC memory:
//
// Virtual Silicon Single-Port Synchronous SRAM
//
virtualsilicon_ssp #(1<<aw, aw-1, dw-1) virtualsilicon_ssp(
.CK(clk),
.ADR(addr),
.DI(di),
.WEN(~we),
.CEN(~ce),
.OEN(~oe),
.DOUT(do)
);
 
`else
 
`ifdef XILINX_RAMB4
 
//
// Instantiation of FPGA memory:
//
// Virtex/Spartan2
//
 
//
// Block 0
//
RAMB4_S16 ramb4_s16_0(
.CLK(clk),
.RST(rst),
.ADDR({2'b00, addr}),
.DI(di[15:0]),
.EN(ce),
.WE(we),
.DO(do[15:0])
);
 
//
// Block 1
//
RAMB4_S16 ramb4_s16_1(
.CLK(clk),
.RST(rst),
.ADDR({2'b00, addr}),
.DI({unconnected, di[20:16]}),
.EN(ce),
.WE(we),
.DO({unconnected, do[20:16]})
);
 
`else
 
//
// Generic single-port synchronous RAM model
//
 
//
// Generic RAM's registers and wires
//
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
reg [dw-1:0] do_reg; // RAM data output register
 
//
// Data output drivers
//
assign do = (oe) ? do_reg : {dw{1'bz}};
 
//
// RAM read and write
//
always @(posedge clk)
if (ce && !we)
do_reg <= #1 mem[addr];
else if (ce && we)
mem[addr] <= #1 di;
 
`endif // !XILINX_RAMB4_S16
`endif // !VIRTUALSILICON_SSP
`endif // !VIRAGE_SSP
`endif // !AVANT_ATP
`endif // !ARTISAN_SSP
 
endmodule
/verilog/or1200.xcv/generic_spram_64x23.v
0,0 → 1,253
//////////////////////////////////////////////////////////////////////
//// ////
//// Generic Single-Port Synchronous RAM ////
//// ////
//// This file is part of memory library available from ////
//// http://www.opencores.org/cvsweb.shtml/generic_memories/ ////
//// ////
//// Description ////
//// This block is a wrapper with common single-port ////
//// synchronous memory interface for different ////
//// types of ASIC and FPGA RAMs. Beside universal memory ////
//// interface it also provides behavioral model of generic ////
//// single-port synchronous RAM. ////
//// It should be used in all OPENCORES designs that want to be ////
//// portable accross different target technologies and ////
//// independent of target memory. ////
//// ////
//// Supported ASIC RAMs are: ////
//// - Artisan Single-Port Sync RAM ////
//// - Avant! Two-Port Sync RAM (*) ////
//// - Virage Single-Port Sync RAM ////
//// - Virtual Silicon Single-Port Sync RAM ////
//// ////
//// Supported FPGA RAMs are: ////
//// - Xilinx Virtex RAMB4_S16 ////
//// ////
//// To Do: ////
//// - xilinx rams need external tri-state logic ////
//// - fix avant! two-port ram ////
//// - add additional RAMs (Altera etc) ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.1 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/30 05:38:02 lampret
// Adding empty directories required by HDL coding guidelines
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module generic_spram_64x23(
// Generic synchronous single-port RAM interface
clk, rst, ce, we, oe, addr, di, do
);
 
//
// Default address and data buses width
//
parameter aw = 6;
parameter dw = 23;
 
//
// Generic synchronous single-port RAM interface
//
input clk; // Clock
input rst; // Reset
input ce; // Chip enable input
input we; // Write enable input
input oe; // Output enable input
input [aw-1:0] addr; // address bus inputs
input [dw-1:0] di; // input data bus
output [dw-1:0] do; // output data bus
 
//
// Internal wires and registers
//
wire [8:0] unconnected;
 
`ifdef ARTISAN_SSP
 
//
// Instantiation of ASIC memory:
//
// Artisan Synchronous Single-Port RAM (ra1sh)
//
art_hssp_64x23 #(dw, 1<<aw, aw) artisan_ssp(
.clk(clk),
.cen(~ce),
.wen(~we),
.a(addr),
.d(di),
.oen(~oe),
.q(do)
);
 
`else
 
`ifdef AVANT_ATP
 
//
// Instantiation of ASIC memory:
//
// Avant! Asynchronous Two-Port RAM
//
avant_atp avant_atp(
.web(~we),
.reb(),
.oeb(~oe),
.rcsb(),
.wcsb(),
.ra(addr),
.wa(addr),
.di(di),
.do(do)
);
 
`else
 
`ifdef VIRAGE_SSP
 
//
// Instantiation of ASIC memory:
//
// Virage Synchronous 1-port R/W RAM
//
virage_ssp virage_ssp(
.clk(clk),
.adr(addr),
.d(di),
.we(we),
.oe(oe),
.me(ce),
.q(do)
);
 
`else
 
`ifdef VIRTUALSILICON_SSP
 
//
// Instantiation of ASIC memory:
//
// Virtual Silicon Single-Port Synchronous SRAM
//
virtualsilicon_ssp #(1<<aw, aw-1, dw-1) virtualsilicon_ssp(
.CK(clk),
.ADR(addr),
.DI(di),
.WEN(~we),
.CEN(~ce),
.OEN(~oe),
.DOUT(do)
);
 
`else
 
`ifdef XILINX_RAMB4
 
//
// Instantiation of FPGA memory:
//
// Virtex/Spartan2
//
 
//
// Block 0
//
RAMB4_S16 ramb4_s16_0(
.CLK(clk),
.RST(rst),
.ADDR({2'b00, addr}),
.DI(di[15:0]),
.EN(ce),
.WE(we),
.DO(do[15:0])
);
 
//
// Block 1
//
RAMB4_S16 ramb4_s16_1(
.CLK(clk),
.RST(rst),
.ADDR({2'b00, addr}),
.DI({unconnected, di[22:16]}),
.EN(ce),
.WE(we),
.DO({unconnected, do[22:16]})
);
 
`else
 
//
// Generic single-port synchronous RAM model
//
 
//
// Generic RAM's registers and wires
//
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
reg [dw-1:0] do_reg; // RAM data output register
 
//
// Data output drivers
//
assign do = (oe) ? do_reg : {dw{1'bz}};
 
//
// RAM read and write
//
always @(posedge clk)
if (ce && !we)
do_reg <= #1 mem[addr];
else if (ce && we)
mem[addr] <= #1 di;
 
`endif // !XILINX_RAMB4_S16
`endif // !VIRTUALSILICON_SSP
`endif // !VIRAGE_SSP
`endif // !AVANT_ATP
`endif // !ARTISAN_SSP
 
endmodule
/verilog/or1200.xcv/ic_tag.v
0,0 → 1,119
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's IC TAGs ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Instatiation of instruction cache tag rams ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module ic_tag(
// Clock and reset
clk, rst,
 
// Internal i/f
addr, en, we, datain, tag_v, tag
);
 
parameter dw = 20;
parameter aw = 9;
 
//
// I/O
//
 
//
// Clock and reset
//
input clk;
input rst;
 
//
// Internal i/f
//
input [aw-1:0] addr;
input en;
input we;
input [dw-1:0] datain;
output tag_v;
output [dw-2:0] tag;
 
`ifdef OR1200_NO_IC
 
//
// Insn cache not implemented
//
assign tag = {dw-1{1'b0}};
assign tag_v = 1'b0;
`else
 
//
// Instantiation of TAG RAM block
//
generic_spram_512x20 ic_tag0(
.clk(clk),
.rst(rst),
.ce(en),
.we(we),
.oe(1'b1),
.addr(addr),
.di(datain),
.do({tag, tag_v})
);
 
`endif
 
endmodule
/verilog/or1200.xcv/dc.v
0,0 → 1,348
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Data Cache top level ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Instantiation of all DC blocks. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:35 igorm
// no message
//
// Revision 1.4 2001/08/13 03:36:20 lampret
// Added cfg regs. Moved all defines into one defines.v file. More cleanup.
//
// Revision 1.3 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/22 03:31:53 lampret
// Fixed RAM's oen bug. Cache bypass under development.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
//
// Data cache
//
 
module dc(
// Rst, clk and clock control
clk, rst, clkdiv_by_2,
 
// External i/f
dcbiu_rdy, dcbiu_datain, dcbiu_dataout, dcbiu_addr, dcbiu_read, dcbiu_write, dcbiu_sel,
 
// Internal i/f
dc_en, dclsu_addr, dclsu_lsuop, dclsu_datain, dclsu_dataout, dclsu_stall, dclsu_unstall,
 
// SPRs
spr_cs, spr_write, spr_addr, spr_dat_i
);
 
parameter dw = `OPERAND_WIDTH;
 
//
// I/O
//
 
//
// Clock and reset
//
input clk;
input rst;
input clkdiv_by_2;
 
//
// External I/F
//
input dcbiu_rdy;
input [dw-1:0] dcbiu_datain;
output [31:0] dcbiu_addr;
output dcbiu_read;
output dcbiu_write;
output [3:0] dcbiu_sel;
 
//
// Internal I/F
//
input dc_en;
input [31:0] dclsu_addr;
input [`LSUOP_WIDTH-1:0] dclsu_lsuop;
input [dw-1:0] dclsu_datain;
output [dw-1:0] dclsu_dataout;
output [dw-1:0] dcbiu_dataout;
output dclsu_stall;
output dclsu_unstall;
 
//
// SPR access
//
input spr_cs;
input spr_write;
input [31:0] spr_addr;
input [31:0] spr_dat_i;
 
//
// Internal wires and regs
//
wire tag_v;
wire [18:0] tag;
wire [dw-1:0] to_dcram;
wire [dw-1:0] from_dcram;
wire [dw-1:0] to_mem2reg;
wire [31:0] saved_addr;
wire refill;
wire [3:0] dcram_we;
wire dctag_we;
wire [dw-1:0] lsu_datain_memaligned;
wire [31:0] dc_addr;
wire refill_first;
wire refill_prepare;
wire refill_start;
wire refill_rest;
wire [`LSUOP_WIDTH-1:0] dcfsm_lsuop;
wire dcfsm_read;
wire dcfsm_write;
wire [1:0] mem2reg_addr;
reg hit;
reg [1:0] valid_div;
reg [3:0] dcbiu_sel;
reg [1:0] bypass_wait;
wire queue;
wire cntrbusy;
wire dcbiu_valid;
wire [12:4] dctag_addr;
wire dctag_en;
wire dctag_v;
wire dc_inv;
 
//
// Simple assignments
//
assign dcbiu_addr = dc_addr;
assign dclsu_unstall = dcbiu_rdy;
assign dc_inv = spr_cs & spr_write;
assign dctag_we = refill | dc_inv;
assign dctag_addr = dc_inv ? spr_dat_i[12:4] : dc_addr[12:4];
assign dctag_en = dc_inv | dc_en;
assign dctag_v = ~dc_inv;
 
//
// Data to BIU is from DCRAM when DC is enabled or from LSU when
// DC is disabled
//
assign dcbiu_dataout = (dc_en) ? from_dcram : lsu_datain_memaligned;
 
//
// Bypases of the DC when DC is disabled
//
assign dcfsm_lsuop = (dc_en) ? dclsu_lsuop : `LSUOP_NOP;
assign dcbiu_read = (dc_en) ? dcfsm_read : ((|dclsu_lsuop) && ~dclsu_lsuop[3]);
assign dcbiu_write = (dc_en) ? dcfsm_write : ((|dclsu_lsuop) && dclsu_lsuop[3]);
always @(dc_en or dclsu_lsuop or dclsu_addr)
casex({dc_en, dclsu_lsuop, dclsu_addr[1:0]})
{1'b0, `LSUOP_SB, 2'b00} : dcbiu_sel = 4'b1000;
{1'b0, `LSUOP_SB, 2'b01} : dcbiu_sel = 4'b0100;
{1'b0, `LSUOP_SB, 2'b10} : dcbiu_sel = 4'b0010;
{1'b0, `LSUOP_SB, 2'b11} : dcbiu_sel = 4'b0001;
{1'b0, `LSUOP_SH, 2'b00} : dcbiu_sel = 4'b1100;
{1'b0, `LSUOP_SH, 2'b10} : dcbiu_sel = 4'b0011;
{1'b0, `LSUOP_SW, 2'b00} : dcbiu_sel = 4'b1111;
{1'b0, `LSUOP_LBZ, 2'b00}, {1'b0, `LSUOP_LBS, 2'b00} : dcbiu_sel = 4'b1000;
{1'b0, `LSUOP_LBZ, 2'b01}, {1'b0, `LSUOP_LBS, 2'b01} : dcbiu_sel = 4'b0100;
{1'b0, `LSUOP_LBZ, 2'b10}, {1'b0, `LSUOP_LBS, 2'b10} : dcbiu_sel = 4'b0010;
{1'b0, `LSUOP_LBZ, 2'b11}, {1'b0, `LSUOP_LBS, 2'b11} : dcbiu_sel = 4'b0001;
{1'b0, `LSUOP_LHZ, 2'b00}, {1'b0, `LSUOP_LHS, 2'b00} : dcbiu_sel = 4'b1100;
{1'b0, `LSUOP_LHZ, 2'b10}, {1'b0, `LSUOP_LHS, 2'b10} : dcbiu_sel = 4'b0011;
{1'b0, `LSUOP_LWZ, 2'b00}, {1'b0, `LSUOP_LWS, 2'b00} : dcbiu_sel = 4'b1111;
7'b1xxxxxx : dcbiu_sel = 4'b1111;
default : dcbiu_sel = 4'b0000;
endcase
 
assign mem2reg_addr = (dc_en) ? saved_addr[1:0] : dclsu_addr[1:0];
 
//
// Wait for DC bypass access
//
always @(posedge rst or posedge clk)
if (rst)
bypass_wait <= #1 2'b00;
else if (dcbiu_valid)
bypass_wait <= #1 2'b00;
else if (dcbiu_read | dcbiu_write)
bypass_wait <= #1 {bypass_wait[0], 1'b1};
else
bypass_wait <= #1 2'b00;
 
//
// Queue
//
assign queue = (refill && (|dcfsm_lsuop) && !refill_first && !refill_rest) ? 1'b1 : 1'b0;
 
//
// DC/LSU stall
//
//assign dclsu_stall = refill_start | (refill_first & ~dcbiu_valid)| refill_rest | queue | cntrbusy | (~dc_en & bypass_wait[1] & ~dcbiu_valid);
assign dclsu_stall = refill_start | (refill_first & ~dcbiu_valid)| refill_rest | queue | cntrbusy | (~dc_en & (dcbiu_read | dcbiu_write) & ~dcbiu_rdy);
 
//
// Select between claddr generated by DC FSM and addr[3:2] generated by LSU
//
assign dc_addr = (refill == 1'b1) ? saved_addr : dclsu_addr;
 
//
// Select between input data generated by LSU or by BIU
//
assign to_dcram = (refill == 1'b1) ? dcbiu_datain : lsu_datain_memaligned;
 
//
// Select between data generated by DCRAM or passed by BIU
//
assign to_mem2reg = (refill_first == 1'b1) | (~dc_en) ? dcbiu_datain : from_dcram;
 
//
// Tag comparison
//
always @(tag or saved_addr or tag_v) begin
if ((tag == saved_addr[31:13]) && tag_v)
hit = 1'b1;
else
hit = 1'b0;
end
 
//
// Valid_div counts RISC clock cycles by modulo 4
//
always @(posedge clk or posedge rst)
if (rst)
valid_div <= #1 2'b0;
else
valid_div <= #1 valid_div + 'd1;
 
//
// dcbiu_valid is one RISC clock cycle long dcbiu_rdy.
// dcbiu_rdy is two or four RISC clock cycles long because memory
// controller works at 1/2 or 1/4 of RISC clock freq (at 1/2 if
// clkdiv_by_2 is asserted).
//
assign dcbiu_valid = dcbiu_rdy & (valid_div[1] | clkdiv_by_2) & valid_div[0];
 
//
// Generate refill_start that signals to frz_logic a cache linefill is about to begin
//
assign refill_start = (refill_prepare & ~hit) ? 1'b1 : 1'b0;
 
//
// Instantiation of DC Finite State Machine
//
dc_fsm dc_fsm(
.clk(clk),
.rst(rst),
.lsu_op(dcfsm_lsuop),
.miss(~hit),
.biudata_valid(dcbiu_valid),
.start_addr(dclsu_addr),
.saved_addr(saved_addr),
.refill(refill),
.refill_first(refill_first),
.refill_prepare(refill_prepare),
.dcram_we(dcram_we),
.biu_read(dcfsm_read),
.biu_write(dcfsm_write),
.refill_rest(refill_rest),
.cntrbusy(cntrbusy)
);
 
//
// Instantiation of Regfile-to-memory aligner
//
reg2mem reg2mem(
.addr(dc_addr[1:0]),
.lsu_op(dclsu_lsuop),
.regdata(dclsu_datain),
.memdata(lsu_datain_memaligned)
);
 
//
// Instantiation of DC main memory
//
dc_ram dc_ram(
.clk(clk),
.rst(rst),
.addr(dc_addr[12:2]),
.en(dc_en),
.we(dcram_we),
.datain(to_dcram),
.dataout(from_dcram)
);
 
//
// Instantiation of DC TAG memory
//
dc_tag dc_tag(
.clk(clk),
.rst(rst),
.addr(dctag_addr),
.en(dctag_en),
.we(dctag_we),
.datain({dc_addr[31:13], dctag_v}),
.tag_v(tag_v),
.tag(tag)
);
 
//
// Instatiation of Memory-to-regfile aligner
//
mem2reg mem2reg(
.addr(mem2reg_addr[1:0]),
.lsu_op(dclsu_lsuop),
.memdata(to_mem2reg),
.regdata(dclsu_dataout)
);
 
endmodule
/verilog/or1200.xcv/cpu.v
0,0 → 1,568
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's CPU ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Instantiation of internal CPU blocks. IFETCH, SPRS, FRZ, ////
//// ALU, EXCEPT, ID, WBMUX, OPERANDMUX, RF etc. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:35 igorm
// no message
//
// Revision 1.4 2001/08/17 08:01:19 lampret
// IC enable/disable.
//
// Revision 1.3 2001/08/13 03:36:20 lampret
// Added cfg regs. Moved all defines into one defines.v file. More cleanup.
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module cpu(
// Clk & Rst
clk, rst,
 
// Insn interface
ic_insn, ic_addr, ic_stall, ic_fetchop, ic_en,
immu_en, immuexcept_miss, immuexcept_fault,
 
// Debug unit
ex_freeze, branch_op,
du_stall, du_addr, du_dat_du, du_read, du_write, du_except,
// Data interface
dclsu_stall, dclsu_unstall, dclsu_addr, dclsu_datain, dclsu_dataout, dclsu_lsuop, dc_en,
dmmu_en, dmmuexcept_miss, dmmuexcept_fault,
 
// Interrupt exceptions
int_high, int_low,
 
// SPR interface
supv, spr_addr, spr_dataout, spr_dat_pic, spr_dat_tt, spr_dat_pm,
spr_dat_dmmu, spr_dat_immu, spr_dat_du, spr_cs, spr_we
);
 
parameter dw = `OPERAND_WIDTH;
parameter aw = `REGFILE_ADDR_WIDTH;
 
//
// I/O ports
//
 
//
// Clk & Rst
//
input clk;
input rst;
 
//
// Insn (IC) interface
//
input [31:0] ic_insn;
output [31:0] ic_addr;
input ic_stall;
output [`FETCHOP_WIDTH-1:0] ic_fetchop;
output ic_en;
 
//
// Insn (IMMU) interface
//
input immuexcept_miss;
input immuexcept_fault;
output immu_en;
 
//
// Debug interface
//
output ex_freeze;
output [`BRANCHOP_WIDTH-1:0] branch_op;
input du_stall;
input [dw-1:0] du_addr;
input [dw-1:0] du_dat_du;
input du_read;
input du_write;
output [`EXCEPT_WIDTH-1:0] du_except;
 
//
// Data (DC) interface
//
input dclsu_stall;
input dclsu_unstall;
output [31:0] dclsu_addr;
input [31:0] dclsu_datain;
output [31:0] dclsu_dataout;
output [`LSUOP_WIDTH-1:0] dclsu_lsuop;
output dc_en;
 
//
// Data (DMMU) interface
//
input dmmuexcept_miss;
input dmmuexcept_fault;
output dmmu_en;
 
//
// SPR interface
//
output supv;
input [dw-1:0] spr_dat_pic;
input [dw-1:0] spr_dat_tt;
input [dw-1:0] spr_dat_pm;
input [dw-1:0] spr_dat_dmmu;
input [dw-1:0] spr_dat_immu;
input [dw-1:0] spr_dat_du;
output [dw-1:0] spr_addr;
output [dw-1:0] spr_dataout;
output [31:0] spr_cs;
output spr_we;
 
//
// Interrupt exceptions
//
input int_high;
input int_low;
 
//
// Internal wires
//
wire [31:0] insn;
wire [31:0] if_pc;
wire [31:2] lr_sav;
wire [aw-1:0] rf_addrw;
wire [aw-1:0] rf_addra;
wire [aw-1:0] rf_addrb;
wire [dw-1:0] simm;
wire [dw-1:2] branch_addrofs;
wire [`ALUOP_WIDTH-1:0] alu_op;
wire [`SHROTOP_WIDTH-1:0] shrot_op;
wire [`COMPOP_WIDTH-1:0] comp_op;
wire [`BRANCHOP_WIDTH-1:0] branch_op;
wire [`LSUOP_WIDTH-1:0] lsu_op;
wire if_freeze;
wire id_freeze;
wire ex_freeze;
wire wb_freeze;
wire [`SEL_WIDTH-1:0] sel_a;
wire [`SEL_WIDTH-1:0] sel_b;
wire [`RFWBOP_WIDTH-1:0] rfwb_op;
wire [dw-1:0] rf_dataw;
wire [dw-1:0] rf_dataa;
wire [dw-1:0] rf_datab;
wire [dw-1:0] muxed_b;
wire [dw-1:0] wb_forw;
wire wbforw_valid;
wire [dw-1:0] operand_a;
wire [dw-1:0] operand_b;
wire [dw-1:0] alu_dataout;
wire [dw-1:0] lsu_dataout;
wire [dw-1:0] sprs_dataout;
wire [31:0] lsu_addrofs;
wire [`MULTICYCLE_WIDTH-1:0] multicycle;
wire [`EXCEPT_WIDTH-1:0] except_type;
wire except_flushpipe;
wire branch_taken;
wire flag;
wire lsu_stall;
wire branch_stall;
wire epcr_we;
wire eear_we;
wire esr_we;
wire pc_we;
wire [31:0] epcr;
wire [31:0] eear;
wire [`SR_WIDTH-1:0] esr;
wire [`SR_WIDTH-1:0] sr;
wire except_start;
wire except_started;
wire [31:0] wb_pc;
wire [31:0] wb_insn;
wire [15:0] spr_addrimm;
wire sig_syscall;
wire sig_trap;
wire [31:0] spr_dat_cfgr;
wire [31:0] spr_dat_rf;
wire [31:0] spr_dat_pc;
wire force_dslot_fetch;
wire if_stall;
wire id_macrc_op;
wire ex_macrc_op;
wire [31:0] mult_mac_result;
wire mac_stall;
 
//
// Exception type going to debug unit
//
assign du_except = except_type;
 
//
// Data cache enable
//
//assign dc_en = 1'b1;
assign dc_en = sr[`SR_DCE];
 
//
// Instruction cache enable
//
//assign ic_en = 1'b1;
assign ic_en = sr[`SR_ICE];
 
//
// DMMU enable
//
assign dmmu_en = sr[`SR_DME];
 
//
// IMMU enable
//
assign immu_en = sr[`SR_IME];
 
//
// SUPV bit
//
assign supv = sr[`SR_SUPV];
 
//
// Instantiation of exception block
//
except except(
.clk(clk),
.rst(rst),
.sig_buserr(1'b0),
.sig_illegal(1'b0),
.sig_align(1'b0),
.sig_range(1'b0),
.sig_dtlbmiss(dmmuexcept_miss),
.sig_dmmufault(dmmuexcept_fault),
.sig_inthigh(int_high),
.sig_syscall(sig_syscall),
.sig_trap(sig_trap),
.sig_itlbmiss(immuexcept_miss),
.sig_immufault(immuexcept_fault),
.sig_intlow(int_low),
.branch_taken(branch_taken),
.id_freeze(id_freeze),
.ex_freeze(ex_freeze),
.wb_freeze(wb_freeze),
.if_stall(if_stall),
.if_pc(if_pc),
.lr_sav(lr_sav),
.except_flushpipe(except_flushpipe),
.except_type(except_type),
.except_start(except_start),
.except_started(except_started),
.wb_pc(wb_pc),
.ex_pc(spr_dat_pc),
 
.datain(operand_b),
.epcr_we(epcr_we),
.eear_we(eear_we),
.esr_we(esr_we),
.epcr(epcr),
.eear(eear),
.esr(esr),
 
.lsu_addr(dclsu_addr),
.sr(sr)
);
 
//
// Instantiation of instruction fetch block
//
ifetch ifetch(
.clk(clk),
.rst(rst),
.ic_insn(ic_insn),
.ic_addr(ic_addr),
.ic_stall(ic_stall),
.ic_fetchop(ic_fetchop),
.if_freeze(if_freeze),
.if_insn(insn),
.if_pc(if_pc),
.branch_op(branch_op),
.except_type(except_type),
.except_start(except_start),
.branch_addrofs(branch_addrofs),
.lr_restor(operand_b),
.flag(flag),
.taken(branch_taken),
.binsn_addr(lr_sav),
.epcr(epcr),
.force_dslot_fetch(force_dslot_fetch),
.if_stall(if_stall),
.branch_stall(branch_stall),
.spr_dat_i(spr_dataout),
.spr_pc_we(pc_we)
);
 
//
// Instantiation of instruction decode/control logic
//
id id(
.clk(clk),
.rst(rst),
.id_freeze(id_freeze),
.ex_freeze(ex_freeze),
.wb_freeze(wb_freeze),
.except_flushpipe(except_flushpipe),
.if_insn(insn),
.branch_op(branch_op),
.rf_addra(rf_addra),
.rf_addrb(rf_addrb),
.alu_op(alu_op),
.shrot_op(shrot_op),
.comp_op(comp_op),
.rf_addrw(rf_addrw),
.rfwb_op(rfwb_op),
.wb_insn(wb_insn),
.simm(simm),
.branch_addrofs(branch_addrofs),
.lsu_addrofs(lsu_addrofs),
.sel_a(sel_a),
.sel_b(sel_b),
.lsu_op(lsu_op),
.multicycle(multicycle),
.spr_addrimm(spr_addrimm),
.wbforw_valid(wbforw_valid),
.sig_syscall(sig_syscall),
.sig_trap(sig_trap),
.force_dslot_fetch(force_dslot_fetch),
.id_macrc_op(id_macrc_op),
.ex_macrc_op(ex_macrc_op)
);
 
//
// Instantiation of write-back muxes
//
wbmux wbmux(
.clk(clk),
.rst(rst),
.wb_freeze(wb_freeze),
.rfwb_op(rfwb_op),
.muxin_a(alu_dataout),
.muxin_b(lsu_dataout),
.muxin_c(sprs_dataout),
.muxin_d({lr_sav, 2'b0}),
.muxout(rf_dataw),
.muxreg(wb_forw),
.muxreg_valid(wbforw_valid)
);
 
//
// Instantiation of register file
//
rf rf(
.clk(clk),
.rst(rst),
.addrw(rf_addrw),
.dataw(rf_dataw),
.id_freeze(id_freeze),
.we(rfwb_op[0]),
.addra(rf_addra),
.dataa(rf_dataa),
.addrb(rf_addrb),
.datab(rf_datab),
.spr_cs(spr_cs[`SPR_GROUP_SYS]),
.spr_write(spr_we),
.spr_addr(spr_addr),
.spr_dat_i(spr_dataout),
.spr_dat_o(spr_dat_rf)
 
);
 
//
// Instantiation of operand muxes
//
operandmuxes operandmuxes(
.clk(clk),
.rst(rst),
.ex_freeze(ex_freeze),
.rf_dataa(rf_dataa),
.rf_datab(rf_datab),
.ex_forw(rf_dataw),
.wb_forw(wb_forw),
.simm(simm),
.sel_a(sel_a),
.sel_b(sel_b),
.operand_a(operand_a),
.operand_b(operand_b),
.muxed_b(muxed_b)
);
 
//
// Instantiation of CPU's ALU
//
alu alu(
.clk(clk),
.rst(rst),
.a(operand_a),
.b(operand_b),
.mult_mac_result(mult_mac_result),
.macrc_op(ex_macrc_op),
.alu_op(alu_op),
.shrot_op(shrot_op),
.comp_op(comp_op),
.result(alu_dataout),
.flag(flag)
);
 
//
// Instantiation of CPU's ALU
//
mult_mac mult_mac(
.clk(clk),
.rst(rst),
.id_macrc_op(id_macrc_op),
.macrc_op(ex_macrc_op),
.a(operand_a),
.b(operand_b),
.alu_op(alu_op),
.result(mult_mac_result),
.mac_stall_r(mac_stall)
);
 
//
// Instantiation of CPU's SPRS block
//
sprs sprs(
.clk(clk),
.rst(rst),
.addrbase(operand_a),
.addrofs(spr_addrimm),
.dat_i(operand_b),
.alu_op(alu_op),
.flag(flag),
.to_wbmux(sprs_dataout),
 
.du_addr(du_addr),
.du_dat_du(du_dat_du),
.du_read(du_read),
.du_write(du_write),
 
.spr_addr(spr_addr),
.spr_dat_pic(spr_dat_pic),
.spr_dat_tt(spr_dat_tt),
.spr_dat_pm(spr_dat_pm),
.spr_dat_cfgr(spr_dat_cfgr),
.spr_dat_rf(spr_dat_rf),
.spr_dat_pc(spr_dat_pc),
.spr_dat_dmmu(spr_dat_dmmu),
.spr_dat_immu(spr_dat_immu),
.spr_dat_du(spr_dat_du),
.spr_dataout(spr_dataout),
.spr_cs(spr_cs),
.spr_we(spr_we),
 
.epcr_we(epcr_we),
.eear_we(eear_we),
.esr_we(esr_we),
.pc_we(pc_we),
.epcr(epcr),
.eear(eear),
.esr(esr),
.except_start(except_start),
.except_started(except_started),
 
.sr(sr),
.branch_op(branch_op)
);
 
//
// Instantiation of load/store unit
//
lsu lsu(
.clk(clk),
.rst(rst),
.addrbase(operand_a),
.addrofs(lsu_addrofs),
.lsu_op(lsu_op),
.lsu_datain(operand_b),
.lsu_dataout(lsu_dataout),
.lsu_stall(lsu_stall),
.dc_stall(dclsu_stall),
.dc_addr(dclsu_addr),
.dc_datain(dclsu_datain),
.dc_dataout(dclsu_dataout),
.dc_lsuop(dclsu_lsuop)
);
 
//
// Instantiation of freeze logic
//
frz_logic frz_logic(
.clk(clk),
.rst(rst),
.multicycle(multicycle),
.except_flushpipe(except_flushpipe),
.lsu_stall(lsu_stall),
.if_stall(if_stall),
.dclsu_unstall(dclsu_unstall),
.branch_stall(branch_stall),
.force_dslot_fetch(force_dslot_fetch),
.du_stall(du_stall),
.mac_stall(mac_stall),
.if_freeze(if_freeze),
.id_freeze(id_freeze),
.ex_freeze(ex_freeze),
.wb_freeze(wb_freeze)
);
 
//
// Instantiation of configuration registers
//
cfgr cfgr(
.clk(clk),
.rst(clk),
.spr_addr(spr_addr),
.spr_dat_o(spr_dat_cfgr)
);
 
endmodule
/verilog/or1200.xcv/except.v
0,0 → 1,347
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Exception logic ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Handles all OR1K exceptions inside CPU block. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
`define EXCEPTFSM_WIDTH 2
`define EXCEPTFSM_IDLE `EXCEPTFSM_WIDTH'd0
`define EXCEPTFSM_FLU1 `EXCEPTFSM_WIDTH'd1
`define EXCEPTFSM_FLU2 `EXCEPTFSM_WIDTH'd2
`define EXCEPTFSM_FLU3 `EXCEPTFSM_WIDTH'd3
 
//
// Exception recognition and sequencing
//
 
module except(
// Clock and reset
clk, rst,
 
// Internal i/f
sig_buserr, sig_illegal, sig_align, sig_range, sig_dtlbmiss, sig_dmmufault,
sig_inthigh, sig_syscall, sig_trap, sig_itlbmiss, sig_immufault, sig_intlow,
branch_taken, id_freeze, ex_freeze, wb_freeze, if_stall,
if_pc, lr_sav, except_flushpipe, except_type, except_start,
except_started, wb_pc, ex_pc, datain, epcr_we, eear_we, esr_we, epcr, eear,
esr, sr, lsu_addr
);
 
//
// I/O
//
input clk;
input rst;
input sig_buserr;
input sig_illegal;
input sig_align;
input sig_range;
input sig_dtlbmiss;
input sig_dmmufault;
input sig_inthigh;
input sig_syscall;
input sig_trap;
input sig_itlbmiss;
input sig_immufault;
input sig_intlow;
input branch_taken;
input id_freeze;
input ex_freeze;
input wb_freeze;
input if_stall;
input [31:0] if_pc;
output [31:2] lr_sav;
input [31:0] datain;
input epcr_we;
input eear_we;
input esr_we;
output [31:0] epcr;
output [31:0] eear;
output [`SR_WIDTH-1:0] esr;
input [`SR_WIDTH-1:0] sr;
input [31:0] lsu_addr;
output except_flushpipe;
output [`EXCEPT_WIDTH-1:0] except_type;
output except_start;
output except_started;
output [31:0] wb_pc;
output [31:0] ex_pc;
 
//
// Internal regs and wires
//
reg [`EXCEPT_WIDTH-1:0] except_type;
reg [31:0] id_pc;
reg [31:0] ex_pc;
reg [31:0] wb_pc;
reg [31:0] epcr;
reg [31:0] eear;
reg [`SR_WIDTH-1:0] esr;
reg [2:0] id_exceptflags;
reg [2:0] ex_exceptflags;
reg [`EXCEPTFSM_WIDTH-1:0] state;
reg extend_flush;
reg ex_dslot;
reg delayed1_ex_dslot;
reg delayed2_ex_dslot;
wire except_started;
wire [12:0] except_trig;
 
//
// Simple combinatorial logic
//
assign except_started = ~except_start & extend_flush;
assign lr_sav = ex_pc[31:2];
assign except_start = (except_type != `EXCEPT_NONE);
assign except_trig = { sig_buserr, sig_illegal, sig_align,
sig_range, sig_dtlbmiss, sig_dmmufault,
sig_inthigh, sig_trap, sig_syscall,
ex_exceptflags[2:0]};
 
//
// PC and Exception flags pipelines
//
always @(posedge clk or posedge rst) begin
if (rst) begin
id_pc <= #1 32'd0;
id_exceptflags <= #1 3'b0;
end
else if (!id_freeze) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: id_pc <= %h", $time, if_pc);
// synopsys translate_on
`endif
id_pc <= #1 if_pc;
id_exceptflags <= #1 { sig_itlbmiss, sig_immufault, sig_intlow & sr[`SR_EXR]};
end
end
 
//
// PC and Exception flags pipelines
//
always @(posedge clk or posedge rst) begin
if (rst) begin
ex_dslot <= #1 1'b0;
ex_pc <= #1 32'd0;
ex_exceptflags <= #1 3'b0;
delayed1_ex_dslot <= #1 1'b0;
delayed2_ex_dslot <= #1 1'b0;
end
else if (!ex_freeze & id_freeze) begin
ex_dslot <= #1 1'b0;
ex_pc <= #1 id_pc;
ex_exceptflags <= #1 3'b000;
delayed1_ex_dslot <= #1 ex_dslot;
delayed2_ex_dslot <= #1 delayed1_ex_dslot;
end
else if (!ex_freeze) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: ex_pc <= %h", $time, id_pc);
// synopsys translate_on
`endif
ex_dslot <= #1 branch_taken;
ex_pc <= #1 id_pc;
ex_exceptflags <= #1 id_exceptflags;
delayed1_ex_dslot <= #1 ex_dslot;
delayed2_ex_dslot <= #1 delayed1_ex_dslot;
end
end
 
 
//
// PC and Exception flags pipelines
//
always @(posedge clk or posedge rst) begin
if (rst) begin
wb_pc <= #1 32'd0;
end
else if (!wb_freeze) begin
wb_pc <= #1 ex_pc;
end
end
 
//
// We have started execution of exception handler:
// 1. Asserted for 3 clock cycles
// 2. Don't execute any instruction that is still in pipeline and is not part of exception handler
//
assign except_flushpipe = (sr[`SR_EXR] & (sig_dtlbmiss | sig_dmmufault | sig_inthigh | sig_syscall |sig_trap | (|ex_exceptflags))
| extend_flush);
 
//
// Exception FSM that sequences execution of exception handler
//
// except_type signals which exception handler we start fetching in:
// 1. Asserted in next clock cycle after exception is recognized
//
always @(posedge clk or posedge rst) begin
if (rst) begin
state <= #1 `EXCEPTFSM_IDLE;
except_type <= #1 `EXCEPT_NONE;
extend_flush <= #1 1'b0;
epcr <= #1 32'b0;
eear <= #1 32'b0;
esr <= #1 `SR_WIDTH'b0;
end
else begin
case (state) // synopsys full_case parallel_case
`EXCEPTFSM_IDLE:
if (except_flushpipe) begin
state <= #1 `EXCEPTFSM_FLU1;
extend_flush <= #1 1'b1;
if (ex_dslot) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display(" INFO: Exception during first delay slot instruction.");
// synopsys translate_on
`endif
epcr <= #1 wb_pc;
end
else if (delayed1_ex_dslot) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display(" INFO: Exception during second (NOP) delay slot instruction.");
// synopsys translate_on
`endif
epcr <= #1 id_pc;
end
else if (delayed2_ex_dslot) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display(" INFO: Exception during third delay slot (SHOULD NOT HAPPEN).");
// synopsys translate_on
`endif
epcr <= #1 id_pc;
end
else begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display(" INFO: Exception during normal (no delay slot) instruction.");
// synopsys translate_on
`endif
epcr <= #1 ex_pc;
end
esr <= #1 sr;
eear <= #1 lsu_addr;
casex (except_trig)
13'b1_xxxx_xxxx_xxxx:
except_type <= #1 `EXCEPT_BUSERR;
13'b0_1xxx_xxxx_xxxx:
except_type <= #1 `EXCEPT_ILLEGAL;
13'b0_01xx_xxxx_xxxx:
except_type <= #1 `EXCEPT_ALIGN;
13'b0_0001_xxxx_xxxx:
except_type <= #1 `EXCEPT_RANGE;
13'b0_0000_1xxx_xxxx:
except_type <= #1 `EXCEPT_DTLBMISS;
13'b0_0000_01xx_xxxx:
except_type <= #1 `EXCEPT_DPF;
13'b0_0000_001x_xxxx:
except_type <= #1 `EXCEPT_HPINT;
13'b0_0000_0001_xxxx:
except_type <= #1 `EXCEPT_TRAP;
13'b0_0000_0000_1xxx:
except_type <= #1 `EXCEPT_SYSCALL;
13'b0_0000_0000_01xx:
except_type <= #1 `EXCEPT_ITLBMISS;
13'b0_0000_0000_001x:
except_type <= #1 `EXCEPT_IPF;
13'b0_0000_0000_0001:
except_type <= #1 `EXCEPT_LPINT;
default:
except_type <= #1 `EXCEPT_NONE;
endcase
end
else begin
if (epcr_we)
epcr <= #1 datain;
if (eear_we)
eear <= #1 datain;
if (esr_we)
esr <= #1 datain[`SR_WIDTH-1:0];
end
`EXCEPTFSM_FLU1:
if (!if_stall && !id_freeze)
begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display(" INFO: EPCR0 %h EEAR %h ESR %h", epcr, eear, esr);
// synopsys translate_on
`endif
state <= #1 `EXCEPTFSM_FLU2;
except_type <= #1 `EXCEPT_NONE;
end
`EXCEPTFSM_FLU2:
state <= #1 `EXCEPTFSM_FLU3;
`EXCEPTFSM_FLU3: begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display(" INFO: Exception just finished flushing pipeline.");
// synopsys translate_on
`endif
state <= #1 `EXCEPTFSM_IDLE;
extend_flush <= #1 1'b0;
end
endcase
end
end
 
endmodule
/verilog/or1200.xcv/generic_spram_2048x32.v
0,0 → 1,435
//////////////////////////////////////////////////////////////////////
//// ////
//// Generic Single-Port Synchronous RAM ////
//// ////
//// This file is part of memory library available from ////
//// http://www.opencores.org/cvsweb.shtml/generic_memories/ ////
//// ////
//// Description ////
//// This block is a wrapper with common single-port ////
//// synchronous memory interface for different ////
//// types of ASIC and FPGA RAMs. Beside universal memory ////
//// interface it also provides behavioral model of generic ////
//// single-port synchronous RAM. ////
//// It should be used in all OPENCORES designs that want to be ////
//// portable accross different target technologies and ////
//// independent of target memory. ////
//// ////
//// Supported ASIC RAMs are: ////
//// - Artisan Single-Port Sync RAM ////
//// - Avant! Two-Port Sync RAM (*) ////
//// - Virage Single-Port Sync RAM ////
//// - Virtual Silicon Single-Port Sync RAM ////
//// ////
//// Supported FPGA RAMs are: ////
//// - Xilinx Virtex RAMB4_S16 ////
//// ////
//// To Do: ////
//// - xilinx rams need external tri-state logic ////
//// - fix avant! two-port ram ////
//// - add additional RAMs (Altera etc) ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.1 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/30 05:38:02 lampret
// Adding empty directories required by HDL coding guidelines
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module generic_spram_2048x32(
// Generic synchronous single-port RAM interface
clk, rst, ce, we, oe, addr, di, do
);
 
//
// Default address and data buses width
//
parameter aw = 11;
parameter dw = 32;
 
//
// Generic synchronous single-port RAM interface
//
input clk; // Clock
input rst; // Reset
input ce; // Chip enable input
input we; // Write enable input
input oe; // Output enable input
input [aw-1:0] addr; // address bus inputs
input [dw-1:0] di; // input data bus
output [dw-1:0] do; // output data bus
 
//
// Internal wires and registers
//
 
 
`ifdef ARTISAN_SSP
 
//
// Instantiation of ASIC memory:
//
// Artisan Synchronous Single-Port RAM (ra1sh)
//
art_hdsp_2048x32 #(dw, 1<<aw, aw) artisan_ssp(
.clk(clk),
.cen(~ce),
.wen(~we),
.a(addr),
.d(di),
.oen(~oe),
.q(do)
);
 
`else
 
`ifdef AVANT_ATP
 
//
// Instantiation of ASIC memory:
//
// Avant! Asynchronous Two-Port RAM
//
avant_atp avant_atp(
.web(~we),
.reb(),
.oeb(~oe),
.rcsb(),
.wcsb(),
.ra(addr),
.wa(addr),
.di(di),
.do(do)
);
 
`else
 
`ifdef VIRAGE_SSP
 
//
// Instantiation of ASIC memory:
//
// Virage Synchronous 1-port R/W RAM
//
virage_ssp virage_ssp(
.clk(clk),
.adr(addr),
.d(di),
.we(we),
.oe(oe),
.me(ce),
.q(do)
);
 
`else
 
`ifdef VIRTUALSILICON_SSP
 
//
// Instantiation of ASIC memory:
//
// Virtual Silicon Single-Port Synchronous SRAM
//
virtualsilicon_ssp #(1<<aw, aw-1, dw-1) virtualsilicon_ssp(
.CK(clk),
.ADR(addr),
.DI(di),
.WEN(~we),
.CEN(~ce),
.OEN(~oe),
.DOUT(do)
);
 
`else
 
`ifdef XILINX_RAMB4
 
//
// Instantiation of FPGA memory:
//
// Virtex/Spartan2
//
 
//
// Block 0
//
RAMB4_S2 ramb4_s2_0(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[1:0]),
.EN(ce),
.WE(we),
.DO(do[1:0])
);
 
//
// Block 1
//
RAMB4_S2 ramb4_s2_1(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[3:2]),
.EN(ce),
.WE(we),
.DO(do[3:2])
);
 
//
// Block 2
//
RAMB4_S2 ramb4_s2_2(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[5:4]),
.EN(ce),
.WE(we),
.DO(do[5:4])
);
 
//
// Block 3
//
RAMB4_S2 ramb4_s2_3(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[7:6]),
.EN(ce),
.WE(we),
.DO(do[7:6])
);
 
//
// Block 4
//
RAMB4_S2 ramb4_s2_4(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[9:8]),
.EN(ce),
.WE(we),
.DO(do[9:8])
);
 
//
// Block 5
//
RAMB4_S2 ramb4_s2_5(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[11:10]),
.EN(ce),
.WE(we),
.DO(do[11:10])
);
 
//
// Block 6
//
RAMB4_S2 ramb4_s2_6(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[13:12]),
.EN(ce),
.WE(we),
.DO(do[13:12])
);
 
//
// Block 7
//
RAMB4_S2 ramb4_s2_7(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[15:14]),
.EN(ce),
.WE(we),
.DO(do[15:14])
);
 
//
// Block 8
//
RAMB4_S2 ramb4_s2_8(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[17:16]),
.EN(ce),
.WE(we),
.DO(do[17:16])
);
 
//
// Block 9
//
RAMB4_S2 ramb4_s2_9(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[19:18]),
.EN(ce),
.WE(we),
.DO(do[19:18])
);
 
//
// Block 10
//
RAMB4_S2 ramb4_s2_10(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[21:20]),
.EN(ce),
.WE(we),
.DO(do[21:20])
);
 
//
// Block 11
//
RAMB4_S2 ramb4_s2_11(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[23:22]),
.EN(ce),
.WE(we),
.DO(do[23:22])
);
 
//
// Block 12
//
RAMB4_S2 ramb4_s2_12(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[25:24]),
.EN(ce),
.WE(we),
.DO(do[25:24])
);
 
//
// Block 13
//
RAMB4_S2 ramb4_s2_13(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[27:26]),
.EN(ce),
.WE(we),
.DO(do[27:26])
);
 
//
// Block 14
//
RAMB4_S2 ramb4_s2_14(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[29:28]),
.EN(ce),
.WE(we),
.DO(do[29:28])
);
 
//
// Block 15
//
RAMB4_S2 ramb4_s2_15(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[31:30]),
.EN(ce),
.WE(we),
.DO(do[31:30])
);
 
`else
 
//
// Generic single-port synchronous RAM model
//
 
//
// Generic RAM's registers and wires
//
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
reg [dw-1:0] do_reg; // RAM data output register
 
//
// Data output drivers
//
assign do = (oe) ? do_reg : {dw{1'bz}};
 
//
// RAM read and write
//
always @(posedge clk)
if (ce && !we)
do_reg <= #1 mem[addr];
else if (ce && we)
mem[addr] <= #1 di;
 
`endif // !XILINX_RAMB4_S16
`endif // !VIRTUALSILICON_SSP
`endif // !VIRAGE_SSP
`endif // !AVANT_ATP
`endif // !ARTISAN_SSP
 
endmodule
/verilog/or1200.xcv/xcv_ram32x8d.v
0,0 → 1,245
//////////////////////////////////////////////////////////////////////
//// ////
//// Xilinx Virtex RAM 32x8D ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Virtex dual-port memory ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.1 2001/08/09 13:39:33 lampret
// Major clean-up.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
`ifdef XILINX_RAM32X1D
 
module xcv_ram32x8d (DPO, SPO, A, D, DPRA, WCLK, WE);
 
//
// I/O
//
output [7:0] DPO;
output [7:0] SPO;
input [4:0] A;
input [4:0] DPRA;
input [7:0] D;
input WCLK;
input WE;
 
//
// Instantiation of block 0
//
RAM32X1D ram32x1d_0(
.DPO(DPO[0]),
.SPO(SPO[0]),
.A0(A[0]),
.A1(A[1]),
.A2(A[2]),
.A3(A[3]),
.A4(A[4]),
.D(D[0]),
.DPRA0(DPRA[0]),
.DPRA1(DPRA[1]),
.DPRA2(DPRA[2]),
.DPRA3(DPRA[3]),
.DPRA4(DPRA[4]),
.WCLK(WCLK),
.WE(WE)
);
 
//
// Instantiation of block 1
//
RAM32X1D ram32x1d_1(
.DPO(DPO[1]),
.SPO(SPO[1]),
.A0(A[0]),
.A1(A[1]),
.A2(A[2]),
.A3(A[3]),
.A4(A[4]),
.D(D[1]),
.DPRA0(DPRA[0]),
.DPRA1(DPRA[1]),
.DPRA2(DPRA[2]),
.DPRA3(DPRA[3]),
.DPRA4(DPRA[4]),
.WCLK(WCLK),
.WE(WE)
);
 
//
// Instantiation of block 2
//
RAM32X1D ram32x1d_2(
.DPO(DPO[2]),
.SPO(SPO[2]),
.A0(A[0]),
.A1(A[1]),
.A2(A[2]),
.A3(A[3]),
.A4(A[4]),
.D(D[2]),
.DPRA0(DPRA[0]),
.DPRA1(DPRA[1]),
.DPRA2(DPRA[2]),
.DPRA3(DPRA[3]),
.DPRA4(DPRA[4]),
.WCLK(WCLK),
.WE(WE)
);
 
//
// Instantiation of block 3
//
RAM32X1D ram32x1d_3(
.DPO(DPO[3]),
.SPO(SPO[3]),
.A0(A[0]),
.A1(A[1]),
.A2(A[2]),
.A3(A[3]),
.A4(A[4]),
.D(D[3]),
.DPRA0(DPRA[0]),
.DPRA1(DPRA[1]),
.DPRA2(DPRA[2]),
.DPRA3(DPRA[3]),
.DPRA4(DPRA[4]),
.WCLK(WCLK),
.WE(WE)
);
 
//
// Instantiation of block 4
//
RAM32X1D ram32x1d_4(
.DPO(DPO[4]),
.SPO(SPO[4]),
.A0(A[0]),
.A1(A[1]),
.A2(A[2]),
.A3(A[3]),
.A4(A[4]),
.D(D[4]),
.DPRA0(DPRA[0]),
.DPRA1(DPRA[1]),
.DPRA2(DPRA[2]),
.DPRA3(DPRA[3]),
.DPRA4(DPRA[4]),
.WCLK(WCLK),
.WE(WE)
);
 
//
// Instantiation of block 5
//
RAM32X1D ram32x1d_5(
.DPO(DPO[5]),
.SPO(SPO[5]),
.A0(A[0]),
.A1(A[1]),
.A2(A[2]),
.A3(A[3]),
.A4(A[4]),
.D(D[5]),
.DPRA0(DPRA[0]),
.DPRA1(DPRA[1]),
.DPRA2(DPRA[2]),
.DPRA3(DPRA[3]),
.DPRA4(DPRA[4]),
.WCLK(WCLK),
.WE(WE)
);
 
//
// Instantiation of block 6
//
RAM32X1D ram32x1d_6(
.DPO(DPO[6]),
.SPO(SPO[6]),
.A0(A[0]),
.A1(A[1]),
.A2(A[2]),
.A3(A[3]),
.A4(A[4]),
.D(D[6]),
.DPRA0(DPRA[0]),
.DPRA1(DPRA[1]),
.DPRA2(DPRA[2]),
.DPRA3(DPRA[3]),
.DPRA4(DPRA[4]),
.WCLK(WCLK),
.WE(WE)
);
 
//
// Instantiation of block 7
//
RAM32X1D ram32x1d_7(
.DPO(DPO[7]),
.SPO(SPO[7]),
.A0(A[0]),
.A1(A[1]),
.A2(A[2]),
.A3(A[3]),
.A4(A[4]),
.D(D[7]),
.DPRA0(DPRA[0]),
.DPRA1(DPRA[1]),
.DPRA2(DPRA[2]),
.DPRA3(DPRA[3]),
.DPRA4(DPRA[4]),
.WCLK(WCLK),
.WE(WE)
);
 
endmodule
 
`endif
/verilog/or1200.xcv/itlb.v
0,0 → 1,219
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Insn TLB ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Instantiation of ITLB. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
//
// Insn TLB
//
 
module itlb(
// Rst and clk
clk, rst,
 
// I/F for translation
tlb_en, vaddr, hit, ppn, uxe, sxe,
 
// SPR access
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o
);
 
parameter dw = `OPERAND_WIDTH;
parameter aw = `OPERAND_WIDTH;
 
//
// I/O
//
 
//
// Clock and reset
//
input clk;
input rst;
 
//
// I/F for translation
//
input tlb_en;
input [aw-1:0] vaddr;
output hit;
output [31:13] ppn;
output uxe;
output sxe;
 
//
// SPR access
//
input spr_cs;
input spr_write;
input [31:0] spr_addr;
input [31:0] spr_dat_i;
output [31:0] spr_dat_o;
 
//
// Internal wires and regs
//
wire [31:19] vpn;
wire v;
wire [5:0] tlb_index;
wire tlb_mr_en;
wire tlb_mr_we;
wire [13:0] tlb_mr_ram_in;
wire [13:0] tlb_mr_ram_out;
wire tlb_tr_en;
wire tlb_tr_we;
wire [20:0] tlb_tr_ram_in;
wire [20:0] tlb_tr_ram_out;
 
//
// Implemented bits inside match and translate registers
//
// itlbwYmrX: vpn 31-19 v 0
// itlbwYtrX: ppn 31-13 uxe 7 sxe 6
//
// itlb memory width:
// 19 bits for ppn
// 13 bits for vpn
// 1 bit for valid
// 2 bits for protection
 
//
// Enable for Match registers
//
assign tlb_mr_en = tlb_en | (spr_cs & !spr_addr[9]);
 
//
// Write enable for Match registers
//
assign tlb_mr_we = spr_cs & spr_write & !spr_addr[9];
 
//
// Enable for Translate registers
//
assign tlb_tr_en = tlb_en | (spr_cs & spr_addr[9]);
 
//
// Write enable for Translate registers
//
assign tlb_tr_we = spr_cs & spr_write & spr_addr[9];
 
//
// Output to SPRS unit
//
assign spr_dat_o = (spr_cs & !spr_write & !spr_addr[9]) ?
{vpn, {18{1'b1}}, v} :
(spr_cs & !spr_write & spr_addr[9]) ?
{ppn, 5'b00000, uxe, sxe, {6{1'b1}}} :
32'h00000000;
 
//
// Assign outputs from Match registers
//
assign {vpn, v} = tlb_mr_ram_out;
 
//
// Assign to Match registers inputs
//
assign tlb_mr_ram_in = {spr_dat_i[31:19], spr_dat_i[0]};
 
//
// Assign outputs from Translate registers
//
assign {ppn, uxe, sxe} = tlb_tr_ram_out;
 
//
// Assign to Translate registers inputs
//
assign tlb_tr_ram_in = {spr_dat_i[31:13], spr_dat_i[7:6]};
 
//
// Generate hit
//
assign hit = (vpn == vaddr[31:19]) & v;
 
//
// TLB index is normally vaddr[18:13]. If it is SPR access then index is
// spr_addr[5:0].
//
assign tlb_index = spr_cs ? spr_addr[5:0] : vaddr[18:13];
 
//
// Instantiation of ITLB Match Registers
//
generic_spram_64x14 itlb_mr_ram(
.clk(clk),
.rst(rst),
.ce(tlb_mr_en),
.we(tlb_mr_we),
.oe(1'b1),
.addr(tlb_index),
.di(tlb_mr_ram_in),
.do(tlb_mr_ram_out)
);
 
//
// Instantiation of ITLB Translate Registers
//
generic_spram_64x21 itlb_tr_ram(
.clk(clk),
.rst(rst),
.ce(tlb_tr_en),
.we(tlb_tr_we),
.oe(1'b1),
.addr(tlb_index),
.di(tlb_tr_ram_in),
.do(tlb_tr_ram_out)
);
 
endmodule
/verilog/or1200.xcv/ic_ram.v
0,0 → 1,114
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's IC RAMs ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Instantiation of Instruction cache data rams ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.3 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/22 03:31:54 lampret
// Fixed RAM's oen bug. Cache bypass under development.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module ic_ram(
// Clock and reset
clk, rst,
 
// Internal i/f
addr, en, we, datain, dataout
);
 
parameter dw = `OPERAND_WIDTH;
parameter aw = `ICINDX;
 
//
// I/O
//
input clk;
input rst;
input [aw-1:0] addr;
input en;
input [3:0] we;
input [dw-1:0] datain;
output [dw-1:0] dataout;
 
`ifdef OR1200_NO_IC
 
//
// Insn cache not implemented
//
assign dataout = {dw{1'b0}};
 
`else
 
//
// Instantiation of 2048x32 RAM block
//
generic_spram_2048x32 ic_ram0(
.clk(clk),
.rst(rst),
.ce(en),
.we(we[0]),
.oe(1'b1),
.addr(addr),
.di(datain),
.do(dataout)
);
 
`endif
 
endmodule
 
/verilog/or1200.xcv/generic_spram_512x20.v
0,0 → 1,292
//////////////////////////////////////////////////////////////////////
//// ////
//// Generic Single-Port Synchronous RAM ////
//// ////
//// This file is part of memory library available from ////
//// http://www.opencores.org/cvsweb.shtml/generic_memories/ ////
//// ////
//// Description ////
//// This block is a wrapper with common single-port ////
//// synchronous memory interface for different ////
//// types of ASIC and FPGA RAMs. Beside universal memory ////
//// interface it also provides behavioral model of generic ////
//// single-port synchronous RAM. ////
//// It should be used in all OPENCORES designs that want to be ////
//// portable accross different target technologies and ////
//// independent of target memory. ////
//// ////
//// Supported ASIC RAMs are: ////
//// - Artisan Single-Port Sync RAM ////
//// - Avant! Two-Port Sync RAM (*) ////
//// - Virage Single-Port Sync RAM ////
//// - Virtual Silicon Single-Port Sync RAM ////
//// ////
//// Supported FPGA RAMs are: ////
//// - Xilinx Virtex RAMB4_S16 ////
//// ////
//// To Do: ////
//// - xilinx rams need external tri-state logic ////
//// - fix avant! two-port ram ////
//// - add additional RAMs (Altera etc) ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.1 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/30 05:38:02 lampret
// Adding empty directories required by HDL coding guidelines
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module generic_spram_512x20(
// Generic synchronous single-port RAM interface
clk, rst, ce, we, oe, addr, di, do
);
 
//
// Default address and data buses width
//
parameter aw = 9;
parameter dw = 20;
 
//
// Generic synchronous single-port RAM interface
//
input clk; // Clock
input rst; // Reset
input ce; // Chip enable input
input we; // Write enable input
input oe; // Output enable input
input [aw-1:0] addr; // address bus inputs
input [dw-1:0] di; // input data bus
output [dw-1:0] do; // output data bus
 
//
// Internal wires and registers
//
 
 
`ifdef ARTISAN_SSP
 
//
// Instantiation of ASIC memory:
//
// Artisan Synchronous Single-Port RAM (ra1sh)
//
art_hssp_512x20 #(dw, 1<<aw, aw) artisan_ssp(
.clk(clk),
.cen(~ce),
.wen(~we),
.a(addr),
.d(di),
.oen(~oe),
.q(do)
);
 
`else
 
`ifdef AVANT_ATP
 
//
// Instantiation of ASIC memory:
//
// Avant! Asynchronous Two-Port RAM
//
avant_atp avant_atp(
.web(~we),
.reb(),
.oeb(~oe),
.rcsb(),
.wcsb(),
.ra(addr),
.wa(addr),
.di(di),
.do(do)
);
 
`else
 
`ifdef VIRAGE_SSP
 
//
// Instantiation of ASIC memory:
//
// Virage Synchronous 1-port R/W RAM
//
virage_ssp virage_ssp(
.clk(clk),
.adr(addr),
.d(di),
.we(we),
.oe(oe),
.me(ce),
.q(do)
);
 
`else
 
`ifdef VIRTUALSILICON_SSP
 
//
// Instantiation of ASIC memory:
//
// Virtual Silicon Single-Port Synchronous SRAM
//
virtualsilicon_ssp #(1<<aw, aw-1, dw-1) virtualsilicon_ssp(
.CK(clk),
.ADR(addr),
.DI(di),
.WEN(~we),
.CEN(~ce),
.OEN(~oe),
.DOUT(do)
);
 
`else
 
`ifdef XILINX_RAMB4
 
//
// Instantiation of FPGA memory:
//
// Virtex/Spartan2
//
 
//
// Block 0
//
RAMB4_S4 ramb4_s4_0(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[3:0]),
.EN(ce),
.WE(we),
.DO(do[3:0])
);
 
//
// Block 1
//
RAMB4_S4 ramb4_s4_1(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[7:4]),
.EN(ce),
.WE(we),
.DO(do[7:4])
);
 
//
// Block 2
//
RAMB4_S4 ramb4_s4_2(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[11:8]),
.EN(ce),
.WE(we),
.DO(do[11:8])
);
 
//
// Block 3
//
RAMB4_S4 ramb4_s4_3(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[15:12]),
.EN(ce),
.WE(we),
.DO(do[15:12])
);
 
//
// Block 4
//
RAMB4_S4 ramb4_s4_4(
.CLK(clk),
.RST(rst),
.ADDR(addr),
.DI(di[19:16]),
.EN(ce),
.WE(we),
.DO(do[19:16])
);
 
`else
 
//
// Generic single-port synchronous RAM model
//
 
//
// Generic RAM's registers and wires
//
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
reg [dw-1:0] do_reg; // RAM data output register
 
//
// Data output drivers
//
assign do = (oe) ? do_reg : {dw{1'bz}};
 
//
// RAM read and write
//
always @(posedge clk)
if (ce && !we)
do_reg <= #1 mem[addr];
else if (ce && we)
mem[addr] <= #1 di;
 
`endif // !XILINX_RAMB4_S16
`endif // !VIRTUALSILICON_SSP
`endif // !VIRAGE_SSP
`endif // !AVANT_ATP
`endif // !ARTISAN_SSP
 
endmodule
/verilog/or1200.xcv/ic_fsm.v
0,0 → 1,250
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's IC FSM ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Instruction cache state machine ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.3 2001/08/17 08:01:19 lampret
// IC enable/disable.
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
`define ICFSM_IDLE 3'd0
`define ICFSM_DOLOAD 3'd1
`define ICFSM_LREFILL3 3'd2
 
//
// Insn cache FSM for cache line of 16 bytes (4x singleword)
//
module ic_fsm(
// Clock and reset
clk, rst,
// Internal i/f
fetch_op, miss, biudata_valid, start_addr, saved_addr, refill,
refill_first, refill_prepare, icram_we, biu_read, refill_rest,
cntrbusy
);
 
//
// I/O
//
input clk;
input rst;
input miss;
input biudata_valid;
input [31:0] start_addr;
input [`FETCHOP_WIDTH-1:0] fetch_op;
output [31:0] saved_addr;
output refill;
output refill_first;
output refill_prepare;
output [3:0] icram_we;
output biu_read;
output refill_rest;
output cntrbusy;
 
//
// Internal wires and regs
//
wire icache_off = 1'b0;
reg [31:0] saved_addr;
reg refill;
reg [3:0] icram_we;
reg [2:0] state;
reg [2:0] cnt;
reg refill_first;
reg refill_prepare;
reg biu_read;
reg refill_rest;
reg cntrbusy;
 
//
// Generate ICRAM's write enable
//
always @(refill_first or refill or biudata_valid or fetch_op or start_addr) begin
if (refill_first || !refill)
case(fetch_op)
`FETCHOP_LW : icram_we = 4'b0000 ^ {4{refill_first}};
default : icram_we = 4'b0000;
endcase
else
icram_we = {4{refill & biudata_valid}};
end
 
//
// Main IC FSM
//
always @(posedge clk or posedge rst) begin
if (rst) begin
refill <= #1 1'b0;
state <= #1 `ICFSM_IDLE;
biu_read <= #1 1'b0;
saved_addr <= #1 32'b0;
refill_first <= #1 1'b0;
refill_prepare <= #1 1'b0;
refill_rest <= #1 1'b0;
cntrbusy <= #1 1'b0;
cnt <= #1 3'b0;
end
else
case (state) // synopsys full_case parallel_case
`ICFSM_IDLE :
case(fetch_op)
`FETCHOP_LW: begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: IC_FSM Load op %h start_addr %h", $time, fetch_op, start_addr);
// synopsys translate_on
`endif
state <= #1 `ICFSM_DOLOAD;
refill <= #1 1'b0;
saved_addr <= #1 start_addr;
refill_first <= #1 1'b0;
refill_prepare <= #1 1'b1;
biu_read <= #1 1'b0;
refill_rest <= #1 1'b0;
cntrbusy <= #1 1'b0;
end
default: begin
state <= #1 `ICFSM_IDLE;
refill <= #1 1'b0;
refill_first <= #1 1'b0;
refill_prepare <= #1 1'b0;
refill_rest <= #1 1'b0;
biu_read <= #1 1'b0;
cntrbusy <= #1 1'b0;
end
endcase
`ICFSM_DOLOAD:
if (icache_off) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: IC_FSM ICache off", $time);
// synopsys translate_on
`endif
state <= #1 `ICFSM_DOLOAD;
refill <= #1 1'b1;
refill_first <= #1 1'b1;
refill_prepare <= #1 1'b0;
refill_rest <= #1 1'b0;
biu_read <= #1 1'b1;
if (biudata_valid) begin
refill <= #1 1'b0;
refill_first <= #1 1'b0;
biu_read <= #1 1'b0;
saved_addr <= #1 start_addr;
end
end else
if (miss) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: IC_FSM Load miss", $time);
// synopsys translate_on
`endif
state <= #1 `ICFSM_LREFILL3;
refill <= #1 1'b1;
refill_first <= #1 1'b1;
refill_prepare <= #1 1'b0;
refill_rest <= #1 1'b0;
cnt <= #1 3'd3;
biu_read <= #1 1'b1;
end
else begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: IC_FSM Load hit", $time);
// synopsys translate_on
`endif
state <= #1 `ICFSM_DOLOAD;
saved_addr <= #1 start_addr;
refill <= #1 1'b0;
refill_first <= #1 1'b0;
refill_prepare <= #1 1'b0;
refill_rest <= #1 1'b0;
cntrbusy <= #1 (fetch_op) ? 1'b1 : 1'b0;
end
`ICFSM_LREFILL3 : begin
if (biudata_valid && cnt) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: IC_FSM Load refill %d", $time, cnt);
// synopsys translate_on
`endif
cnt <= #1 cnt - 'd1;
saved_addr[3:2] <= #1 saved_addr[3:2] + 'd1;
refill_first <= #1 1'b0;
end
else if (biudata_valid) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: IC_FSM Load refill end", $time, cnt);
// synopsys translate_on
`endif
state <= #1 `ICFSM_DOLOAD;
saved_addr[3:2] <= #1 saved_addr[3:2] + 'd1;
refill <= #1 1'b1;
refill_first <= #1 1'b0;
biu_read <= #1 1'b0;
cntrbusy <= #1 (fetch_op) ? 1'b1 : 1'b0;
end
refill_rest <= #1 ~refill_first & refill;
end
endcase
end
 
endmodule
/verilog/or1200.xcv/generic_dpram_32x32.v
0,0 → 1,337
//////////////////////////////////////////////////////////////////////
//// ////
//// Generic Double-Port Synchronous RAM ////
//// ////
//// This file is part of memory library available from ////
//// http://www.opencores.org/cvsweb.shtml/generic_memories/ ////
//// ////
//// Description ////
//// This block is a wrapper with common double-port ////
//// synchronous memory interface for different ////
//// types of ASIC and FPGA RAMs. Beside universal memory ////
//// interface it also provides behavioral model of generic ////
//// double-port synchronous RAM. ////
//// It should be used in all OPENCORES designs that want to be ////
//// portable accross different target technologies and ////
//// independent of target memory. ////
//// ////
//// Supported ASIC RAMs are: ////
//// - Artisan Double-Port Sync RAM ////
//// - Avant! Two-Port Sync RAM (*) ////
//// - Virage 2-port Sync RAM ////
//// ////
//// Supported FPGA RAMs are: ////
//// - Xilinx Virtex RAMB4_S16_S16 ////
//// ////
//// To Do: ////
//// - fix Avant! ////
//// - xilinx rams need external tri-state logic ////
//// - add additional RAMs (Altera, VS etc) ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.1 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/30 05:38:02 lampret
// Adding empty directories required by HDL coding guidelines
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module generic_dpram_32x32(
// Generic synchronous double-port RAM interface
clk_a, rst_a, ce_a, oe_a, addr_a, do_a,
clk_b, rst_b, ce_b, we_b, addr_b, di_b
);
 
//
// Default address and data buses width
//
parameter aw = 5;
parameter dw = 32;
 
//
// Generic synchronous double-port RAM interface
//
input clk_a; // Clock
input rst_a; // Reset
input ce_a; // Chip enable input
input oe_a; // Output enable input
input [aw-1:0] addr_a; // address bus inputs
output [dw-1:0] do_a; // output data bus
input clk_b; // Clock
input rst_b; // Reset
input ce_b; // Chip enable input
input we_b; // Write enable input
input [aw-1:0] addr_b; // address bus inputs
input [dw-1:0] di_b; // input data bus
 
//
// Internal wires and registers
//
 
`ifdef ARTISAN_SDP
 
//
// Instantiation of ASIC memory:
//
// Artisan Synchronous Double-Port RAM (ra2sh)
//
art_hsdp_32x32 #(dw, 1<<aw, aw) artisan_sdp(
.qa(do_a),
.clka(clk_a),
.cena(~ce_a),
.wena(1'b1),
.aa(addr_a),
.da(32'h00000000),
.oena(~oe_a),
.qb(),
.clkb(clk_b),
.cenb(~ce_b),
.wenb(~we_b),
.ab(addr_b),
.db(di_b),
.oenb(1'b1)
);
 
`else
 
`ifdef AVANT_ATP
 
//
// Instantiation of ASIC memory:
//
// Avant! Asynchronous Two-Port RAM
//
avant_atp avant_atp(
.web(~we),
.reb(),
.oeb(~oe),
.rcsb(),
.wcsb(),
.ra(addr),
.wa(addr),
.di(di),
.do(do)
);
 
`else
 
`ifdef VIRAGE_STP
 
//
// Instantiation of ASIC memory:
//
// Virage Synchronous 2-port R/W RAM
//
virage_stp virage_stp(
.QA(do_a),
.QB(),
 
.ADRA(addr_a),
.DA(32'h00000000),
.WEA(1'b0),
.OEA(oe_a),
.MEA(ce_a),
.CLKA(clk_a),
 
.ADRB(addr_b),
.DB(di_b),
.WEB(we_b),
.OEB(1'b1),
.MEB(ce_b),
.CLKB(clk_b)
);
 
`else
 
`ifdef XILINX_RAM32X1D
 
//
// Instantiation of FPGA memory:
//
// Virtex/Spartan2
//
 
//
// Block 0
//
xcv_ram32x8d xcv_ram32x8d_0 (
.DPO(do_a[7:0]),
.SPO(),
.A(addr_b),
.D(di_b[7:0]),
.DPRA(addr_a),
.WCLK(clk_b),
.WE(we_b)
);
 
//
// Block 1
//
xcv_ram32x8d xcv_ram32x8d_1 (
.DPO(do_a[15:8]),
.SPO(),
.A(addr_b),
.D(di_b[15:8]),
.DPRA(addr_a),
.WCLK(clk_b),
.WE(we_b)
);
 
 
//
// Block 2
//
xcv_ram32x8d xcv_ram32x8d_2 (
.DPO(do_a[23:16]),
.SPO(),
.A(addr_b),
.D(di_b[23:16]),
.DPRA(addr_a),
.WCLK(clk_b),
.WE(we_b)
);
 
//
// Block 3
//
xcv_ram32x8d xcv_ram32x8d_3 (
.DPO(do_a[31:24]),
.SPO(),
.A(addr_b),
.D(di_b[31:24]),
.DPRA(addr_a),
.WCLK(clk_b),
.WE(we_b)
);
 
`else
 
`ifdef XILINX_RAMB4
 
//
// Instantiation of FPGA memory:
//
// Virtex/Spartan2
//
 
//
// Block 0
//
RAMB4_S16_S16 ramb4_s16_0(
.CLKA(clk_a),
.RSTA(rst_a),
.ADDRA({3'b000, addr_a}),
.DIA(16'h0000),
.ENA(ce_a),
.WEA(1'b0),
.DOA(do_a[15:0]),
 
.CLKB(clk_b),
.RSTB(rst_b),
.ADDRB({3'b000, addr_b}),
.DIB(di_b[15:0]),
.ENB(ce_b),
.WEB(we_b),
.DOB()
);
 
//
// Block 1
//
RAMB4_S16_S16 ramb4_s16_1(
.CLKA(clk_a),
.RSTA(rst_a),
.ADDRA({3'b000, addr_a}),
.DIA(16'h0000),
.ENA(ce_a),
.WEA(1'b0),
.DOA(do_a[31:16]),
 
.CLKB(clk_b),
.RSTB(rst_b),
.ADDRB({3'b000, addr_b}),
.DIB(di_b[31:16]),
.ENB(ce_b),
.WEB(we_b),
.DOB()
);
 
`else
 
//
// Generic double-port synchronous RAM model
//
 
//
// Generic RAM's registers and wires
//
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
reg [dw-1:0] do_reg; // RAM data output register
 
//
// Data output drivers
//
assign do_a = (oe_a) ? do_reg : {dw{1'bz}};
 
//
// RAM read
//
always @(posedge clk_a)
if (ce_a)
do_reg <= #1 mem[addr_a];
 
//
// RAM write
//
always @(posedge clk_b)
if (ce_b && we_b)
mem[addr_b] <= #1 di_b;
 
`endif // !XILINX_RAMB4_S16_S16
`endif // !XILINX_RAM32X1D
`endif // !VIRAGE_STP
`endif // !AVANT_ATP
`endif // !ARTISAN_SDP
 
endmodule
/verilog/or1200.xcv/ifetch.v
0,0 → 1,317
 
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's instruction fetch ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// PC, instruction fetch, interface to IC. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.1 2001/08/09 13:39:33 lampret
// Major clean-up.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module ifetch(
// Clock and reset
clk, rst,
 
// External i/f to IC
ic_insn, ic_addr, ic_stall, ic_fetchop,
 
// Internal i/f
if_freeze, if_insn, if_pc, branch_op, except_type,
branch_addrofs, lr_restor, flag, taken, binsn_addr, except_start,
epcr, force_dslot_fetch, if_stall, branch_stall,
spr_dat_i, spr_pc_we
);
 
//
// I/O
//
 
//
// Clock and reset
//
input clk;
input rst;
 
//
// External i/f to IC
//
input [31:0] ic_insn;
output [31:0] ic_addr;
output [`FETCHOP_WIDTH-1:0] ic_fetchop;
input ic_stall;
 
//
// Internal i/f
//
input if_freeze;
output [31:0] if_insn;
output [31:0] if_pc;
input [`BRANCHOP_WIDTH-1:0] branch_op;
input [`EXCEPT_WIDTH-1:0] except_type;
input [31:2] branch_addrofs;
input [31:0] lr_restor;
input flag;
input [31:2] binsn_addr;
output taken;
input except_start;
input [31:0] epcr;
input force_dslot_fetch;
output if_stall;
output branch_stall;
input [31:0] spr_dat_i;
input spr_pc_we;
 
//
// Internal wires and regs
//
reg [31:2] pcreg;
reg [32:2] dslot_pc;
reg [32:0] if_saved;
reg [31:0] pcaddr;
reg [31:0] pc_saved;
reg taken; /* Set to in case of jump or taken branch */
 
//
// Current registered PC (corresponds to fetched instruction)
//
//assign if_pc = {pcreg[31:2], 2'b00};
assign if_pc = (if_saved[32]) ? pc_saved : ic_addr;
assign ic_addr = dslot_pc[32] ? {dslot_pc[31:2], 2'b00} : pcaddr;
assign branch_stall = dslot_pc[32] & taken;
//assign if_stall = ic_stall | (~branch_stall & taken);
assign if_stall = ic_stall;
 
//
// Control access to IC subsystem
//
assign ic_fetchop = (if_saved[32] & !if_stall) ? `FETCHOP_NOP : `FETCHOP_LW;
 
//
// Just fetched instruction
//
assign if_insn = (if_saved[32]) ? if_saved[31:0] : (ic_stall) ? 32'h1500FFFF : ic_insn;
 
//
// Delay slot PC saved
//
always @(posedge clk or posedge rst)
if (rst)
dslot_pc <= #1 31'h00000000;
// else if (force_dslot_fetch)
// dslot_pc <= #1 {1'b1, pcaddr[31:2]};
else if (!ic_stall)
dslot_pc <= #1 31'h00000000;
 
//
// Async calculation of new PC value. This value is used for addressing the IC.
//
always @(pcreg or branch_addrofs or binsn_addr or flag or branch_op or except_type
or except_start or lr_restor or epcr or spr_pc_we or spr_dat_i) begin
casex ({spr_pc_we, except_start, branch_op}) // synopsys parallel_case
{2'b00, `BRANCHOP_NOP}: begin
pcaddr = {pcreg + 'd1, 2'b0};
taken = 1'b0;
end
{2'b00, `BRANCHOP_J}: begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: BRANCHOP_J: pcaddr <= branch_addrofs %h", $time, branch_addrofs);
// synopsys translate_on
`endif
pcaddr = {branch_addrofs, 2'b0};
taken = 1'b1;
end
{2'b00, `BRANCHOP_JR}: begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: BRANCHOP_JR: pcaddr <= lr_restor %h", $time, lr_restor);
// synopsys translate_on
`endif
pcaddr = lr_restor;
taken = 1'b1;
end
{2'b00, `BRANCHOP_BAL}: begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: BRANCHOP_BAL: pcaddr %h = binsn_addr %h + branch_addrofs %h", $time, binsn_addr + branch_addrofs, binsn_addr, branch_addrofs);
// synopsys translate_on
`endif
pcaddr = {binsn_addr + branch_addrofs, 2'b0};
taken = 1'b1;
end
{2'b00, `BRANCHOP_BF}:
if (flag) begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: BRANCHOP_BF: pcaddr %h = binsn_addr %h + branch_addrofs %h", $time, binsn_addr + branch_addrofs, binsn_addr, branch_addrofs);
// synopsys translate_on
`endif
pcaddr = {binsn_addr + branch_addrofs, 2'b0};
taken = 1'b1;
end
else begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: BRANCHOP_BF: not taken", $time);
// synopsys translate_on
`endif
pcaddr = {pcreg + 'd1, 2'b0};
taken = 1'b0;
end
{2'b00, `BRANCHOP_BNF}:
if (flag) begin
pcaddr = {pcreg + 'd1, 2'b0};
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: BRANCHOP_BNF: not taken", $time);
// synopsys translate_on
`endif
taken = 1'b0;
end
else begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: BRANCHOP_BNF: pcaddr %h = binsn_addr %h + branch_addrofs %h", $time, binsn_addr + branch_addrofs, binsn_addr, branch_addrofs);
// synopsys translate_on
`endif
pcaddr = {binsn_addr + branch_addrofs, 2'b0};
taken = 1'b1;
end
{2'b00, `BRANCHOP_RFE}: begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: BRANCHOP_RFE: pcaddr <= epcr %h", $time, epcr);
// synopsys translate_on
`endif
pcaddr = epcr;
taken = 1'b1;
end
{2'b01, 3'bxxx}: begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("Starting exception: %h.", except_type);
// synopsys translate_on
`endif
pcaddr = { 20'h0_0000, except_type, 8'h00};
taken = 1'b1;
end
default: begin
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("l.mtspr writing into PC: %h.", spr_dat_i);
// synopsys translate_on
`endif
pcaddr = spr_dat_i;
taken = 1'b0;
end
endcase
end
 
//
// PC register
//
always @(posedge clk or posedge rst) begin
if (rst)
pcreg <= #1 30'd64;
else if (spr_pc_we)
pcreg <= #1 spr_dat_i[31:2];
else if (!if_freeze && !ic_stall) begin
pcreg <= #1 ic_addr[31:2];
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: pcreg incremented to %h", $time, {ic_addr[31:2], 2'b0});
// synopsys translate_on
`endif
end
end
 
//
// Stores INSN when pipeline is frozen
//
always @(posedge clk or posedge rst)
if (rst) begin
if_saved <= #1 33'b0;
end
else if (if_freeze && !if_saved[32] && !ic_stall) begin // && !taken
if_saved <= #1 {1'b1, ic_insn};
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: if_saved <= %h", $time, {1'b1, ic_insn});
// synopsys translate_on
`endif
end
else if (!if_freeze) begin
if_saved[32] <= #1 1'b0;
if_saved[31:0] <= #1 32'h1500eeee;
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display("%t: if_saved[32] <= 0", $time);
// synopsys translate_on
`endif
end
 
//
// Stores PC when pipeline is frozen
//
always @(posedge clk or posedge rst)
if (rst) begin
pc_saved <= #1 32'b0;
end
else if (if_freeze && !if_saved[32] && !ic_stall) begin // && !taken
pc_saved <= #1 ic_addr;
end
else if (!if_freeze) begin
pc_saved <= #1 32'h00000000;
end
 
endmodule
/verilog/or1200.xcv/dmmu.v
0,0 → 1,237
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Data MMU top level ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Instantiation of all DMMU blocks. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.1 2001/08/17 08:03:35 lampret
// *** empty log message ***
//
// Revision 1.2 2001/07/22 03:31:53 lampret
// Fixed RAM's oen bug. Cache bypass under development.
//
// Revision 1.1 2001/07/20 00:46:03 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
//
// Data MMU
//
 
module dmmu(
// Rst and clk
clk, rst,
 
// LSU i/f
dmmu_en, supv, dmmulsu_vaddr, dmmulsu_lsuop, dmmulsu_stall,
 
// Except I/F
dmmuexcept_miss, dmmuexcept_fault,
 
// SPR access
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o,
 
// DC i/f
dcdmmu_paddr
);
 
parameter dw = `OPERAND_WIDTH;
parameter aw = `OPERAND_WIDTH;
 
//
// I/O
//
 
//
// Clock and reset
//
input clk;
input rst;
 
//
// LSU I/F
//
input dmmu_en;
input supv;
input [aw-1:0] dmmulsu_vaddr;
input [`LSUOP_WIDTH-1:0] dmmulsu_lsuop;
output dmmulsu_stall;
 
//
// Exception I/F
//
output dmmuexcept_miss;
output dmmuexcept_fault;
 
//
// SPR access
//
input spr_cs;
input spr_write;
input [aw-1:0] spr_addr;
input [31:0] spr_dat_i;
output [31:0] spr_dat_o;
 
//
// DC I/F
//
output [aw-1:0] dcdmmu_paddr;
 
//
// Internal wires and regs
//
wire dtlb_spr_access;
wire [31:13] dtlb_ppn;
wire dtlb_hit;
wire dtlb_uwe;
wire dtlb_ure;
wire dtlb_swe;
wire dtlb_sre;
wire [31:0] dtlb_dat_o;
 
//
// Implemented bits inside match and translate registers
//
// dtlbwYmrX: vpn 31-10 v 0
// dtlbwYtrX: ppn 31-10 uwe 9 ure 8 swe 7 sre 6
//
// dtlb memory width:
// 19 bits for ppn
// 13 bits for vpn
// 1 bit for valid
// 4 bits for protection
 
`ifdef OR1200_NO_DMMU
 
//
// Put all outputs in inactive state
//
assign dmmulsu_stall = 1'b0;
assign dmmuexcept_miss = 1'b0;
assign dmmuexcept_fault = 1'b0;
assign spr_dat_o = 32'h00000000;
assign dcdmmu_paddr = dmmulsu_vaddr;
 
`else
 
//
// DTLB SPR access
//
// 0C00 - 0E00 dtlbmr w0-3
// 0C00 - 0C80 dtlbmr w0
// 0C00 - 0C40 dtlbmr w0 [63:0]
//
// 0E00 - 1000 dtlbtr w0-3
// 0E00 - 0E80 dtlbtr w0
// 0E00 - 0E40 dtlbtr w0 [63:0]
//
assign dtlb_spr_access = spr_cs & spr_addr[10];
 
//
// Physical address is either translated virtual address or
// simply equal when DMMU is disabled
//
assign dcdmmu_paddr = dmmu_en ? {dtlb_ppn, dmmulsu_vaddr[12:0]} : dmmulsu_vaddr;
 
//
// Output to SPRS unit
//
assign spr_dat_o = dtlb_spr_access ? dtlb_dat_o : 32'h00000000;
 
//
// DMMU stall
//
assign dmmulsu_stall = 1'b0;
 
//
// Page fault exception logic
//
assign dmmuexcept_fault = (|dmmulsu_lsuop) && dmmu_en &&
( (!dmmulsu_lsuop[3] & !supv & !dtlb_ure) // Load in user mode not enabled
|| (!dmmulsu_lsuop[3] & supv & !dtlb_sre) // Load in supv mode not enabled
|| (dmmulsu_lsuop[3] & !supv & !dtlb_uwe) // Store in user mode not enabled
|| (dmmulsu_lsuop[3] & supv & !dtlb_swe) ); // Store in supv mode not enabled
 
//
// TLB Miss exception logic
//
assign dmmuexcept_miss = (|dmmulsu_lsuop) && dmmu_en && !dtlb_hit;
 
//
// Instantiation of DTLB
//
dtlb dtlb(
// Rst and clk
.clk(clk),
.rst(rst),
 
// I/F for translation
.tlb_en(dmmu_en),
.vaddr(dmmulsu_vaddr),
.hit(dtlb_hit),
.ppn(dtlb_ppn),
.uwe(dtlb_uwe),
.ure(dtlb_ure),
.swe(dtlb_swe),
.sre(dtlb_sre),
 
// SPR access
.spr_cs(dtlb_spr_access),
.spr_write(spr_write),
.spr_addr(spr_addr),
.spr_dat_i(spr_dat_i),
.spr_dat_o(dtlb_dat_o)
);
 
`endif
 
endmodule
/verilog/or1200.xcv/wbmux.v
0,0 → 1,152
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Write-back Mux ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// CPU's write-back stage of the pipeline ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.2 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.1 2001/07/20 00:46:23 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module wbmux(
// Clock and reset
clk, rst,
 
// Internal i/f
wb_freeze, rfwb_op,
muxin_a, muxin_b, muxin_c, muxin_d,
muxout, muxreg, muxreg_valid
);
 
parameter width = `OPERAND_WIDTH;
 
//
// I/O
//
 
//
// Clock and reset
//
input clk;
input rst;
 
//
// Internal i/f
//
input wb_freeze;
input [`RFWBOP_WIDTH-1:0] rfwb_op;
input [width-1:0] muxin_a;
input [width-1:0] muxin_b;
input [width-1:0] muxin_c;
input [width-1:0] muxin_d;
output [width-1:0] muxout;
output [width-1:0] muxreg;
output muxreg_valid;
 
//
// Internal wires and regs
//
reg [width-1:0] muxout;
reg [width-1:0] muxreg;
reg muxreg_valid;
 
//
// Registered output from the write-back multiplexer
//
always @(posedge clk or posedge rst) begin
if (rst) begin
muxreg <= #1 32'd0;
muxreg_valid <= #1 1'b0;
end
else if (!wb_freeze) begin
muxreg <= #1 muxout;
muxreg_valid <= #1 rfwb_op[0];
end
end
 
//
// Write-back multiplexer
//
always @(muxin_a or muxin_b or muxin_c or muxin_d or rfwb_op) begin
case(rfwb_op[`RFWBOP_WIDTH-1:1]) // synopsys full_case parallel_case infer_mux
2'b00: muxout = muxin_a;
2'b01: begin
muxout = muxin_b;
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display(" WBMUX: muxin_b %h", muxin_b);
// synopsys translate_on
`endif
end
2'b10: begin
muxout = muxin_c;
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display(" WBMUX: muxin_c %h", muxin_c);
// synopsys translate_on
`endif
end
2'b11: begin
muxout = muxin_d + 4'h8;
`ifdef OR1200_VERBOSE
// synopsys translate_off
$display(" WBMUX: muxin_d %h", muxin_d + 4'h8);
// synopsys translate_on
`endif
end
endcase
end
 
endmodule
/verilog/or1200.xcv/rf.v
0,0 → 1,248
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's register file inside CPU ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Instantiation of register file memories ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:36 igorm
// no message
//
// Revision 1.3 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/22 03:31:54 lampret
// Fixed RAM's oen bug. Cache bypass under development.
//
// Revision 1.1 2001/07/20 00:46:21 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module rf(
// Clock and reset
clk, rst,
 
// Write i/f
addrw, dataw, we,
 
// Read i/f
id_freeze, addra, addrb, dataa, datab,
 
// Debug
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o
);
 
parameter dw = `OPERAND_WIDTH;
parameter aw = `REGFILE_ADDR_WIDTH;
 
//
// I/O
//
 
//
// Clock and reset
//
input clk;
input rst;
 
//
// Write i/f
//
input [aw-1:0] addrw;
input [dw-1:0] dataw;
input we;
 
//
// Read i/f
//
input id_freeze;
input [aw-1:0] addra;
input [aw-1:0] addrb;
output [dw-1:0] dataa;
output [dw-1:0] datab;
 
//
// SPR access for debugging purposes
//
input spr_cs;
input spr_write;
input [31:0] spr_addr;
input [31:0] spr_dat_i;
output [31:0] spr_dat_o;
 
//
// Internal wires and regs
//
wire [dw-1:0] from_rfa;
wire [dw-1:0] from_rfb;
reg [dw:0] dataa_saved;
reg [dw:0] datab_saved;
wire [aw-1:0] rf_addra;
wire [aw-1:0] rf_addrw;
wire [dw-1:0] rf_dataw;
wire rf_we;
wire spr_valid;
 
//
// SPR access is valid when spr_cs is asserted and
// SPR address matches GPR addresses
//
assign spr_valid = spr_cs & (spr_addr[10:5] == `SPR_RF);
 
//
// SPR data output is always from RF A
//
assign spr_dat_o = from_rfa;
 
//
// Operand A comes from RF or from saved A register
//
assign dataa = (dataa_saved[32]) ? dataa_saved[31:0] : from_rfa;
 
//
// Operand B comes from RF or from saved B register
//
assign datab = (datab_saved[32]) ? datab_saved[31:0] : from_rfb;
 
//
// RF A read address is either from SPRS or normal from CPU control
//
assign rf_addra = (spr_valid & !spr_write) ? spr_addr[4:0] : addra;
 
//
// RF write address is either from SPRS or normal from CPU control
//
assign rf_addrw = (spr_valid & spr_write) ? spr_addr[4:0] : addrw;
 
//
// RF write data is either from SPRS or normal from CPU datapath
//
assign rf_dataw = (spr_valid & spr_write) ? spr_dat_i : dataw;
 
//
// RF write enable is either from SPRS or normal from CPU control
//
assign rf_we = (spr_valid & spr_write) | we;
 
//
// Stores operand from RF_A into temp reg when pipeline is frozen
//
always @(posedge clk or posedge rst)
if (rst) begin
dataa_saved <= #1 33'b0;
end
else if (id_freeze & !dataa_saved[32]) begin
dataa_saved <= #1 {1'b1, from_rfa};
end
else if (!id_freeze)
dataa_saved <= #1 33'b0;
 
//
// Stores operand from RF_B into temp reg when pipeline is frozen
//
always @(posedge clk or posedge rst)
if (rst) begin
datab_saved <= #1 33'b0;
end
else if (id_freeze & !datab_saved[32]) begin
datab_saved <= #1 {1'b1, from_rfb};
end
else if (!id_freeze)
datab_saved <= #1 33'b0;
 
//
// Instantiation of register file two-port RAM A
//
generic_dpram_32x32 rf_a(
// Port A
.clk_a(clk),
.rst_a(rst),
.ce_a(1'b1),
// .we_a(1'b0),
.oe_a(1'b1),
.addr_a(rf_addra),
// .di_a(32'h0000_0000),
.do_a(from_rfa),
 
// Port B
.clk_b(clk),
.rst_b(rst),
.ce_b(rf_we),
.we_b(rf_we),
// .oe_b(1'b0),
.addr_b(rf_addrw),
.di_b(rf_dataw)
// .do_b()
);
 
//
// Instantiation of register file two-port RAM B
//
generic_dpram_32x32 rf_b(
// Port A
.clk_a(clk),
.rst_a(rst),
.ce_a(1'b1),
// .we_a(1'b0),
.oe_a(1'b1),
.addr_a(addrb),
// .di_a(32'h0000_0000),
.do_a(from_rfb),
 
// Port B
.clk_b(clk),
.rst_b(rst),
.ce_b(rf_we),
.we_b(rf_we),
// .oe_b(1'b0),
.addr_b(rf_addrw),
.di_b(rf_dataw)
// .do_b()
);
 
endmodule
/verilog/or1200.xcv/wb_biu.v
0,0 → 1,200
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's WISHBONE BIU ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Implements WISHBONE interface ////
//// ////
//// To Do: ////
//// - add support for wb_err_i ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:18:35 igorm
// no message
//
// Revision 1.3 2001/08/09 13:39:33 lampret
// Major clean-up.
//
// Revision 1.2 2001/07/22 03:31:54 lampret
// Fixed RAM's oen bug. Cache bypass under development.
//
// Revision 1.1 2001/07/20 00:46:23 lampret
// Development version of RTL. Libraries are missing.
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
module wb_biu(
// WISHBONE interface
wb_clk_i, wb_rst_i, wb_ack_i, wb_err_i, wb_rty_i, wb_dat_i,
wb_cyc_o, wb_adr_o, wb_stb_o, wb_we_o, wb_sel_o, wb_dat_o,
 
// Internal RISC bus
biu_to_biu, biu_addr, biu_read, biu_write, biu_rdy, biu_from_biu, biu_sel
);
 
parameter dw = `OPERAND_WIDTH;
parameter aw = `OPERAND_WIDTH;
 
//
// WISHBONE interface
//
input wb_clk_i; // clock input
input wb_rst_i; // reset input
input wb_ack_i; // normal termination
input wb_err_i; // termination w/ error
input wb_rty_i; // termination w/ retry
input [dw-1:0] wb_dat_i; // input data bus
output wb_cyc_o; // cycle valid output
output [aw-1:0] wb_adr_o; // address bus outputs
output wb_stb_o; // strobe output
output wb_we_o; // indicates write transfer
output [3:0] wb_sel_o; // byte select outputs
output [dw-1:0] wb_dat_o; // output data bus
 
//
// Internal RISC interface
//
input [dw-1:0] biu_to_biu; // input data bus
input [aw-1:0] biu_addr; // address bus
input biu_read; // read request
input biu_write; // write request
output biu_rdy; // data valid
output [dw-1:0] biu_from_biu; // output data bus
input [3:0] biu_sel; // byte select inputs
 
//
// Registers
//
`ifdef OR1200_REGISTERED_OUTPUTS
reg [aw-1:0] wb_adr_o; // address bus outputs
reg wb_stb_o; // strobe output
reg wb_we_o; // indicates write transfer
reg [3:0] wb_sel_o; // byte select outputs
reg [dw-1:0] wb_dat_o; // output data bus
`endif
 
//
// WISHBONE I/F <-> Internal RISC I/F conversion
//
 
//
// Address bus
//
`ifdef OR1200_REGISTERED_OUTPUTS
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
wb_adr_o <= #1 {aw{1'b0}};
else
wb_adr_o <= #1 biu_addr;
`else
assign wb_adr_o = biu_addr;
`endif
 
//
// Input data bus
//
assign biu_from_biu = wb_dat_i;
 
//
// Output data bus
//
`ifdef OR1200_REGISTERED_OUTPUTS
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
wb_dat_o <= #1 {dw{1'b0}};
else
wb_dat_o <= #1 biu_to_biu;
`else
assign wb_dat_o = biu_to_biu;
`endif
 
//
// Acknowledgment of the data to the RISC
//
assign biu_rdy = wb_ack_i;
 
//
// WB cyc_o
//
assign wb_cyc_o = wb_stb_o;
 
//
// WB stb_o
//
`ifdef OR1200_REGISTERED_OUTPUTS
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
wb_stb_o <= #1 1'b0;
else
wb_stb_o <= #1 (biu_read | biu_write);
`else
assign wb_stb_o = (biu_read | biu_write);
`endif
 
//
// WB we_o
//
`ifdef OR1200_REGISTERED_OUTPUTS
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
wb_we_o <= #1 1'b0;
else
wb_we_o <= #1 biu_write;
`else
assign wb_we_o = biu_write;
`endif
 
//
// WB sel_o
//
`ifdef OR1200_REGISTERED_OUTPUTS
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
wb_sel_o <= #1 4'b0000;
else
wb_sel_o <= #1 biu_sel;
`else
assign wb_sel_o = biu_sel;
`endif
 
endmodule
/verilog/or1200.xcv/du.v
0,0 → 1,334
//////////////////////////////////////////////////////////////////////
//// ////
//// OR1200's Debug Unit ////
//// ////
//// This file is part of the OpenRISC 1200 project ////
//// http://www.opencores.org/cores/or1k/ ////
//// ////
//// Description ////
//// Basic OR1200 debug unit. ////
//// ////
//// To Do: ////
//// - make it smaller and faster ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "defines.v"
 
//
// Debug unit
//
 
module du(
// RISC Internal Interface
clk, rst,
dclsu_lsuop, icfetch_op, ex_freeze, branch_op,
du_stall, du_addr, du_dat_i, du_dat_o, du_read, du_write, du_except,
spr_cs, spr_write, spr_addr, spr_dat_i, spr_dat_o,
 
// External Debug Interface
dbg_stall_i, dbg_dat_i, dbg_adr_i, dbg_op_i, dbg_ewt_i,
dbg_lss_o, dbg_is_o, dbg_wp_o, dbg_bp_o, dbg_dat_o
);
 
parameter dw = `OPERAND_WIDTH;
parameter aw = `OPERAND_WIDTH;
 
//
// I/O
//
 
//
// RISC Internal Interface
//
input clk; // Clock
input rst; // Reset
input [`LSUOP_WIDTH-1:0] dclsu_lsuop; // LSU status
input [`FETCHOP_WIDTH-1:0] icfetch_op; // IFETCH unit status
input ex_freeze; // EX stage freeze
input [`BRANCHOP_WIDTH-1:0] branch_op; // Branch op
output du_stall; // Debug Unit Stall
output [aw-1:0] du_addr; // Debug Unit Address
input [dw-1:0] du_dat_i; // Debug Unit Data In
output [dw-1:0] du_dat_o; // Debug Unit Data Out
output du_read; // Debug Unit Read Enable
output du_write; // Debug Unit Write Enable
input [`EXCEPT_WIDTH-1:0] du_except; // Exception started
input spr_cs; // SPR Chip Select
input spr_write; // SPR Read/Write
input [aw-1:0] spr_addr; // SPR Address
input [dw-1:0] spr_dat_i; // SPR Data Input
output [dw-1:0] spr_dat_o; // SPR Data Output
 
//
// External Debug Interface
//
input dbg_stall_i; // External Stall Input
input [dw-1:0] dbg_dat_i; // External Data Input
input [aw-1:0] dbg_adr_i; // External Address Input
input [2:0] dbg_op_i; // External Operation Select Input
input dbg_ewt_i; // External Watchpoint Trigger Input
output [3:0] dbg_lss_o; // External Load/Store Unit Status
output [1:0] dbg_is_o; // External Insn Fetch Status
output [10:0] dbg_wp_o; // Watchpoints Outputs
output dbg_bp_o; // Breakpoint Output
output [dw-1:0] dbg_dat_o; // External Data Output
 
 
//
// Some connections go directly from the CPU through DU to Debug I/F
//
assign dbg_lss_o = dclsu_lsuop;
assign dbg_is_o = icfetch_op;
assign dbg_wp_o = 11'b000_0000_0000;
assign dbg_dat_o = du_dat_i;
 
//
// Some connections go directly from Debug I/F through DU to the CPU
//
assign du_stall = dbg_stall_i;
assign du_addr = dbg_adr_i;
assign du_dat_o = dbg_dat_i;
assign du_read = (dbg_op_i == `DU_OP_READSPR);
assign du_write = (dbg_op_i == `DU_OP_WRITESPR);
 
`ifdef DU_IMPLEMENTED
 
//
// Debug Mode Register 1 (only ST and BT implemented)
//
`ifdef DU_DMR1
reg [23:22] dmr1; // DMR1 implemented (ST & BT)
`else
wire [23:22] dmr1; // DMR1 not implemented
`endif
 
//
// Debug Mode Register 2 (not implemented)
//
`ifdef DU_DMR2
wire [31:0] dmr2; // DMR not implemented
`endif
 
//
// Debug Stop Register
//
`ifdef DU_DSR
reg [13:0] dsr; // DSR implemented
`else
wire [13:0] dsr; // DSR not implemented
`endif
 
//
// Debug Reason Register
//
`ifdef DU_DRR
reg [13:0] drr; // DRR implemented
reg [13:0] except_unmasked;
`else
wire [13:0] drr; // DRR not implemented
`endif
 
//
// Internal wires
//
wire [13:0] except_masked;
wire dmr1_sel; // DMR1 select
wire dsr_sel; // DSR select
wire drr_sel; // DRR select
reg dbg_bp_r;
`ifdef DU_READREGS
reg [31:0] spr_dat_o;
`endif
 
//
// DU registers address decoder
//
`ifdef DU_DMR1
assign dmr1_sel = (spr_cs && (spr_addr[`SPROFS_BITS] == `DU_OFS_DMR1));
`endif
`ifdef DU_DSR
assign dsr_sel = (spr_cs && (spr_addr[`SPROFS_BITS] == `DU_OFS_DSR));
`endif
`ifdef DU_DRR
assign drr_sel = (spr_cs && (spr_addr[`SPROFS_BITS] == `DU_OFS_DRR));
`endif
 
//
// Decode started exception
//
always @(du_except)
case (du_except)
4'he: except_unmasked = 14'b10_0000_0000_0000;
4'hd: except_unmasked = 14'b01_0000_0000_0000;
4'hc: except_unmasked = 14'b00_1000_0000_0000;
4'hb: except_unmasked = 14'b00_0100_0000_0000;
4'ha: except_unmasked = 14'b00_0010_0000_0000;
4'h9: except_unmasked = 14'b00_0001_0000_0000;
4'h8: except_unmasked = 14'b00_0000_1000_0000;
4'h7: except_unmasked = 14'b00_0000_0100_0000;
4'h6: except_unmasked = 14'b00_0000_0010_0000;
4'h5: except_unmasked = 14'b00_0000_0001_0000;
4'h4: except_unmasked = 14'b00_0000_0000_1000;
4'h3: except_unmasked = 14'b00_0000_0000_0100;
4'h2: except_unmasked = 14'b00_0000_0000_0010;
4'h1: except_unmasked = 14'b00_0000_0000_0001;
default: except_unmasked = 14'b00_0000_0000_0000;
endcase
 
//
// Get only 'stop' exceptions
//
assign except_masked = dsr & except_unmasked;
 
//
// dbg_bp_o is registered
//
assign dbg_bp_o = dbg_bp_r;
 
//
// Breakpoint activation register
//
always @(posedge clk or posedge rst)
if (rst)
dbg_bp_r <= #1 1'b0;
else
dbg_bp_r <= |except_masked
`ifdef DU_DMR1_ST
| ~ex_freeze & dmr1[`DU_DMR1_ST]
`endif
`ifdef DU_DMR1_BT
| ~ex_freeze & (branch_op != `BRANCHOP_NOP) & dmr1[`DU_DMR1_BT]
`endif
;
 
//
// Write to DMR1
//
`ifdef DU_DMR1
always @(posedge clk or posedge rst)
if (rst)
dmr1 <= 2'b00;
else if (dmr1_sel && spr_write)
dmr1 <= #1 spr_dat_i[23:22];
`else
assign dmr1 = 2'b00;
`endif
 
//
// DMR2 bits tied to zero
//
`ifdef DU_DMR2
assign dmr2 = 32'h0000_0000;
`endif
 
//
// Write to DSR
//
`ifdef DU_DSR
always @(posedge clk or posedge rst)
if (rst)
dsr <= 14'b0;
else if (dsr_sel && spr_write)
dsr <= #1 spr_dat_i[13:0];
`else
assign dsr = 14'b0;
`endif
 
//
// Write to DRR
//
`ifdef DU_DRR
always @(posedge clk or posedge rst)
if (rst)
drr <= 14'b0;
else if (drr_sel && spr_write)
drr <= #1 spr_dat_i[13:0];
else
drr <= #1 drr | except_masked;
`else
assign drr = 14'b0;
`endif
 
//
// Read DU registers
//
`ifdef DU_READREGS
always @(spr_addr or dsr or drr)
case (spr_addr[`SPROFS_BITS])
`ifdef DU_DMR1
`DU_OFS_DMR1:
spr_dat_o = {8'b0, dmr1, 22'b0};
`endif
`ifdef DU_DMR2
`DU_OFS_DMR2:
spr_dat_o = dmr2;
`endif
`ifdef DU_DSR
`DU_OFS_DSR:
spr_dat_o = {18'b0, dsr};
`endif
`ifdef DU_DRR
`DU_OFS_DRR:
spr_dat_o = {18'b0, drr};
`endif
default:
spr_dat_o = 32'h0000_0000;
endcase
`endif
 
`else
 
//
// When DU is not implemented, drive all outputs as would when DU is disabled
//
assign dbg_bp_o = 1'b0;
 
//
// Read DU registers
//
`ifdef DU_READREGS
assign spr_dat_o = 32'h0000_0000;
`ifdef DU_UNUSED_ZERO
`endif
`endif
 
`endif
 
endmodule
/verilog/ssvga/ssvga_wbs_if.v
0,0 → 1,178
//////////////////////////////////////////////////////////////////////
//// ////
//// Simple Small VGA IP Core ////
//// ////
//// This file is part of the Simple Small VGA project ////
//// ////
//// ////
//// Description ////
//// LITTLE-ENDIAN WISHBONE slave interface. ////
//// ////
//// To Do: ////
//// Nothing ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:19:09 igorm
// no message
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
`define SEL_PAL 10
`define SEL_ADDRESS 2
 
module ssvga_wbs_if(
// Clock and reset
wb_clk_i, wb_rst_i,
// WISHBONE Slave I/F
wbs_cyc_i, wbs_stb_i, wbs_sel_i, wbs_we_i,
wbs_adr_i, wbs_dat_i, wbs_cab_i,
wbs_dat_o, wbs_ack_o, wbs_err_o, wbs_rty_o,
 
// Other signals
ssvga_en, pal_wr_en, pal_rd_en, pal_dat,
pix_start_addr, misc
);
 
//
// I/O ports
//
 
//
// Clock and reset
//
input wb_clk_i; // Pixel Clock
input wb_rst_i; // Reset
 
//
// WISHBONE Slave I/F
//
input wbs_cyc_i;
input wbs_stb_i;
input [3:0] wbs_sel_i;
input wbs_we_i;
input [31:0] wbs_adr_i;
input [31:0] wbs_dat_i;
input wbs_cab_i;
output [31:0] wbs_dat_o;
output wbs_ack_o;
output wbs_err_o;
output wbs_rty_o;
 
//
// Other signals
//
output ssvga_en; // Global enable
output pal_wr_en; // Palette write enable
output pal_rd_en; // Palette read enable
input [15:0] pal_dat; // Palette data
output [31:2] pix_start_addr ;
input [15:0] misc;
 
//
// Internal regs and wires
//
reg wbs_ack_o; // WISHBONE ack
reg wbs_err_o; // WISHBONE err
reg [0:0] ctrl_r; // Control register
wire valid_access; // Access to SSVGA
 
//
// Control register
//
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
ctrl_r <= #1 1'b0;
else if (valid_access & wbs_we_i & !wbs_adr_i[`SEL_PAL] & !wbs_adr_i[`SEL_ADDRESS])
ctrl_r <= #1 wbs_dat_i[0];
 
reg [31:2] pix_start_addr ;
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
pix_start_addr <= #1 30'h0000_0000 ;
else if (valid_access & wbs_we_i & !wbs_adr_i[`SEL_PAL] & wbs_adr_i[`SEL_ADDRESS] )
pix_start_addr <= #1 wbs_dat_i[31:2] ;
 
//
// Generate delayed WISHBONE ack/err
//
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i) begin
wbs_ack_o <= #1 1'b0;
wbs_err_o <= #1 1'b0;
end
else if (valid_access) begin
wbs_ack_o <= #1 1'b1;
wbs_err_o <= #1 1'b0;
end
else if (wbs_cyc_i & wbs_stb_i) begin
wbs_ack_o <= #1 1'b0;
wbs_err_o <= #1 1'b1;
end
else begin
wbs_ack_o <= #1 1'b0;
wbs_err_o <= #1 1'b0;
end
 
//
// Generate WISHBONE output signals
//
reg [31:0] wbs_dat_o ;
always@(wbs_adr_i or pal_dat or ctrl_r or pix_start_addr or misc)
begin
if ( wbs_adr_i[`SEL_PAL] )
wbs_dat_o = {16'h0000, pal_dat} ;
else
if ( wbs_adr_i[`SEL_ADDRESS] )
wbs_dat_o = {pix_start_addr, 2'b00} ;
else
wbs_dat_o = {{15{1'b0}}, misc, ctrl_r};
end
 
assign wbs_rty_o = 1'b0;
 
//
// Generate other signals
//
assign valid_access = wbs_cyc_i & wbs_stb_i & (wbs_sel_i == 4'b1111);
assign ssvga_en = ctrl_r[0];
assign pal_wr_en = valid_access & wbs_we_i & wbs_adr_i[`SEL_PAL];
assign pal_rd_en = valid_access & ~wbs_we_i & wbs_adr_i[`SEL_PAL];
 
endmodule
/verilog/ssvga/ssvga_crtc.v
0,0 → 1,170
//////////////////////////////////////////////////////////////////////
//// ////
//// Simple Small VGA IP Core ////
//// ////
//// This file is part of the Simple Small VGA project ////
//// ////
//// ////
//// Description ////
//// Hsync/Vsync generator. ////
//// ////
//// To Do: ////
//// Nothing ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:19:09 igorm
// no message
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
`include "ssvga_defines.v"
 
module ssvga_crtc(
clk, rst, hsync, vsync, hblank, vblank
);
 
//
// I/O ports
//
input clk; // Pixel Clock
input rst; // Reset
output hsync; // H sync
output vsync; // V sync
output hblank; // H blank
output vblank; // V blank
 
//
// Internal wires and regs
//
reg [`SSVGA_HCW-1:0] hcntr; // Horizontal counter
reg [`SSVGA_VCW-1:0] vcntr; // Vertical counter
reg hsync; // Horizontal sync
reg vsync; // Vertical sync
 
// flip - flops for decoding end of one line
reg line_end1 ;
reg line_end2 ;
 
always@(posedge clk or posedge rst)
begin
if (rst)
begin
line_end1 <= #1 1'b0 ;
line_end2 <= #1 1'b0 ;
end
else
begin
line_end1 <= #1 hsync ;
line_end2 <= #1 line_end1 ;
end
end
 
wire line_end = ~line_end2 && line_end1 ;
 
//
// Assert hblank when hsync is not asserted
//
reg hblank ;
always@(posedge clk or posedge rst)
begin
if (rst)
hblank <= #1 1'b0 ;
else
if ( hcntr == (`SSVGA_HPULSE + `SSVGA_HBACKP) )
hblank <= #1 1'b0 ;
else
if ( hcntr == (`SSVGA_HTOT - `SSVGA_HFRONTP) )
hblank <= #1 1'b1 ;
end
 
reg vblank ;
always@(posedge clk or posedge rst)
begin
if ( rst )
vblank <= #1 1'b0 ;
else
if ((vcntr == (`SSVGA_VPULSE + `SSVGA_VBACKP)) && line_end)
vblank <= #1 1'b0 ;
else
if ((vcntr == (`SSVGA_VTOT - `SSVGA_VFRONTP)) && line_end)
vblank <= #1 1'b1 ;
end
 
//
// Horizontal counter
//
always @(posedge clk or posedge rst)
if (rst)
hcntr <= #1 `SSVGA_HCW'h0;
else if (hcntr == `SSVGA_HTOT - 1)
hcntr <= #1 `SSVGA_HCW'h0;
else
hcntr <= #1 hcntr + 1;
//
// Horizontal sync
//
always @(posedge clk or posedge rst)
if (rst)
hsync <= #1 1'b0;
else if (hcntr == `SSVGA_HCW'h0)
hsync <= #1 1'b1;
else if (hcntr == `SSVGA_HPULSE)
hsync <= #1 1'b0 ;
 
//
// Vertical counter
//
always @(posedge clk or posedge rst)
if (rst)
vcntr <= #1 `SSVGA_VCW'h0;
else if ((vcntr == `SSVGA_VTOT - 1) && line_end)
vcntr <= #1 `SSVGA_VCW'h0;
else if ( line_end )
vcntr <= #1 vcntr + 1;
//
// Vertical sync
//
always @(posedge clk or posedge rst)
if (rst)
vsync <= #1 1'b0;
else if ((vcntr == `SSVGA_VCW'd0) && line_end)
vsync <= #1 1'b1;
else if ((vcntr == `SSVGA_VPULSE) && line_end)
vsync <= #1 1'b0;
endmodule
/verilog/ssvga/ssvga_defines.v
0,0 → 1,130
//////////////////////////////////////////////////////////////////////
//// ////
//// Simple Small VGA IP Core ////
//// ////
//// This file is part of the Simple Small VGA project ////
//// ////
//// ////
//// Description ////
//// Definitions. ////
//// ////
//// To Do: ////
//// Nothing ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:19:09 igorm
// no message
//
//
// 14.4 MHz (400x320)
 
/*
`define PIXEL_NUM 'd128000 // 166668
`define SSVGA_HCW 10
`define SSVGA_VCW 10
`define SSVGA_HTOT `SSVGA_HCW'd646
`define SSVGA_HPULSE `SSVGA_HCW'd140
`define SSVGA_HFRONTP `SSVGA_HCW'd53
`define SSVGA_HBACKP `SSVGA_HCW'd53
 
`define SSVGA_VTOT `SSVGA_VCW'd340
`define SSVGA_VPULSE `SSVGA_VCW'd6
`define SSVGA_VFRONTP `SSVGA_HCW'd2
`define SSVGA_VBACKP `SSVGA_HCW'd2
`define SSVGA_VMCW 17
*/
// 10 MHz (400x320)
/*`define PIXEL_NUM 'd128000 // 166668
`define SSVGA_HCW 10
`define SSVGA_VCW 10
`define SSVGA_HTOT `SSVGA_HCW'd516
`define SSVGA_HPULSE `SSVGA_HCW'd90
`define SSVGA_HFRONTP `SSVGA_HCW'd13
`define SSVGA_HBACKP `SSVGA_HCW'd13
 
`define SSVGA_VTOT `SSVGA_VCW'd323
`define SSVGA_VPULSE `SSVGA_VCW'd1
`define SSVGA_VFRONTP `SSVGA_HCW'd1
`define SSVGA_VBACKP `SSVGA_HCW'd1
`define SSVGA_VMCW 17
*/
 
// 20 MHz (640x480)
//`define PIXEL_NUM 'd307200 // 333270
//`define SSVGA_HCW 10
//`define SSVGA_VCW 10
//`define SSVGA_HTOT `SSVGA_HCW'd690
//`define SSVGA_HPULSE `SSVGA_HCW'd40
//`define SSVGA_HFRONTP `SSVGA_HCW'd5
//`define SSVGA_HBACKP `SSVGA_HCW'd5
//
//`define SSVGA_VTOT `SSVGA_VCW'd483
//`define SSVGA_VPULSE `SSVGA_VCW'd1
//`define SSVGA_VFRONTP `SSVGA_HCW'd1
//`define SSVGA_VBACKP `SSVGA_HCW'd1
//`define SSVGA_VMCW 17
 
// 25 MHz (640x480)
`define PIXEL_NUM 'd307200 // 383330
`define SSVGA_HCW 10
`define SSVGA_VCW 10
`define SSVGA_HTOT `SSVGA_HCW'd800
`define SSVGA_HPULSE `SSVGA_HCW'd96
`define SSVGA_HFRONTP `SSVGA_HCW'd48
`define SSVGA_HBACKP `SSVGA_HCW'd16
 
`define SSVGA_VTOT `SSVGA_VCW'd525
`define SSVGA_VPULSE `SSVGA_VCW'd2
`define SSVGA_VFRONTP `SSVGA_HCW'd10
`define SSVGA_VBACKP `SSVGA_HCW'd33
`define SSVGA_VMCW 17
 
// 23 MHz (640x480)
//`define PIXEL_NUM 'd307200 // 383330
//`define SSVGA_HCW 10
//`define SSVGA_VCW 10
//`define SSVGA_HTOT `SSVGA_HCW'd750
//`define SSVGA_HPULSE `SSVGA_HCW'd90
//`define SSVGA_HFRONTP `SSVGA_HCW'd10
//`define SSVGA_HBACKP `SSVGA_HCW'd10
//
//`define SSVGA_VTOT `SSVGA_VCW'd511
//`define SSVGA_VPULSE `SSVGA_VCW'd4
//`define SSVGA_VFRONTP `SSVGA_HCW'd12
//`define SSVGA_VBACKP `SSVGA_HCW'd15
//`define SSVGA_VMCW 17
 
//`define XILINX_RAMB4
/verilog/ssvga/crtc_iob.v
0,0 → 1,45
module CRTC_IOB
(
reset_in,
clk_in,
hsync_in,
vsync_in,
rgb_in,
hsync_out,
vsync_out,
rgb_out
) ;
 
input reset_in,
clk_in ;
 
input hsync_in,
vsync_in ;
 
input [15:4] rgb_in ;
 
output hsync_out,
vsync_out ;
output [15:4] rgb_out ;
 
reg hsync_out,
vsync_out ;
 
reg [15:4] rgb_out ;
 
always@(posedge clk_in or posedge reset_in)
begin
if ( reset_in )
begin
hsync_out <= #1 1'b0 ;
vsync_out <= #1 1'b0 ;
rgb_out <= #1 12'h000 ;
end
else
begin
hsync_out <= #1 hsync_in ;
vsync_out <= #1 vsync_in ;
rgb_out <= #1 rgb_in ;
end
end
endmodule
/verilog/ssvga/ssvga_top.v
0,0 → 1,342
//////////////////////////////////////////////////////////////////////
//// ////
//// Simple Small VGA IP Core ////
//// ////
//// This file is part of the Simple Small VGA project ////
//// ////
//// ////
//// Description ////
//// Top level of SSVGA. ////
//// ////
//// To Do: ////
//// Nothing ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:19:09 igorm
// no message
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
module ssvga_top(
// Clock and reset
wb_clk_i, wb_rst_i,
// WISHBONE Master I/F
wbm_cyc_o, wbm_stb_o, wbm_sel_o, wbm_we_o,
wbm_adr_o, wbm_dat_o, wbm_cab_o,
wbm_dat_i, wbm_ack_i, wbm_err_i, wbm_rty_i,
 
// WISHBONE Slave I/F
wbs_cyc_i, wbs_stb_i, wbs_sel_i, wbs_we_i,
wbs_adr_i, wbs_dat_i, wbs_cab_i,
wbs_dat_o, wbs_ack_o, wbs_err_o, wbs_rty_o,
 
// Signals to VGA display
pad_hsync_o, pad_vsync_o, pad_rgb_o, led_o,
 
// clock x2 output for crtc iob connection
pix_clk, misc
);
 
//
// I/O ports
//
 
//
// Clock and reset
//
input wb_clk_i; // Pixel Clock
input wb_rst_i; // Reset
 
//
// WISHBONE Master I/F
//
output wbm_cyc_o;
output wbm_stb_o;
output [3:0] wbm_sel_o;
output wbm_we_o;
output [31:0] wbm_adr_o;
output [31:0] wbm_dat_o;
output wbm_cab_o;
input [31:0] wbm_dat_i;
input wbm_ack_i;
input wbm_err_i;
input wbm_rty_i;
 
//
// WISHBONE Slave I/F
//
input wbs_cyc_i;
input wbs_stb_i;
input [3:0] wbs_sel_i;
input wbs_we_i;
input [31:0] wbs_adr_i;
input [31:0] wbs_dat_i;
input wbs_cab_i;
output [31:0] wbs_dat_o;
output wbs_ack_o;
output wbs_err_o;
output wbs_rty_o;
 
//
// VGA display
//
output pad_hsync_o; // H sync
output pad_vsync_o; // V sync
output [15:0] pad_rgb_o; // Digital RGB data
output led_o;
output pix_clk ; // pixel clock output
 
input [15:0] misc;
 
//
// Internal wires and regs
//
wire ssvga_en; // Global enable
wire fifo_full; // FIFO full flag
wire fifo_empty; // FIFO empty flag
wire wbm_restart ; // indicator on when WISHBONE master should restart whole screen because of pixel buffer underrun
wire crtc_hblank; // H blank
wire crtc_vblank; // V blank
wire fifo_wr_en; // FIFO write enable
wire fifo_rd_en; // FIFO read enable
wire [31:0] fifo_in; // FIFO input data
wire [7:0] fifo_out; // FIFO output data
//wire [7:0] pal_indx; // Palette index
wire pal_wr_en; // Palette write enable
wire pal_rd_en; // Palette read enable
wire [15:0] pal_pix_dat ; // pixel output from pallete RAM
 
// clockx2 - buffered
wire clk_2x_buf;
assign pix_clk = clk_2x_buf ;
reg go ;
 
// rgb output assignment - when blank output transmits black pixels, otherwise it transmits pallete data
reg drive_blank_reg ;
//always@(posedge wb_clk_i or posedge wb_rst_i)
always@(posedge clk_2x_buf or posedge wb_rst_i)
begin
if ( wb_rst_i )
drive_blank_reg <= #1 1'b0 ;
else
drive_blank_reg <= #1 ( crtc_hblank || crtc_vblank || ~go ) ;
end
 
assign pad_rgb_o = drive_blank_reg ? 16'h0000 : pal_pix_dat ;
//assign pad_rgb_o = drive_blank_reg ? 16'h0000 : wbs_dat_i[15:0]; // for test
 
assign led_o = ssvga_en ;
 
//
// Read FIFO when blanks are not asserted and fifo has been filled once
//
always@(posedge wb_clk_i or posedge wb_rst_i)
begin
if ( wb_rst_i )
go <= #1 1'b0 ;
else
if ( ~ssvga_en )
go <= #1 1'b0 ;
else
go <= #1 ( fifo_full & crtc_hblank & crtc_vblank ) || ( go && ~fifo_empty ) ;
end
 
assign fifo_rd_en = !crtc_hblank & !crtc_vblank & go ;
 
assign wbm_restart = go & fifo_empty ;
 
//
// Palette index is either color index from FIFO or
// address from WISHBONE slave when writing into palette
//
//assign pal_indx = (pal_wr_en || pal_rd_en) ? wbs_adr_i[9:2] : fifo_out;
 
//
// Instantiation of WISHBONE Master block
//
wire [31:2] pix_start_addr ;
ssvga_wbm_if ssvga_wbm_if(
 
// Clock and reset
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
 
// WISHBONE Master I/F
.wbm_cyc_o(wbm_cyc_o),
.wbm_stb_o(wbm_stb_o),
.wbm_sel_o(wbm_sel_o),
.wbm_we_o(wbm_we_o),
.wbm_adr_o(wbm_adr_o),
.wbm_dat_o(wbm_dat_o),
.wbm_cab_o(wbm_cab_o),
.wbm_dat_i(wbm_dat_i),
.wbm_ack_i(wbm_ack_i),
.wbm_err_i(wbm_err_i),
.wbm_rty_i(wbm_rty_i),
 
// FIFO control and other signals
.ssvga_en(ssvga_en),
.fifo_full(fifo_full),
.fifo_wr_en(fifo_wr_en),
.fifo_dat(fifo_in),
.pix_start_addr(pix_start_addr),
.resync(wbm_restart)
);
 
//
// Instantiation of WISHBONE Slave block
//
wire [15:0] wbs_pal_data ;
ssvga_wbs_if ssvga_wbs_if(
 
// Clock and reset
.wb_clk_i(wb_clk_i),
.wb_rst_i(wb_rst_i),
 
// WISHBONE Slave I/F
.wbs_cyc_i(wbs_cyc_i),
.wbs_stb_i(wbs_stb_i),
.wbs_sel_i(wbs_sel_i),
.wbs_we_i(wbs_we_i),
.wbs_adr_i(wbs_adr_i),
.wbs_dat_i(wbs_dat_i),
.wbs_cab_i(wbs_cab_i),
.wbs_dat_o(wbs_dat_o),
.wbs_ack_o(wbs_ack_o),
.wbs_err_o(wbs_err_o),
.wbs_rty_o(wbs_rty_o),
 
// Control for other SSVGA blocks
.ssvga_en(ssvga_en),
.pal_wr_en(pal_wr_en),
.pal_rd_en(pal_rd_en),
.pal_dat(wbs_pal_data),
.pix_start_addr(pix_start_addr),
.misc(misc)
);
 
//
// Instantiation of line FIFO block
//
ssvga_fifo ssvga_fifo(
.wclk(wb_clk_i),
.rclk(clk_2x_buf),
.rst(wb_rst_i),
.wr_en(fifo_wr_en),
.rd_en(fifo_rd_en),
.dat_i(fifo_in),
.dat_o(fifo_out),
.full(fifo_full),
.empty(fifo_empty),
.ssvga_en(ssvga_en)
);
 
//
// Instantiation of 256x16 Palette block
//
RAMB4_S16_S16 ssvga_pallete
(
.ADDRA(wbs_adr_i[9:2]),
.DIA(wbs_dat_i[15:0]),
.ENA(1'b1),
.RSTA(wb_rst_i),
.CLKA(wb_clk_i),
.WEA(pal_wr_en),
.DOA(wbs_pal_data),
.ADDRB(fifo_out),
.DIB(16'h0000),
.ENB(1'b1),
.RSTB(wb_rst_i),
.CLKB(clk_2x_buf),
.WEB(1'b0),
.DOB(pal_pix_dat)
) ;
 
/*generic_spram_256x16 ssvga_palette(
// Generic synchronous single-port RAM interface
.clk(wb_clk_i),
.rst(wb_rst_i),
.ce(1'b1),
.we(pal_wr_en),
.oe(1'b1),
.addr(pal_indx),
.di(wbs_dat_i[15:0]),
.do(pad_rgb_o)
);
*/
//
// Instantiation of CRT controller block
//
wire clk_buf;
wire clk_2x;
assign clk_buf = wb_clk_i;
`ifdef TARGET_VIRTEX
BUFG BUFG_crt2(.O(clk_2x_buf), .I(clk_2x));
`else
assign clk_2x_buf = clk_2x;
`endif
 
`ifdef TARGET_VIRTEX
CLKDLL CLKDLL(
.CLK0(),
.CLK90(),
.CLK180(),
.CLK270(),
.CLK2X(clk_2x),
.CLKDV(),
.LOCKED(),
.CLKIN(clk_buf),
.CLKFB(clk_2x_buf),
.RST(1'b0)
);
`else
assign clk_2x = clk_buf;
`endif
 
ssvga_crtc ssvga_crtc(
.clk(clk_2x_buf),
.rst(wb_rst_i),
.hsync(pad_hsync_o),
.vsync(pad_vsync_o),
.hblank(crtc_hblank),
.vblank(crtc_vblank)
);
 
endmodule
/verilog/ssvga/ssvga_fifo.v
0,0 → 1,189
//////////////////////////////////////////////////////////////////////
//// ////
//// Simple Small VGA IP Core ////
//// ////
//// This file is part of the Simple Small VGA project ////
//// ////
//// ////
//// Description ////
//// 512 entry FIFO for storing line video data. It uses one ////
//// clock for reading and writing. ////
//// ////
//// To Do: ////
//// Nothing ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:19:09 igorm
// no message
//
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
module ssvga_fifo(
wclk, rclk, rst, dat_i, wr_en, rd_en,
dat_o, full, empty, ssvga_en
);
 
//
// I/O ports
//
input wclk; // write clock
input rclk; // read clock
input rst; // Reset
input [31:0] dat_i; // Input data
input wr_en; // Write enable
input rd_en; // Read enable
output [7:0] dat_o; // Output data
output full; // Full flag
output empty; // Empty flag
input ssvga_en ; // vga enable
 
//
// Internal wires and regs
//
reg [7:0] wr_ptr; // Write pointer
reg [7:0] wr_ptr_plus1; // Write pointer
reg [9:0] rd_ptr; // Read pointer
reg [9:0] rd_ptr_plus1; // Read pointer plus1
wire rd_en_int; // FIFO internal read enable
 
//
// Write pointer + 1
//
 
always @(posedge wclk or posedge rst)
if (rst)
wr_ptr_plus1 <= #1 8'b0000_0001 ;
else if (~ssvga_en)
wr_ptr_plus1 <= #1 8'b0000_0001 ;
else if (wr_en)
wr_ptr_plus1 <= #1 wr_ptr_plus1 + 1;
 
//
// Write pointer
//
always @(posedge wclk or posedge rst)
if (rst)
wr_ptr <= #1 8'b0000_0000;
else if (~ssvga_en)
wr_ptr <= #1 8'b0000_0000;
else if (wr_en)
wr_ptr <= #1 wr_ptr_plus1 ;
 
//
// Read pointer
//
always @(posedge rclk or posedge rst)
if (rst)
rd_ptr <= #1 10'b00_0000_0000;
else if (~ssvga_en)
rd_ptr <= #1 10'b00_0000_0000;
else if (rd_en_int)
rd_ptr <= #1 rd_ptr_plus1 ;
 
always @(posedge rclk or posedge rst)
if (rst)
rd_ptr_plus1 <= #1 10'b00_0000_0001;
else if (~ssvga_en)
rd_ptr_plus1 <= #1 10'b00_0000_0001;
else if (rd_en_int)
rd_ptr_plus1 <= #1 rd_ptr_plus1 + 1 ;
 
//
// Empty is asserted when both pointers match
//
assign empty = (rd_ptr == {wr_ptr, 2'b00}) ;
 
//
// Full is asserted when both pointers match
// and wr_ptr did increment in previous clock cycle
//
 
assign full = ( wr_ptr_plus1 == rd_ptr[9:2] ) ;
 
wire valid_pix = 1'b1 ;
 
//
// Read enable for FIFO
//
assign rd_en_int = rd_en & !empty & valid_pix;
 
wire [8:0] ram_pix_address = rd_en_int ? {rd_ptr_plus1[9:2], rd_ptr_plus1[0]} : {rd_ptr[9:2], rd_ptr[0]} ;
 
wire [7:0] dat_o_low ;
wire [7:0] dat_o_high ;
 
assign dat_o = rd_ptr[1] ? dat_o_high : dat_o_low ;
 
RAMB4_S8_S16 ramb4_s8_0(
.CLKA(rclk),
.RSTA(rst),
.ADDRA(ram_pix_address),
.DIA(8'h00),
.ENA(1'b1),
.WEA(1'b0),
.DOA(dat_o_low),
 
.CLKB(wclk),
.RSTB(rst),
.ADDRB(wr_ptr),
.DIB(dat_i[15:0]),
.ENB(1'b1),
.WEB(wr_en),
.DOB()
);
 
RAMB4_S8_S16 ramb4_s8_1(
.CLKA(rclk),
.RSTA(rst),
.ADDRA(ram_pix_address),
.DIA(8'h00),
.ENA(1'b1),
.WEA(1'b0),
.DOA(dat_o_high),
 
.CLKB(wclk),
.RSTB(rst),
.ADDRB(wr_ptr),
.DIB(dat_i[31:16]),
.ENB(1'b1),
.WEB(wr_en),
.DOB()
);
 
endmodule
/verilog/ssvga/ssvga_wbm_if.v
0,0 → 1,187
//////////////////////////////////////////////////////////////////////
//// ////
//// Simple Small VGA IP Core ////
//// ////
//// This file is part of the Simple Small VGA project ////
//// ////
//// ////
//// Description ////
//// LITTLE-ENDIAN WISHBONE master interface. ////
//// ////
//// To Do: ////
//// Nothing ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 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 ////
//// ////
//////////////////////////////////////////////////////////////////////
//
// CVS Revision History
//
// $Log: not supported by cvs2svn $
// Revision 1.1.1.1 2001/10/06 10:19:09 igorm
// no message
//
//
 
// synopsys translate_off
`include "timescale.v"
`include "ssvga_defines.v"
// synopsys translate_on
 
module ssvga_wbm_if(
// Clock and reset
wb_clk_i, wb_rst_i,
// WISHBONE Master I/F
wbm_cyc_o, wbm_stb_o, wbm_sel_o, wbm_we_o,
wbm_adr_o, wbm_dat_o, wbm_cab_o,
wbm_dat_i, wbm_ack_i, wbm_err_i, wbm_rty_i,
 
// Other signals
ssvga_en, fifo_full,
fifo_wr_en, fifo_dat,
pix_start_addr, resync
);
 
//
// I/O ports
//
 
//
// Clock and reset
//
input wb_clk_i; // Pixel Clock
input wb_rst_i; // Reset
 
//
// WISHBONE Master I/F
//
output wbm_cyc_o;
output wbm_stb_o;
output [3:0] wbm_sel_o;
output wbm_we_o;
output [31:0] wbm_adr_o;
output [31:0] wbm_dat_o;
output wbm_cab_o;
input [31:0] wbm_dat_i;
input wbm_ack_i;
input wbm_err_i;
input wbm_rty_i;
 
//
// Other signals
//
input ssvga_en; // Global enable
input fifo_full; // FIFO is full
output fifo_wr_en; // FIFO write enable
output [31:0] fifo_dat; // FIFO data
input [31:2] pix_start_addr ;
input resync ; // when pixel buffer underrun occures, master must resynchronize operation to start of screen
 
//
// Internal regs and wires
//
reg [`SSVGA_VMCW-1:0] vmaddr_r; // Video memory address counter
//reg [31:0] shift_r; // Shift register
//reg [1:0] shift_empty_r; // Shift register empty flags
 
// frame finished indicator - whenever video memory address shows 640x480 pixels read
reg frame_read ;
wire frame_read_in = ( vmaddr_r == `SSVGA_VMCW'h0_00_00 ) & wbm_ack_i & wbm_stb_o || ~ssvga_en || resync ;
 
always@(posedge wb_clk_i or posedge wb_rst_i)
begin
if (wb_rst_i)
frame_read <= #1 1'b0 ;
else
frame_read <= #1 frame_read_in ;
end
 
//
// Video memory address generation
//
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
vmaddr_r <= #1 ((`PIXEL_NUM/4)-1) ;
else if (frame_read)
vmaddr_r <= #1 ((`PIXEL_NUM/4)-1);
else if (wbm_ack_i & wbm_stb_o)
vmaddr_r <= #1 vmaddr_r - 1;
 
reg [31:2] wbm_adr ;
always@(posedge wb_clk_i or posedge wb_rst_i)
begin
if (wb_rst_i)
wbm_adr <= #1 30'h0000_0000 ;
else if (frame_read)
wbm_adr <= #1 pix_start_addr ;
else if (wbm_ack_i & wbm_stb_o)
wbm_adr <= #1 wbm_adr + 1 ;
end
 
//
// Shift register
//
/*always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
shift_r <= #1 32'h0000_0000;
else if (wbm_ack_i & wbm_cyc_o)
shift_r <= #1 wbm_dat_i;
else if (!fifo_full)
shift_r <= #1 {16'h00, shift_r[31:16]};
 
//
// Shift register empty flags
//
always @(posedge wb_clk_i or posedge wb_rst_i)
if (wb_rst_i)
shift_empty_r <= #1 2'b11 ;
else if (wbm_ack_i & wbm_cyc_o)
shift_empty_r <= #1 2'b00;
else if (!fifo_full)
shift_empty_r <= #1 {1'b1, shift_empty_r[1]};
*/
//
// Generate WISHBONE output signals
//
assign wbm_cyc_o = ssvga_en & !frame_read ;
assign wbm_stb_o = wbm_cyc_o & !fifo_full;
assign wbm_sel_o = 4'b1111;
assign wbm_we_o = 1'b0;
assign wbm_adr_o = {wbm_adr, 2'b00};
assign wbm_dat_o = 32'h0000_0000;
assign wbm_cab_o = 1'b1;
 
//
// Generate other signals
//
assign fifo_wr_en = wbm_ack_i & wbm_stb_o ;
assign fifo_dat = wbm_dat_i ;
 
endmodule
/verilog/xfpga_defines.v
0,0 → 1,52
//////////////////////////////////////////////////////////////////////
//// ////
//// MP3 demo Definitions ////
//// ////
//// This file is part of the MP3 demo application ////
//// http://www.opencores.org/cores/or1k/mp3/ ////
//// ////
//// Description ////
//// DEfine target technology etc. Right now FIFOs are available ////
//// only for Xilinx Virtex FPGAs. (TARGET_VIRTEX) ////
//// ////
//// To Do: ////
//// - nothing really ////
//// ////
//// Author(s): ////
//// - Damjan Lampret, damjan.lampret@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 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 $
 
//
// Define to target to Xilinx Virtex
//
`define TARGET_VIRTEX
/verilog/tcop_top.v
0,0 → 1,463
//////////////////////////////////////////////////////////////////////
//// ////
//// MP3 demo Traffic Cop ////
//// ////
//// This file is part of the MP3 demo application ////
//// http://www.opencores.org/cores/or1k/mp3/ ////
//// ////
//// Description ////
//// This block connectes the RISC, audio i/f and memory ////
//// controller together. ////
//// ////
//// To Do: ////
//// - nothing really ////
//// ////
//// Author(s): ////
//// - Lior Shtram, lior.shtram@flextronicssemi.com ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 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 $
//
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
// sr_input_sel
`define SR_RD 3'b001
`define SR_RI 3'b010
`define SR_VM 3'b011
`define SR_DM 3'b100
 
 
module tcop_top (
rstn,
clk,
 
wb_vs_adr_i,
wb_vs_dat_i,
wb_vs_dat_o,
wb_vs_sel_i,
wb_vs_we_i,
wb_vs_stb_i,
wb_vs_cyc_i,
wb_vs_ack_o,
wb_vs_err_o,
 
wb_vm_adr_o,
wb_vm_dat_i,
wb_vm_sel_o,
wb_vm_we_o,
wb_vm_stb_o,
wb_vm_cyc_o,
wb_vm_cab_o,
wb_vm_ack_i,
wb_vm_err_i,
 
wb_dm_adr_o,
wb_dm_dat_i,
wb_dm_dat_o,
wb_dm_sel_o,
wb_dm_we_o,
wb_dm_stb_o,
wb_dm_cyc_o,
wb_dm_cab_o,
wb_dm_ack_i,
wb_dm_err_i,
 
wb_ri_cyc_o,
wb_ri_adr_o,
wb_ri_dat_i,
wb_ri_dat_o,
wb_ri_sel_o,
wb_ri_ack_i,
wb_ri_err_i,
wb_ri_rty_i,
wb_ri_we_o,
wb_ri_stb_o,
 
wb_rd_cyc_o,
wb_rd_adr_o,
wb_rd_dat_i,
wb_rd_dat_o,
wb_rd_sel_o,
wb_rd_ack_i,
wb_rd_err_i,
wb_rd_rty_i,
wb_rd_we_o,
wb_rd_stb_o,
 
wb_sr_dat_i,
wb_sr_dat_o,
wb_sr_adr_i,
wb_sr_sel_i,
wb_sr_we_i,
wb_sr_cyc_i,
wb_sr_stb_i,
wb_sr_ack_o,
wb_sr_err_o,
 
wb_fl_dat_i,
wb_fl_dat_o,
wb_fl_adr_i,
wb_fl_sel_i,
wb_fl_we_i,
wb_fl_cyc_i,
wb_fl_stb_i,
wb_fl_ack_o,
wb_fl_err_o,
 
wb_au_dat_i,
wb_au_dat_o,
wb_au_adr_i,
wb_au_sel_i,
wb_au_we_i,
wb_au_cyc_i,
wb_au_stb_i,
wb_au_ack_o,
wb_au_err_o
 
);
 
parameter data_width = 32;
parameter addr_width = 32;
 
parameter n_mast_i = (data_width + 2) ;
parameter n_mast_o = data_width + addr_width + 6 ;
 
input clk;
input rstn;
 
output [addr_width-1:0] wb_vs_adr_i;
output [data_width-1:0] wb_vs_dat_i;
input [data_width-1:0] wb_vs_dat_o;
output [3:0] wb_vs_sel_i;
output wb_vs_we_i;
output wb_vs_stb_i;
output wb_vs_cyc_i;
input wb_vs_ack_o;
input wb_vs_err_o;
 
input [addr_width-1:0] wb_vm_adr_o;
output [data_width-1:0] wb_vm_dat_i;
input [3:0] wb_vm_sel_o;
input wb_vm_stb_o;
input wb_vm_we_o;
input wb_vm_cyc_o;
input wb_vm_cab_o;
output wb_vm_ack_i;
output wb_vm_err_i;
 
input [addr_width-1:0] wb_dm_adr_o;
output [data_width-1:0] wb_dm_dat_i;
input [data_width-1:0] wb_dm_dat_o;
input [3:0] wb_dm_sel_o;
input wb_dm_stb_o;
input wb_dm_we_o;
input wb_dm_cyc_o;
input wb_dm_cab_o;
output wb_dm_ack_i;
output wb_dm_err_i;
input [addr_width-1:0] wb_ri_adr_o;
input wb_ri_cyc_o;
output [data_width-1:0] wb_ri_dat_i;
input [data_width-1:0] wb_ri_dat_o;
input [3:0] wb_ri_sel_o;
output wb_ri_ack_i;
output wb_ri_err_i;
output wb_ri_rty_i;
input wb_ri_we_o;
input wb_ri_stb_o;
 
input [addr_width-1:0] wb_rd_adr_o;
input wb_rd_cyc_o;
output [data_width-1:0] wb_rd_dat_i;
input [data_width-1:0] wb_rd_dat_o;
input [3:0] wb_rd_sel_o;
output wb_rd_ack_i;
output wb_rd_err_i;
output wb_rd_rty_i;
input wb_rd_we_o;
input wb_rd_stb_o;
 
output [data_width-1:0] wb_sr_dat_i;
input [data_width-1:0] wb_sr_dat_o;
output [addr_width-1:0] wb_sr_adr_i;
output [3:0] wb_sr_sel_i;
output wb_sr_we_i;
output wb_sr_cyc_i;
output wb_sr_stb_i;
input wb_sr_ack_o;
input wb_sr_err_o;
 
output [data_width-1:0] wb_fl_dat_i;
input [data_width-1:0] wb_fl_dat_o;
output [addr_width-1:0] wb_fl_adr_i;
output [3:0] wb_fl_sel_i;
output wb_fl_we_i;
output wb_fl_cyc_i;
output wb_fl_stb_i;
input wb_fl_ack_o;
input wb_fl_err_o;
 
output [data_width-1:0] wb_au_dat_i;
input [data_width-1:0] wb_au_dat_o;
output [addr_width-1:0] wb_au_adr_i;
output [3:0] wb_au_sel_i;
output wb_au_we_i;
output wb_au_cyc_i;
output wb_au_stb_i;
input wb_au_ack_o;
input wb_au_err_o;
 
 
wire [data_width-1:0] data_width_zeros;
assign data_width_zeros = 0;
wire [n_mast_i-1:0] n_mast_i_zeros;
assign n_mast_i_zeros = 0;
wire [n_mast_o-1:0] n_mast_o_zeros;
wire [n_mast_i-1:0] ri_inputs;
wire [n_mast_o-1:0] ri_outputs;
wire [n_mast_i-1:0] rd_inputs;
wire [n_mast_o-1:0] rd_outputs;
wire [n_mast_i-1:0] vm_inputs;
wire [n_mast_o-1:0] vm_outputs;
wire [n_mast_i-1:0] dm_inputs;
wire [n_mast_o-1:0] dm_outputs;
wire [n_mast_o-1:0] vs_inputs;
wire [n_mast_i-1:0] vs_outputs;
reg [n_mast_o-1:0] sr_inputs;
wire [n_mast_i-1:0] sr_outputs;
wire [n_mast_o-1:0] fl_inputs;
wire [n_mast_i-1:0] fl_outputs;
wire [n_mast_o-1:0] au_inputs;
wire [n_mast_i-1:0] au_outputs;
wire [n_mast_i-1:0] sr_to_dm;
wire [n_mast_i-1:0] fl_to_dm;
wire [n_mast_i-1:0] au_to_rd;
wire [n_mast_i-1:0] vs_to_rd;
wire [n_mast_i-1:0] sr_to_rd;
wire [n_mast_i-1:0] fl_to_rd;
wire [n_mast_i-1:0] sr_to_ri;
wire [n_mast_i-1:0] fl_to_ri;
wire fl_input_sel;
reg [2:0] sr_input_sel;
reg [3:0] dm_cs;
reg [3:0] rd_cs;
wire dm_fl_cs;
wire dm_sr_cs;
wire dm_au_cs;
wire dm_vs_cs;
wire rd_fl_cs;
wire rd_sr_cs;
wire rd_au_cs;
wire rd_vs_cs;
wire ri_fl_cs;
wire ri_sr_cs;
//reg rd_sr_con;
reg dm_fl_con;
reg rd_fl_con;
reg ri_fl_con;
 
// We don't support retries
assign wb_ri_rty_i = 1'b0;
assign wb_rd_rty_i = 1'b0;
 
//////////////////////////////////
// Gathering all inputs and outputs together
 
assign { wb_ri_dat_i, wb_ri_ack_i, wb_ri_err_i } = ri_inputs ;
assign ri_outputs = { wb_ri_dat_o, wb_ri_adr_o, wb_ri_sel_o, wb_ri_we_o, wb_ri_stb_o };
 
assign { wb_rd_dat_i, wb_rd_ack_i, wb_rd_err_i } = rd_inputs ;
assign rd_outputs = { wb_rd_dat_o, wb_rd_adr_o, wb_rd_sel_o, wb_rd_we_o, wb_rd_stb_o };
 
assign { wb_vm_dat_i, wb_vm_ack_i, wb_vm_err_i } = vm_inputs ;
// This is a problem !!!!!!!!!!!!!!!
assign vm_outputs = { data_width_zeros, wb_vm_adr_o, wb_vm_sel_o, wb_vm_we_o, wb_vm_stb_o };
 
assign { wb_dm_dat_i, wb_dm_ack_i, wb_dm_err_i } = dm_inputs ;
assign dm_outputs = { wb_dm_dat_o, wb_dm_adr_o, wb_dm_sel_o, wb_dm_we_o, wb_dm_stb_o };
 
assign { wb_vs_dat_i, wb_vs_adr_i, wb_vs_sel_i, wb_vs_we_i, wb_vs_stb_i } = vs_inputs;
assign vs_outputs = { wb_vs_dat_o, wb_vs_ack_o, wb_vs_err_o };
 
assign { wb_fl_dat_i, wb_fl_adr_i, wb_fl_sel_i, wb_fl_we_i, wb_fl_stb_i } = fl_inputs;
assign fl_outputs = { wb_fl_dat_o, wb_fl_ack_o, wb_fl_err_o };
 
assign { wb_sr_dat_i, wb_sr_adr_i, wb_sr_sel_i, wb_sr_we_i, wb_sr_stb_i } = sr_inputs;
assign sr_outputs = { wb_sr_dat_o, wb_sr_ack_o, wb_sr_err_o };
 
assign { wb_au_dat_i, wb_au_adr_i, wb_au_sel_i, wb_au_we_i, wb_au_stb_i } = au_inputs;
assign au_outputs = { wb_au_dat_o, wb_au_ack_o, wb_au_err_o };
 
//////////////////////////////////////////////////////////////////////////
// Connectivity
 
// VGA slave is only accessable by RISC Data
assign vs_inputs = rd_outputs;
// Audio is only accessable by RISC Data
assign au_inputs = rd_outputs;
 
// SRAM is accessable by either RISC Data or VGA Master
always @(sr_input_sel or rd_outputs or vm_outputs or ri_outputs or dm_outputs or n_mast_i_zeros)
begin
case (sr_input_sel)
`SR_RD: sr_inputs <= rd_outputs;
`SR_RI: sr_inputs <= ri_outputs;
`SR_VM: sr_inputs <= vm_outputs;
`SR_DM: sr_inputs <= dm_outputs;
default: sr_inputs <= n_mast_i_zeros;
endcase
end
 
// FLASH is accessable by either RISC Instruction, RISC Data or Development I/F
assign fl_inputs = ( ri_fl_con ? ri_outputs : rd_fl_con ? rd_outputs : dm_outputs );
 
// RISC Instruction access
assign sr_to_ri = ( sr_input_sel == `SR_RI ? sr_outputs : n_mast_i_zeros );
assign fl_to_ri = ( ri_fl_con ? fl_outputs : n_mast_i_zeros );
assign ri_inputs = sr_to_ri | fl_to_ri;
 
// Development I/F access
assign sr_to_dm = ( sr_input_sel == `SR_DM ? sr_outputs : n_mast_i_zeros );
assign fl_to_dm = ( dm_fl_con ? fl_outputs : n_mast_i_zeros );
assign dm_inputs = sr_to_dm | fl_to_dm;
 
// VGA Master can only access SRAM
assign vm_inputs = ( sr_input_sel == 2'b11 ? sr_outputs : n_mast_i_zeros );
 
// RISC Data can access all 4 slaves
// SRAM can go to two masters
assign sr_to_rd = ( sr_input_sel == `SR_RD ? sr_outputs : n_mast_i_zeros );
// FLASH can go to two masters
assign fl_to_rd = ( ( ri_fl_con | !rd_fl_cs ) ? n_mast_i_zeros : fl_outputs );
// Audio can go to RISC Data
assign au_to_rd = ( ( !rd_au_cs ) ? n_mast_i_zeros : au_outputs );
// Video slave can go to RISC Data
assign vs_to_rd = ( ( !rd_vs_cs ) ? n_mast_i_zeros : vs_outputs );
// Now we just OR all slave outputs
assign rd_inputs = sr_to_rd | fl_to_rd | au_to_rd | vs_to_rd;
 
 
///////////////////////////////////////////////////////////////////////////
// Decoding
 
// decoding address of RISC data
always @( wb_rd_adr_o[addr_width-1:addr_width-2] )
begin
case ( wb_rd_adr_o[addr_width-1:addr_width-2] )
2'b00: rd_cs = 4'b0001;
2'b01: rd_cs = 4'b0010;
2'b10: rd_cs = 4'b0100;
2'b11: rd_cs = 4'b1000;
default: rd_cs = 4'bx;
endcase
end
 
assign rd_sr_cs = rd_cs[2];
assign rd_fl_cs = rd_cs[0];
assign rd_au_cs = rd_cs[1];
assign rd_vs_cs = rd_cs[3];
 
// decoding address of Development I/F
always @( wb_dm_adr_o[addr_width-1:addr_width-2] )
begin
case ( wb_dm_adr_o[addr_width-1:addr_width-2] )
2'b00: dm_cs = 4'b0001;
2'b01: dm_cs = 4'b0010;
2'b10: dm_cs = 4'b0100;
2'b11: dm_cs = 4'b1000;
default: dm_cs = 4'bx;
endcase
end
 
assign dm_sr_cs = dm_cs[2];
assign dm_fl_cs = dm_cs[0];
assign dm_au_cs = dm_cs[1];
assign dm_vs_cs = dm_cs[3];
 
// decoding of address of RISC instruction
assign ri_sr_cs = wb_ri_adr_o[addr_width-1];
assign ri_fl_cs = ~wb_ri_adr_o[addr_width-1];
 
// Priority mechanism for Flash slave between RISC Data, RISC Insn, and Development I/F masters
always @( posedge clk or negedge rstn )
if (!rstn) begin
dm_fl_con <= 1'b0;
rd_fl_con <= 1'b0;
ri_fl_con <= 1'b0;
end
else
case ( { dm_fl_con, rd_fl_con, ri_fl_con } )
3'b000: if ( wb_dm_cyc_o & wb_dm_stb_o & dm_fl_cs ) dm_fl_con <= #1 1'b1;
else if ( wb_rd_cyc_o & wb_rd_stb_o & rd_fl_cs ) rd_fl_con <= #1 1'b1;
else if ( wb_ri_cyc_o & wb_ri_stb_o & ri_fl_cs ) ri_fl_con <= #1 1'b1;
3'b001: if ( (wb_ri_cyc_o & wb_ri_stb_o & ri_fl_cs)
& !(wb_rd_cyc_o & wb_rd_stb_o & rd_fl_cs & wb_fl_ack_o)
& !(wb_dm_cyc_o & wb_dm_stb_o & dm_fl_cs & wb_fl_ack_o) ) ri_fl_con <= #1 1'b1;
else ri_fl_con <= #1 1'b0;
3'b010: if ( wb_rd_cyc_o & wb_rd_stb_o & rd_fl_cs ) rd_fl_con <= #1 1'b1;
else rd_fl_con <= #1 1'b0;
3'b100: if ( wb_dm_cyc_o & wb_dm_stb_o & dm_fl_cs ) dm_fl_con <= #1 1'b1;
else dm_fl_con <= #1 1'b0;
default: $display("Error, two or more masters currently accessing FLASH");
endcase
 
// Priority mechanism between RISC Data, VGA Master and Development I/F Master
always @( posedge clk or negedge rstn )
if (!rstn)
sr_input_sel <= 3'b000;
else
case ( sr_input_sel )
3'b000: if ( wb_vm_cyc_o & wb_vm_stb_o ) sr_input_sel <= #1 `SR_VM;
else
if ( wb_dm_cyc_o & wb_dm_stb_o & dm_sr_cs ) sr_input_sel <= #1 `SR_DM;
else if ( wb_rd_cyc_o & wb_rd_stb_o & rd_sr_cs ) sr_input_sel <= #1 `SR_RD;
else if ( wb_ri_cyc_o & wb_ri_stb_o & ri_sr_cs ) sr_input_sel <= #1 `SR_RI;
`SR_VM: if ( wb_vm_cyc_o & wb_vm_stb_o ) sr_input_sel <= #1 `SR_VM;
else sr_input_sel <= #1 3'b000;
`SR_RI: if ( ( wb_ri_cyc_o & wb_ri_stb_o & ri_sr_cs ) & !(wb_rd_cyc_o & rd_sr_cs & wb_sr_ack_o)) sr_input_sel <= #1 `SR_RI;
else sr_input_sel <= #1 3'b000;
`SR_RD: if ( wb_rd_cyc_o & wb_rd_stb_o & rd_sr_cs & ~wb_rd_ack_i) sr_input_sel <= #1 `SR_RD;
else sr_input_sel <= #1 3'b000;
`SR_DM: if ( wb_dm_cyc_o & wb_dm_stb_o & dm_sr_cs & ~wb_dm_ack_i) sr_input_sel <= #1 `SR_DM;
else sr_input_sel <= #1 3'b000;
default: $display("Error, two or more masters currently accessing SRAM");
endcase
 
// Connecting the cyc signals
assign wb_fl_cyc_i = dm_fl_con ? wb_dm_cyc_o : rd_fl_con ? wb_rd_cyc_o : ri_fl_con ? wb_ri_cyc_o : 1'b0;
assign wb_sr_cyc_i = sr_input_sel == `SR_VM ? wb_vm_cyc_o : sr_input_sel == `SR_RD ? wb_rd_cyc_o : sr_input_sel == `SR_RI ? wb_ri_cyc_o : sr_input_sel == `SR_DM ? wb_dm_cyc_o : 1'b0;
assign wb_au_cyc_i = rd_au_cs ? wb_rd_cyc_o : 1'b0 ;
assign wb_vs_cyc_i = rd_vs_cs ? wb_rd_cyc_o : 1'b0 ;
 
endmodule
/verilog/xfpga_top.v
0,0 → 1,847
//////////////////////////////////////////////////////////////////////
//// ////
//// MP3 demo Top Level ////
//// ////
//// This file is part of the MP3 demo application ////
//// http://www.opencores.org/cores/or1k/mp3/ ////
//// ////
//// Description ////
//// Top level instantiating all the blocks. ////
//// ////
//// To Do: ////
//// - nothing really ////
//// ////
//// Author(s): ////
//// - Lior Shtram, lior.shtram@flextronicssemi.com ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 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 $
 
`define EXCLUDE_DBG
// `define EXCLUDE_VGA
// `define EXCLUDE_RISC
// `define VGA_RAMDAC
 
`include "xfpga_defines.v"
 
module xfpga_top (
 
// Global connections
clk,
// clk2,
rstn,
 
// Flash RAM
flash_rstn,
flash_cen,
flash_oen,
flash_wen,
flash_rdy,
flash_d,
flash_a,
 
// SRAM Right
sram_r_cen,
sram_r_oen,
sram_r0_wen,
sram_r1_wen,
sram_r_d,
sram_r_a,
 
// SRAM Left
sram_l_cen,
sram_l_oen,
sram_l0_wen,
sram_l1_wen,
sram_l_d,
sram_l_a,
 
`ifdef VGA_RAMDAC
 
// VGA RAMDAC
ramdac_pixclk,
ramdac_hsyncn,
ramdac_vsync,
ramdac_blank,
ramdac_p,
ramdac_rdn,
ramdac_wrn,
ramdac_rs,
ramdac_d,
 
`else
 
// VGA Direct
vga_blank,
vga_pclk,
vga_hsyncn,
vga_vsyncn,
vga_r,
vga_g,
vga_b,
 
`endif
 
// Codec connections
codec_mclk,
codec_lrclk,
codec_sclk,
codec_sdin,
codec_sdout,
 
// Ethernet
eth_col,
eth_crs,
eth_trste,
eth_tx_clk,
eth_tx_en,
eth_tx_er,
eth_txd,
eth_rx_clk,
eth_rx_dv,
eth_rx_er,
eth_rxd,
eth_fds_mdint,
eth_mdc,
eth_mdio,
 
// Switches
sw,
 
// Used for tracing fifo activity (CODEC)
USB_VPO,
USB_VMO,
 
// PS2 port
ps2_clk,
ps2_data,
 
// GDB JTAG CPLD
/*
cpld_muxr,
cpld_muxd,
*/
cpld_tdo
 
);
 
 
// Global connections
 
input clk;
//input clk2;
input rstn;
 
// Flash RAM
 
output flash_rstn;
output flash_cen;
output flash_oen;
output flash_wen;
input flash_rdy;
inout [7:0] flash_d;
inout [20:0] flash_a;
 
// SRAM Right
 
output sram_r_cen;
output sram_r1_wen;
output sram_r0_wen;
output sram_r_oen;
output [18:0] sram_r_a;
inout [15:0] sram_r_d;
 
// SRAM Left
 
output sram_l_cen;
output sram_l0_wen;
output sram_l1_wen;
output sram_l_oen;
output [18:0] sram_l_a;
inout [15:0] sram_l_d;
 
`ifdef VGA_RAMDAC
 
output ramdac_pixclk;
output ramdac_hsyncn;
output ramdac_vsync;
output ramdac_blank;
output [7:0] ramdac_p;
output ramdac_rdn;
output ramdac_wrn;
output [2:0] ramdac_rs;
inout [7:0] ramdac_d;
 
`else
 
// VGA Direct
 
output vga_pclk;
output vga_blank;
output vga_hsyncn;
output vga_vsyncn;
output [3:0] vga_r;
output [3:0] vga_g;
output [3:0] vga_b;
 
`endif
 
// Stereo Codec
 
output codec_mclk;
output codec_lrclk;
output codec_sclk;
output codec_sdin;
input codec_sdout;
 
// Ethernet
 
output eth_tx_er;
input eth_tx_clk;
output eth_tx_en;
output [4:0] eth_txd;
input eth_rx_er;
input eth_rx_clk;
input eth_rx_dv;
input [4:0] eth_rxd;
input eth_col;
input eth_crs;
output eth_trste;
input eth_fds_mdint;
inout eth_mdio;
output eth_mdc;
 
// Switches
input [2:1] sw;
 
// Used for tracing fifo activity (CODEC)
output USB_VPO;
output USB_VMO;
 
// PS2 port
inout ps2_clk;
inout ps2_data;
 
// GDB JTAG muxed from the CPLD
/*
input cpld_muxr;
input cpld_muxd;
*/
output cpld_tdo;
 
/////////////////////////////////////////////////////////////////////////////////////
// And now for the insides
 
wire [31:0] wb_vs_adr_i;
wire [31:0] wb_vs_dat_i;
wire [31:0] wb_vs_dat_o;
wire [3:0] wb_vs_sel_i;
wire wb_vs_we_i;
wire wb_vs_stb_i;
wire wb_vs_cyc_i;
wire wb_vs_ack_o;
wire wb_vs_err_o;
 
wire [31:0] wb_vm_adr_o;
wire [31:0] wb_vm_dat_i;
wire [3:0] wb_vm_sel_o;
wire wb_vm_we_o;
wire wb_vm_stb_o;
wire wb_vm_cyc_o;
wire wb_vm_cab_o;
wire wb_vm_ack_i;
wire wb_vm_err_i;
 
wire [31:0] wb_dm_adr_o;
wire [31:0] wb_dm_dat_i;
wire [31:0] wb_dm_dat_o;
wire [3:0] wb_dm_sel_o;
wire wb_dm_we_o;
wire wb_dm_stb_o;
wire wb_dm_cyc_o;
wire wb_dm_cab_o;
wire wb_dm_ack_i;
wire wb_dm_err_i;
 
wire [31:0] wb_ri_adr_o;
wire wb_ri_cyc_o;
wire [31:0] wb_ri_dat_i;
wire [31:0] wb_ri_dat_o;
wire [3:0] wb_ri_sel_o;
wire wb_ri_ack_i;
wire wb_ri_err_i;
wire wb_ri_rty_i;
wire wb_ri_we_o;
wire wb_ri_stb_o;
 
wire [31:0] wb_rd_adr_o;
wire wb_rd_cyc_o;
wire [31:0] wb_rd_dat_i;
wire [31:0] wb_rd_dat_o;
wire [3:0] wb_rd_sel_o;
wire wb_rd_ack_i;
wire wb_rd_err_i;
wire wb_rd_rty_i;
wire wb_rd_we_o;
wire wb_rd_stb_o;
 
wire [31:0] wb_sr_dat_i;
wire [31:0] wb_sr_dat_o;
wire [31:0] wb_sr_adr_i;
wire [3:0] wb_sr_sel_i;
wire wb_sr_we_i;
wire wb_sr_cyc_i;
wire wb_sr_stb_i;
wire wb_sr_ack_o;
wire wb_sr_err_o;
 
wire [31:0] wb_fl_dat_i;
wire [31:0] wb_fl_dat_o;
wire [31:0] wb_fl_adr_i;
wire [3:0] wb_fl_sel_i;
wire wb_fl_we_i;
wire wb_fl_cyc_i;
wire wb_fl_stb_i;
wire wb_fl_ack_o;
wire wb_fl_err_o;
 
wire [31:0] wb_au_dat_i;
wire [31:0] wb_au_dat_o;
wire [31:0] wb_au_adr_i;
wire [3:0] wb_au_sel_i;
wire wb_au_we_i;
wire wb_au_cyc_i;
wire wb_au_stb_i;
wire wb_au_ack_o;
wire wb_au_err_o;
 
wire vga_int;
 
wire audio_dreq;
 
reg my_int;
 
wire [3:0] vga_r_int;
wire [3:0] vga_g_int;
wire [3:0] vga_b_int;
 
wire crt_hsync;
wire crt_vsync;
 
wire [3:0] dbg_lss;
wire [1:0] dbg_is;
wire [10:0] dbg_wp;
wire dbg_bp;
wire [31:0] dbg_dat_dbg;
wire [31:0] dbg_dat_risc;
wire [31:0] dbg_adr;
wire dbg_ewt;
wire dbg_stall;
wire [2:0] dbg_op;
 
wire jtag_tdi;
wire jtag_tms;
wire jtag_tck;
wire jtag_trst;
wire jtag_tdo;
 
wire [20:0] flash_a_int;
wire flash_a_oe;
 
wire simon = sw[1];
wire igor = sw[2];
 
 
reg resetn_d;
reg resetn;
wire wb_clk_i;
wire clk_dll;
wire clk_buf1;
 
`ifdef EXCLUDE_DBG
`else
reg sram_ra;
`endif
 
always @ (posedge wb_clk_i or negedge rstn)
begin
if(~rstn)
resetn_d <= 1'b0;
else
resetn_d <= #1 1'b1;
end
 
always @ (posedge wb_clk_i)
begin
resetn <= #1 resetn_d;
end
 
`ifdef TARGET_VIRTEX
IBUFG IBUFG1(.O(wb_clk_i), .I(clk));
`else
assign wb_clk_i = clk;
`endif
 
/////////////////////////////////////////////////////////////////////////////////////
// GDB JTAG demultiplexer
`ifdef EXCLUDE_DBG
assign jtag_tms = 1'b0;
assign jtag_tdi = 1'b0;
assign jtag_trst = 1'b1;
assign jtag_tck = 1'b0;
assign cpld_tdo = 1'b0;
 
assign flash_a = flash_a_int;
`else
/* SIMON */
 
always @ (posedge clk or negedge rstn)
begin
if(~rstn)
sram_ra <= 1'b0;
else if(wb_sr_cyc_i & wb_sr_stb_i & !wb_sr_we_i & !sram_ra)
sram_ra <= #1 1'b1;
end
assign jtag_tms = ~sram_ra ? 1'b0 : flash_a[6];
assign jtag_tdi = ~sram_ra ? 1'b0 : flash_a[7];
assign jtag_trst = ~sram_ra ? 1'b1 : flash_a[8];
assign jtag_tck = ~sram_ra ? 1'b0 : flash_a[9];
assign cpld_tdo = ~sram_ra ? 1'b0 : jtag_tdo;
 
assign flash_a = ~sram_ra ? flash_a_int : 21'bz;
`endif
 
/////////////////////////////////////////////////////////////////////////////////////
// The VGA block
 
`ifdef EXCLUDE_VGA
initial $display("Warning: exclude vga.");
vga_dummy_top vga
(
.wb_clk_i( wb_clk_i ),
.wb_rst_i( resetn ),
.rst_nreset_i( resetn ),
.wb_inta_o( vga_int ),
.clk_pclk_i( vga_pclk ),
.vga_hsync_pad_o( vga_hsyncn ),
.vga_vsync_pad_o( vga_vsyncn ),
.vga_csync_pad_o( ),
.vga_blank_pad_o( vga_blank ),
.vga_r_pad_o( vga_r[3:0] ),
.vga_b_pad_o( vga_b[3:0] ),
.vga_g_pad_o( vga_g[3:0] ),
 
.wb_adr_i( wb_vs_adr_i ),
.wb_sdat_i( wb_vs_dat_i ),
.wb_sdat_o( wb_vs_dat_o ),
.wb_sel_i( wb_vs_sel_i ),
.wb_we_i( wb_vs_we_i ),
.wb_vga_stb_i( wb_vs_stb_i ),
.wb_clut_stb_i( wb_vs_stb_i ),
.wb_cyc_i( wb_vs_cyc_i ),
.wb_ack_o( wb_vs_ack_o ),
.wb_err_o( wb_vs_err_o ),
 
.wb_adr_o( wb_vm_adr_o ),
.wb_mdat_i( wb_vm_dat_i ),
.wb_sel_o( wb_vm_sel_o ),
.wb_we_o( wb_vm_we_o ),
.wb_stb_o( wb_vm_stb_o ),
.wb_cyc_o( wb_vm_cyc_o ),
.wb_cab_o( wb_vm_cab_o ),
.wb_ack_i( wb_vm_ack_i ),
.wb_err_i( wb_vm_err_i )
);
`else
// CRT controler instance
ssvga_top CRT
(
// Clock and reset
.wb_clk_i(wb_clk_i),
.wb_rst_i(~resetn),
// WISHBONE Master I/F
.wbm_cyc_o (wb_vm_cyc_o),
.wbm_stb_o (wb_vm_stb_o),
.wbm_sel_o (wb_vm_sel_o),
.wbm_we_o (wb_vm_we_o),
.wbm_adr_o (wb_vm_adr_o),
.wbm_dat_o (),
.wbm_cab_o (wb_vm_cab_o),
.wbm_dat_i (wb_vm_dat_i),
.wbm_ack_i (wb_vm_ack_i),
.wbm_err_i (wb_vm_err_i),
.wbm_rty_i (1'b0),
 
// WISHBONE Slave I/F
.wbs_cyc_i (wb_vs_cyc_i),
.wbs_stb_i (wb_vs_stb_i),
.wbs_sel_i (wb_vs_sel_i),
.wbs_we_i (wb_vs_we_i),
.wbs_adr_i (wb_vs_adr_i),
.wbs_dat_i (wb_vs_dat_i),
.wbs_cab_i (1'b0),
.wbs_dat_o (wb_vs_dat_o),
.wbs_ack_o (wb_vs_ack_o),
.wbs_err_o (wb_vs_err_o),
.wbs_rty_o (),
 
// Signals to VGA display
.pad_hsync_o (crt_hsync),
.pad_vsync_o (crt_vsync),
.pad_rgb_o ({vga_r_int, vga_g_int, vga_b_int}),
.led_o (),
.pix_clk (crt_out_reg_clk),
.misc({11'b0, jtag_tdo, jtag_trst, jtag_tdi, jtag_tms, jtag_tck})
);
 
CRTC_IOB crt_out_reg
(
.reset_in (~resetn),
.clk_in (crt_out_reg_clk),
.hsync_in (crt_hsync),
.vsync_in (crt_vsync),
.rgb_in ({vga_r_int, vga_g_int, vga_b_int}),
.hsync_out (vga_hsyncn),
.vsync_out (vga_vsyncn),
.rgb_out ({vga_r, vga_g, vga_b})
) ;
`endif
 
 
/////////////////////////////////////////////////////////////////////////////////////
// The Audio block
//
audio_top audio (
.clk( wb_clk_i ),
.rstn( resetn ),
.wb_dat_i( wb_au_dat_i ),
.wb_dat_o( wb_au_dat_o ),
.wb_adr_i( wb_au_adr_i ),
.wb_sel_i( wb_au_sel_i ),
.wb_we_i( wb_au_we_i ),
.wb_cyc_i( wb_au_cyc_i ),
.wb_stb_i( wb_au_stb_i ),
.wb_ack_o( wb_au_ack_o ),
.wb_err_o( wb_au_err_o ),
.mclk( codec_mclk ),
.lrclk( codec_lrclk ),
.sclk( codec_sclk ),
.sdin( codec_sdin ),
.sdout( codec_sdout ),
.audio_dreq( audio_dreq ),
.igor(simon),
.simon(igor),
.USB_VPO(USB_VPO),
.USB_VMO(USB_VMO)
 
);
 
//////////////////////////////////////////////////////
// Development i/f
dbg_top dbg1 (
/*
.tms_pad_i(1'b0),
.tck_pad_i(1'b0),
.trst_pad_i(1'b1),
.tdi_pad_i(1'b0),
.tdo_pad_o(),
*/
.tms_pad_i(jtag_tms),
.tck_pad_i(jtag_tck),
.trst_pad_i(jtag_trst),
.tdi_pad_i(jtag_tdi),
.tdo_pad_o(jtag_tdo),
 
.capture_dr_o(),
.shift_dr_o(),
.update_dr_o(),
.extest_selected_o(),
.bs_chain_i(1'b0),
.wb_rst_i(~resetn),
.risc_clk_i(wb_clk_i),
.risc_data_i(dbg_dat_risc),
.wp_i(dbg_wp),
.bp_i(dbg_bp),
.lsstatus_i(dbg_lss),
.istatus_i(dbg_is),
 
.risc_data_o(dbg_dat_dbg),
.risc_addr_o(dbg_adr),
.opselect_o(dbg_op),
.risc_stall_o(dbg_stall),
.reset_o(),
 
.wb_clk_i(wb_clk_i),
.wb_adr_o( wb_dm_adr_o ),
.wb_dat_i( wb_dm_dat_i ),
.wb_dat_o( wb_dm_dat_o ),
.wb_sel_o( wb_dm_sel_o ),
.wb_we_o( wb_dm_we_o ),
.wb_stb_o( wb_dm_stb_o ),
.wb_cyc_o( wb_dm_cyc_o ),
.wb_cab_o( wb_dm_cab_o ),
.wb_ack_i( wb_dm_ack_i ),
.wb_err_i( wb_dm_err_i )
);
 
/////////////////////////////////////////////////////////////////////////////////////
// The CPU block
`ifdef EXCLUDE_RISC
or1200_dummy risc (
`else
or1200 risc (
`endif
.iwb_clk_i( wb_clk_i ),
.iwb_rst_i( ~resetn ),
.iwb_cyc_o( wb_ri_cyc_o ),
.iwb_adr_o( wb_ri_adr_o ),
.iwb_dat_i( wb_ri_dat_i ),
.iwb_dat_o( wb_ri_dat_o ),
.iwb_sel_o( wb_ri_sel_o ),
.iwb_ack_i( wb_ri_ack_i ),
.iwb_err_i( wb_ri_err_i ),
.iwb_rty_i( wb_ri_rty_i ),
.iwb_we_o( wb_ri_we_o ),
.iwb_stb_o( wb_ri_stb_o ),
 
.dwb_clk_i( wb_clk_i ),
.dwb_rst_i( ~resetn ),
.dwb_cyc_o( wb_rd_cyc_o ),
.dwb_adr_o( wb_rd_adr_o ),
.dwb_dat_i( wb_rd_dat_i ),
.dwb_dat_o( wb_rd_dat_o ),
.dwb_sel_o( wb_rd_sel_o ),
.dwb_ack_i( wb_rd_ack_i ),
.dwb_err_i( wb_rd_err_i ),
.dwb_rty_i( wb_rd_rty_i ),
.dwb_we_o( wb_rd_we_o ),
.dwb_stb_o( wb_rd_stb_o ),
 
.rst( ~resetn ),
.clk( wb_clk_i ),
.clkdiv_by_2( 1'b1 ),
 
.dbg_stall_i(dbg_stall),
.dbg_dat_i(dbg_dat_dbg),
.dbg_adr_i(dbg_adr),
.dbg_op_i(dbg_op),
.dbg_ewt_i(1'b0),
 
.dbg_lss_o(dbg_lss),
.dbg_is_o(dbg_is),
.dbg_wp_o(dbg_wp),
.dbg_bp_o(dbg_bp),
.dbg_dat_o(dbg_dat_risc),
 
.pm_clksd( ),
.pm_cpustall( 1'b0 ),
.pm_dc_gate( ),
.pm_ic_gate( ),
.pm_dmmu_gate( ),
.pm_immu_gate( ),
.pm_tt_gate( ),
.pm_cpu_gate( ),
.pm_wakeup( ),
.pm_lvolt( ),
// .pic_ints( { 19'b0, audio_dreq } )
.pic_ints( { my_int, 19'b0} )
);
 
/////////////////////////////////////////////////////////////////////////////////////
// The Flash controller
flash_top flash (
.clk( wb_clk_i ),
.rstn( resetn ),
.wb_dat_i( wb_fl_dat_i ),
.wb_dat_o( wb_fl_dat_o ),
.wb_adr_i( wb_fl_adr_i ),
.wb_sel_i( wb_fl_sel_i ),
.wb_we_i( wb_fl_we_i ),
.wb_cyc_i( wb_fl_cyc_i ),
.wb_stb_i( wb_fl_stb_i ),
.wb_ack_o( wb_fl_ack_o ),
.wb_err_o( wb_fl_err_o ),
.flash_rstn( flash_rstn ),
.cen( flash_cen ),
.oen( flash_oen ),
.wen( flash_wen ),
.rdy( flash_rdy ),
.d( flash_d ),
.a( flash_a_int ),
.a_oe( flash_a_oe )
);
 
/////////////////////////////////////////////////////////////////////////////////////
// The SRAM controller
sram_top sram (
.clk( wb_clk_i ),
.rstn( resetn ),
.wb_dat_i( wb_sr_dat_i ),
.wb_dat_o( wb_sr_dat_o ),
.wb_adr_i( wb_sr_adr_i ),
.wb_sel_i( wb_sr_sel_i ),
.wb_we_i( wb_sr_we_i ),
.wb_cyc_i( wb_sr_cyc_i ),
.wb_stb_i( wb_sr_stb_i ),
.wb_ack_o( wb_sr_ack_o ),
.wb_err_o( wb_sr_err_o ),
.r_cen( sram_r_cen ),
.r0_wen( sram_r0_wen ),
.r1_wen( sram_r1_wen ),
.r_oen( sram_r_oen ),
.r_a( sram_r_a ),
.r_d( sram_r_d ),
.l_cen( sram_l_cen ),
.l0_wen( sram_l0_wen ),
.l1_wen( sram_l1_wen ),
.l_oen( sram_l_oen ),
.l_a( sram_l_a ),
.l_d( sram_l_d )
);
 
/////////////////////////////////////////////////////////////////////////////////////
// The Traffic COP
//
tcop_top tcop (
.clk( wb_clk_i ),
.rstn( resetn ),
 
// The VGA connections
.wb_vs_adr_i( wb_vs_adr_i ),
.wb_vs_dat_i( wb_vs_dat_i ),
.wb_vs_dat_o( wb_vs_dat_o ),
.wb_vs_sel_i( wb_vs_sel_i ),
.wb_vs_we_i( wb_vs_we_i ),
.wb_vs_stb_i( wb_vs_stb_i ),
.wb_vs_cyc_i( wb_vs_cyc_i ),
.wb_vs_ack_o( wb_vs_ack_o ),
.wb_vs_err_o( wb_vs_err_o ),
 
.wb_vm_adr_o( wb_vm_adr_o ),
.wb_vm_dat_i( wb_vm_dat_i ),
.wb_vm_sel_o( wb_vm_sel_o ),
.wb_vm_we_o( wb_vm_we_o ),
.wb_vm_stb_o( wb_vm_stb_o ),
.wb_vm_cyc_o( wb_vm_cyc_o ),
.wb_vm_cab_o( wb_vm_cab_o ),
.wb_vm_ack_i( wb_vm_ack_i ),
.wb_vm_err_i( wb_vm_err_i ),
 
// The Development I/F
 
.wb_dm_adr_o( wb_dm_adr_o ),
.wb_dm_dat_i( wb_dm_dat_i ),
.wb_dm_dat_o( wb_dm_dat_o ),
.wb_dm_sel_o( wb_dm_sel_o ),
.wb_dm_we_o( wb_dm_we_o ),
.wb_dm_stb_o( wb_dm_stb_o ),
.wb_dm_cyc_o( wb_dm_cyc_o ),
.wb_dm_cab_o( wb_dm_cab_o ),
.wb_dm_ack_i( wb_dm_ack_i ),
.wb_dm_err_i( wb_dm_err_i ),
 
// The RISC connections
 
.wb_ri_cyc_o( wb_ri_cyc_o ),
.wb_ri_adr_o( wb_ri_adr_o ),
.wb_ri_dat_i( wb_ri_dat_i ),
.wb_ri_dat_o( wb_ri_dat_o ),
.wb_ri_sel_o( wb_ri_sel_o ),
.wb_ri_ack_i( wb_ri_ack_i ),
.wb_ri_err_i( wb_ri_err_i ),
.wb_ri_rty_i( wb_ri_rty_i ),
.wb_ri_we_o( wb_ri_we_o ),
.wb_ri_stb_o( wb_ri_stb_o ),
 
.wb_rd_cyc_o( wb_rd_cyc_o ),
.wb_rd_adr_o( wb_rd_adr_o ),
.wb_rd_dat_i( wb_rd_dat_i ),
.wb_rd_dat_o( wb_rd_dat_o ),
.wb_rd_sel_o( wb_rd_sel_o ),
.wb_rd_ack_i( wb_rd_ack_i ),
.wb_rd_err_i( wb_rd_err_i ),
.wb_rd_rty_i( wb_rd_rty_i ),
.wb_rd_we_o( wb_rd_we_o ),
.wb_rd_stb_o( wb_rd_stb_o ),
 
// The SRAM
 
.wb_sr_dat_i( wb_sr_dat_i ),
.wb_sr_dat_o( wb_sr_dat_o ),
.wb_sr_adr_i( wb_sr_adr_i ),
.wb_sr_sel_i( wb_sr_sel_i ),
.wb_sr_we_i( wb_sr_we_i ),
.wb_sr_cyc_i( wb_sr_cyc_i ),
.wb_sr_stb_i( wb_sr_stb_i ),
.wb_sr_ack_o( wb_sr_ack_o ),
.wb_sr_err_o( wb_sr_err_o ),
 
// The Flash RAM connections
 
.wb_fl_dat_i( wb_fl_dat_i ),
.wb_fl_dat_o( wb_fl_dat_o ),
.wb_fl_adr_i( wb_fl_adr_i ),
.wb_fl_sel_i( wb_fl_sel_i ),
.wb_fl_we_i( wb_fl_we_i ),
.wb_fl_cyc_i( wb_fl_cyc_i ),
.wb_fl_stb_i( wb_fl_stb_i ),
.wb_fl_ack_o( wb_fl_ack_o ),
.wb_fl_err_o( wb_fl_err_o ),
 
// The Audio connections
 
.wb_au_dat_i( wb_au_dat_i ),
.wb_au_dat_o( wb_au_dat_o ),
.wb_au_adr_i( wb_au_adr_i ),
.wb_au_sel_i( wb_au_sel_i ),
.wb_au_we_i( wb_au_we_i ),
.wb_au_cyc_i( wb_au_cyc_i ),
.wb_au_stb_i( wb_au_stb_i ),
.wb_au_ack_o( wb_au_ack_o ),
.wb_au_err_o( wb_au_err_o )
);
 
 
// Connecting all the leftovers
// synplicity
 
always @(posedge wb_clk_i)
// my_int <= $random;
my_int <= 1'b0;
endmodule
 
/verilog/dbg_interface/dbg_sync_clk1_clk2.v
0,0 → 1,148
//////////////////////////////////////////////////////////////////////
//// ////
//// dbg_sync_clk1_clk2.v ////
//// ////
//// This file is part of the SoC/OpenRISC Development Interface ////
//// http://www.opencores.org/cores/DebugInterface/ ////
//// ////
//// Author(s): ////
//// - Igor Mohor (igorM@opencores.org) ////
//// ////
//// All additional information is avaliable in the Readme.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 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 $
// Revision 1.1.1.1 2001/10/06 10:19:09 igorm
// no message
//
// Revision 1.1.1.1 2001/09/13 13:49:19 mohor
// Initial official release.
//
//
//
//
//
 
`include "dbg_timescale.v"
 
// FF in clock domain 1 is being set by a signal from the clock domain 2
module dbg_sync_clk1_clk2 (clk1, clk2, reset1, reset2, set2, sync_out);
 
parameter Tp = 1;
 
input clk1;
input clk2;
input reset1;
input reset2;
input set2;
 
output sync_out;
 
reg set2_q;
reg set2_q2;
reg set1_q;
reg set1_q2;
reg clear2_q;
reg clear2_q2;
reg sync_out;
 
wire z;
 
assign z = set2 | set2_q & ~clear2_q2;
 
 
// Latching and synchronizing "set" to clk2
always @ (posedge clk2 or posedge reset2)
begin
if(reset2)
set2_q <=#Tp 1'b0;
else
set2_q <=#Tp z;
end
 
 
always @ (posedge clk2 or posedge reset2)
begin
if(reset2)
set2_q2 <=#Tp 1'b0;
else
set2_q2 <=#Tp set2_q;
end
 
 
// Synchronizing "set" to clk1
always @ (posedge clk1 or posedge reset1)
begin
if(reset1)
set1_q <=#Tp 1'b0;
else
set1_q <=#Tp set2_q2;
end
 
 
always @ (posedge clk1 or posedge reset1)
begin
if(reset1)
set1_q2 <=#Tp 1'b0;
else
set1_q2 <=#Tp set1_q;
end
 
 
// Synchronizing "clear" to clk2
always @ (posedge clk2 or posedge reset2)
begin
if(reset2)
clear2_q <=#Tp 1'b0;
else
clear2_q <=#Tp set1_q2;
end
 
 
always @ (posedge clk2 or posedge reset2)
begin
if(reset2)
clear2_q2 <=#Tp 1'b0;
else
clear2_q2 <=#Tp clear2_q;
end
 
 
always @ (posedge clk1 or posedge reset1)
begin
if(reset1)
sync_out <=#Tp 1'b0;
else
sync_out <=#Tp set1_q2;
end
 
endmodule
/verilog/dbg_interface/dbg_top.v
0,0 → 1,1268
//////////////////////////////////////////////////////////////////////
//// ////
//// dbg_top.v ////
//// ////
//// ////
//// This file is part of the SoC/OpenRISC Development Interface ////
//// http://www.opencores.org/cores/DebugInterface/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@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 $
// Revision 1.7 2001/10/16 10:09:56 mohor
// Signal names changed to lowercase.
//
//
// Revision 1.6 2001/10/15 09:55:47 mohor
// Wishbone interface added, few fixes for better performance,
// hooks for boundary scan testing added.
//
// Revision 1.5 2001/09/24 14:06:42 mohor
// Changes connected to the OpenRISC access (SPR read, SPR write).
//
// Revision 1.4 2001/09/20 10:11:25 mohor
// Working version. Few bugs fixed, comments added.
//
// Revision 1.3 2001/09/19 11:55:13 mohor
// Asynchronous set/reset not used in trace any more.
//
// Revision 1.2 2001/09/18 14:13:47 mohor
// Trace fixed. Some registers changed, trace simplified.
//
// Revision 1.1.1.1 2001/09/13 13:49:19 mohor
// Initial official release.
//
// Revision 1.3 2001/06/01 22:22:35 mohor
// This is a backup. It is not a fully working version. Not for use, yet.
//
// Revision 1.2 2001/05/18 13:10:00 mohor
// Headers changed. All additional information is now avaliable in the README.txt file.
//
// Revision 1.1.1.1 2001/05/18 06:35:02 mohor
// Initial release
//
//
 
`include "dbg_timescale.v"
`include "dbg_defines.v"
 
// Top module
module dbg_top(
// 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] wb_adr_o;
reg [31:0] wb_dat_o;
reg wb_we_o;
reg wb_cyc_o;
 
// TAP states
reg TestLogicReset;
reg RunTestIdle;
reg SelectDRScan;
reg CaptureDR;
reg ShiftDR;
reg Exit1DR;
reg PauseDR;
reg Exit2DR;
reg UpdateDR;
 
reg SelectIRScan;
reg CaptureIR;
reg ShiftIR;
reg Exit1IR;
reg PauseIR;
reg Exit2IR;
reg UpdateIR;
 
 
// Defining which instruction is selected
reg EXTESTSelected;
reg SAMPLE_PRELOADSelected;
reg IDCODESelected;
reg CHAIN_SELECTSelected;
reg INTESTSelected;
reg CLAMPSelected;
reg CLAMPZSelected;
reg HIGHZSelected;
reg DEBUGSelected;
reg BYPASSSelected;
 
reg [31:0] ADDR;
reg [31:0] DataOut;
 
reg [`OPSELECTWIDTH-1:0] opselect_o; // Operation selection (selecting what kind of data is set to the risc_data_i)
 
reg [`CHAIN_ID_LENGTH-1:0] Chain; // Selected chain
reg [31:0] RISC_DATAINLatch; // Data from DataIn is latched one risc_clk_i clock cycle after RISC register is
// accessed for reading
reg [31:0] RegisterReadLatch; // Data when reading register is latched one TCK clock after the register is read.
reg RegAccessTck; // Indicates access to the registers (read or write)
reg RISCAccessTck; // Indicates access to the RISC (read or write)
reg [7:0] BitCounter; // Counting bits in the ShiftDR and Exit1DR stages
reg RW; // Read/Write bit
reg CrcMatch; // The crc that is shifted in and the internaly calculated crc are equal
 
reg RegAccess_q; // Delayed signals used for accessing the registers
reg RegAccess_q2; // Delayed signals used for accessing the registers
reg RISCAccess_q; // Delayed signals used for accessing the RISC
reg RISCAccess_q2; // Delayed signals used for accessing the RISC
 
reg wb_AccessTck; // Indicates access to the WISHBONE
reg [31:0] WBReadLatch; // Data latched during WISHBONE read
reg WBErrorLatch; // Error latched during WISHBONE read
 
wire TCK = tck_pad_i;
wire TMS = tms_pad_i;
wire TDI = tdi_pad_i;
wire RESET = ~trst_pad_i | wb_rst_i; // trst_pad_i is active low
 
wire [31:0] RegDataIn; // Data from registers (read data)
wire [`CRC_LENGTH-1:0] CalculatedCrcOut; // CRC calculated in this module. This CRC is apended at the end of the TDO.
 
wire RiscStall_reg; // RISC is stalled by setting the register bit
wire RiscReset_reg; // RISC is reset by setting the register bit
wire RiscStall_trace; // RISC is stalled by trace module
wire RegisterScanChain; // Register Scan chain selected
wire RiscDebugScanChain; // Risc Debug Scan chain selected
wire WishboneScanChain; // WISHBONE Scan chain selected
 
wire RiscStall_read_access; // Stalling RISC because of the read access (SPR read)
wire RiscStall_write_access; // Stalling RISC because of the write access (SPR write)
wire RiscStall_access; // Stalling RISC because of the read or write access
 
assign capture_dr_o = CaptureDR;
assign shift_dr_o = ShiftDR;
assign update_dr_o = UpdateDR;
assign extest_selected_o = EXTESTSelected;
wire BS_CHAIN_I = bs_chain_i;
// This signals are used only when TRACE is used in the design
`ifdef TRACE_ENABLED
wire [39:0] TraceChain; // Chain that comes from trace module
reg ReadBuffer_Tck; // Command for incrementing the trace read pointer (synchr with TCK)
wire ReadTraceBuffer; // Command for incrementing the trace read pointer (synchr with MClk)
reg ReadTraceBuffer_q; // Delayed command for incrementing the trace read pointer (synchr with MClk)
wire ReadTraceBufferPulse; // Pulse for reading the trace buffer (valid for only one Mclk command)
 
// Outputs from registers
wire ContinMode; // Trace working in continous mode
wire TraceEnable; // Trace enabled
wire [10:0] WpTrigger; // Watchpoint starts trigger
wire BpTrigger; // Breakpoint starts trigger
wire [3:0] LSSTrigger; // Load/store status starts trigger
wire [1:0] ITrigger; // Instruction status starts trigger
wire [1:0] TriggerOper; // Trigger operation
wire WpTriggerValid; // Watchpoint trigger is valid
wire BpTriggerValid; // Breakpoint trigger is valid
wire LSSTriggerValid; // Load/store status trigger is valid
wire ITriggerValid; // Instruction status trigger is valid
wire [10:0] WpQualif; // Watchpoint starts qualifier
wire BpQualif; // Breakpoint starts qualifier
wire [3:0] LSSQualif; // Load/store status starts qualifier
wire [1:0] IQualif; // Instruction status starts qualifier
wire [1:0] QualifOper; // Qualifier operation
wire WpQualifValid; // Watchpoint qualifier is valid
wire BpQualifValid; // Breakpoint qualifier is valid
wire LSSQualifValid; // Load/store status qualifier is valid
wire IQualifValid; // Instruction status qualifier is valid
wire [10:0] WpStop; // Watchpoint stops recording of the trace
wire BpStop; // Breakpoint stops recording of the trace
wire [3:0] LSSStop; // Load/store status stops recording of the trace
wire [1:0] IStop; // Instruction status stops recording of the trace
wire [1:0] StopOper; // Stop operation
wire WpStopValid; // Watchpoint stop is valid
wire BpStopValid; // Breakpoint stop is valid
wire LSSStopValid; // Load/store status stop is valid
wire IStopValid; // Instruction status stop is valid
wire RecordPC; // Recording program counter
wire RecordLSEA; // Recording load/store effective address
wire RecordLDATA; // Recording load data
wire RecordSDATA; // Recording store data
wire RecordReadSPR; // Recording read SPR
wire RecordWriteSPR; // Recording write SPR
wire RecordINSTR; // Recording instruction
// End: Outputs from registers
 
wire TraceTestScanChain; // Trace Test Scan chain selected
wire [47:0] Trace_Data; // Trace data
 
wire [`OPSELECTWIDTH-1:0]opselect_trace;// Operation selection (trace selecting what kind of
// data is set to the risc_data_i)
 
`endif
 
 
/**********************************************************************************
* *
* TAP State Machine: Fully JTAG compliant *
* *
**********************************************************************************/
 
// TestLogicReset state
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
TestLogicReset<=#Tp 1;
else
begin
if(TMS & (TestLogicReset | SelectIRScan))
TestLogicReset<=#Tp 1;
else
TestLogicReset<=#Tp 0;
end
end
 
// RunTestIdle state
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
RunTestIdle<=#Tp 0;
else
begin
if(~TMS & (TestLogicReset | RunTestIdle | UpdateDR | UpdateIR))
RunTestIdle<=#Tp 1;
else
RunTestIdle<=#Tp 0;
end
end
 
// SelectDRScan state
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
SelectDRScan<=#Tp 0;
else
begin
if(TMS & (RunTestIdle | UpdateDR | UpdateIR))
SelectDRScan<=#Tp 1;
else
SelectDRScan<=#Tp 0;
end
end
 
// CaptureDR state
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
CaptureDR<=#Tp 0;
else
begin
if(~TMS & SelectDRScan)
CaptureDR<=#Tp 1;
else
CaptureDR<=#Tp 0;
end
end
 
// ShiftDR state
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
ShiftDR<=#Tp 0;
else
begin
if(~TMS & (CaptureDR | ShiftDR | Exit2DR))
ShiftDR<=#Tp 1;
else
ShiftDR<=#Tp 0;
end
end
 
// Exit1DR state
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
Exit1DR<=#Tp 0;
else
begin
if(TMS & (CaptureDR | ShiftDR))
Exit1DR<=#Tp 1;
else
Exit1DR<=#Tp 0;
end
end
 
// PauseDR state
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
PauseDR<=#Tp 0;
else
begin
if(~TMS & (Exit1DR | PauseDR))
PauseDR<=#Tp 1;
else
PauseDR<=#Tp 0;
end
end
 
// Exit2DR state
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
Exit2DR<=#Tp 0;
else
begin
if(TMS & PauseDR)
Exit2DR<=#Tp 1;
else
Exit2DR<=#Tp 0;
end
end
 
// UpdateDR state
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
UpdateDR<=#Tp 0;
else
begin
if(TMS & (Exit1DR | Exit2DR))
UpdateDR<=#Tp 1;
else
UpdateDR<=#Tp 0;
end
end
 
// Delayed UpdateDR state
reg UpdateDR_q;
always @ (posedge TCK)
begin
UpdateDR_q<=#Tp UpdateDR;
end
 
 
// SelectIRScan state
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
SelectIRScan<=#Tp 0;
else
begin
if(TMS & SelectDRScan)
SelectIRScan<=#Tp 1;
else
SelectIRScan<=#Tp 0;
end
end
 
// CaptureIR state
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
CaptureIR<=#Tp 0;
else
begin
if(~TMS & SelectIRScan)
CaptureIR<=#Tp 1;
else
CaptureIR<=#Tp 0;
end
end
 
// ShiftIR state
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
ShiftIR<=#Tp 0;
else
begin
if(~TMS & (CaptureIR | ShiftIR | Exit2IR))
ShiftIR<=#Tp 1;
else
ShiftIR<=#Tp 0;
end
end
 
// Exit1IR state
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
Exit1IR<=#Tp 0;
else
begin
if(TMS & (CaptureIR | ShiftIR))
Exit1IR<=#Tp 1;
else
Exit1IR<=#Tp 0;
end
end
 
// PauseIR state
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
PauseIR<=#Tp 0;
else
begin
if(~TMS & (Exit1IR | PauseIR))
PauseIR<=#Tp 1;
else
PauseIR<=#Tp 0;
end
end
 
// Exit2IR state
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
Exit2IR<=#Tp 0;
else
begin
if(TMS & PauseIR)
Exit2IR<=#Tp 1;
else
Exit2IR<=#Tp 0;
end
end
 
// UpdateIR state
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
UpdateIR<=#Tp 0;
else
begin
if(TMS & (Exit1IR | Exit2IR))
UpdateIR<=#Tp 1;
else
UpdateIR<=#Tp 0;
end
end
 
/**********************************************************************************
* *
* End: TAP State Machine *
* *
**********************************************************************************/
 
 
 
/**********************************************************************************
* *
* JTAG_IR: JTAG Instruction Register *
* *
**********************************************************************************/
wire [1:0]Status = 2'b10; // Holds current chip status. Core should return this status. For now a constant is used.
 
reg [`IR_LENGTH-1:0]JTAG_IR; // Instruction register
reg [`IR_LENGTH-1:0]LatchedJTAG_IR;
 
reg TDOInstruction;
 
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
JTAG_IR[`IR_LENGTH-1:0] <= #Tp 0;
else
begin
if(CaptureIR)
begin
JTAG_IR[1:0] <= #Tp 2'b01; // This value is fixed for easier fault detection
JTAG_IR[3:2] <= #Tp Status[1:0]; // Current status of chip
end
else
begin
if(ShiftIR)
begin
JTAG_IR[`IR_LENGTH-1:0] <= #Tp {TDI, JTAG_IR[`IR_LENGTH-1:1]};
end
end
end
end
 
 
//TDO is changing on the falling edge of TCK
always @ (negedge TCK)
begin
if(ShiftIR)
TDOInstruction <= #Tp JTAG_IR[0];
end
 
/**********************************************************************************
* *
* End: JTAG_IR *
* *
**********************************************************************************/
 
 
/**********************************************************************************
* *
* JTAG_DR: JTAG Data Register *
* *
**********************************************************************************/
wire [31:0] IDCodeValue = `IDCODE_VALUE; // IDCODE value is 32-bit long.
 
reg [`DR_LENGTH-1:0]JTAG_DR_IN; // Data register
reg TDOData;
 
 
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
JTAG_DR_IN[`DR_LENGTH-1:0]<=#Tp 0;
else
if(ShiftDR)
JTAG_DR_IN[BitCounter]<=#Tp TDI;
end
 
wire [72:0] RISC_Data;
wire [45:0] Register_Data;
wire [72:0] WISHBONE_Data;
wire wb_Access_wbClk;
 
assign RISC_Data = {CalculatedCrcOut, RISC_DATAINLatch, 33'h0};
assign Register_Data = {CalculatedCrcOut, RegisterReadLatch, 6'h0};
assign WISHBONE_Data = {CalculatedCrcOut, WBReadLatch, 32'h0, WBErrorLatch};
 
 
`ifdef TRACE_ENABLED
assign Trace_Data = {CalculatedCrcOut, TraceChain};
`endif
 
//TDO is changing on the falling edge of TCK
always @ (negedge TCK or posedge RESET)
begin
if(RESET)
begin
TDOData <= #Tp 0;
`ifdef TRACE_ENABLED
ReadBuffer_Tck<=#Tp 0;
`endif
end
else
if(UpdateDR)
begin
TDOData <= #Tp CrcMatch;
`ifdef TRACE_ENABLED
if(DEBUGSelected & TraceTestScanChain & TraceChain[0]) // Sample in the trace buffer is valid
ReadBuffer_Tck<=#Tp 1; // Increment read pointer
`endif
end
else
begin
if(ShiftDR)
begin
if(IDCODESelected)
TDOData <= #Tp IDCodeValue[BitCounter]; // IDCODE is shifted out
else
if(CHAIN_SELECTSelected)
TDOData <= #Tp 0;
else
if(DEBUGSelected)
begin
if(RiscDebugScanChain)
TDOData <= #Tp RISC_Data[BitCounter]; // Data read from RISC in the previous cycle is shifted out
else
if(RegisterScanChain)
TDOData <= #Tp Register_Data[BitCounter]; // Data read from register in the previous cycle is shifted out
else
if(WishboneScanChain)
TDOData <= #Tp WISHBONE_Data[BitCounter]; // Data read from the WISHBONE slave
`ifdef TRACE_ENABLED
else
if(TraceTestScanChain)
TDOData <= #Tp Trace_Data[BitCounter]; // Data from the trace buffer is shifted out
`endif
end
end
else
begin
TDOData <= #Tp 0;
`ifdef TRACE_ENABLED
ReadBuffer_Tck<=#Tp 0;
`endif
end
end
end
 
/**********************************************************************************
* *
* End: JTAG_DR *
* *
**********************************************************************************/
 
 
 
/**********************************************************************************
* *
* CHAIN_SELECT logic *
* *
**********************************************************************************/
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
Chain[`CHAIN_ID_LENGTH-1:0]<=#Tp `GLOBAL_BS_CHAIN; // Global BS chain is selected after reset
else
if(UpdateDR & CHAIN_SELECTSelected & CrcMatch)
Chain[`CHAIN_ID_LENGTH-1:0]<=#Tp JTAG_DR_IN[3:0]; // New chain is selected
end
 
 
 
/**********************************************************************************
* *
* Register read/write logic *
* RISC registers read/write logic *
* *
**********************************************************************************/
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
begin
ADDR[31:0] <=#Tp 32'h0;
DataOut[31:0] <=#Tp 32'h0;
RW <=#Tp 1'b0;
RegAccessTck <=#Tp 1'b0;
RISCAccessTck <=#Tp 1'b0;
wb_adr_o <=#Tp 32'h0;
wb_we_o <=#Tp 1'h0;
wb_dat_o <=#Tp 32'h0;
wb_AccessTck <=#Tp 1'h0;
end
else
if(UpdateDR & DEBUGSelected & CrcMatch)
begin
if(RegisterScanChain)
begin
ADDR[4:0] <=#Tp JTAG_DR_IN[4:0]; // Latching address for register access
RW <=#Tp JTAG_DR_IN[5]; // latch R/W bit
DataOut[31:0] <=#Tp JTAG_DR_IN[37:6]; // latch data for write
RegAccessTck <=#Tp 1'b1;
end
else
if(RiscDebugScanChain)
begin
ADDR[31:0] <=#Tp JTAG_DR_IN[31:0]; // Latching address for RISC register access
RW <=#Tp JTAG_DR_IN[32]; // latch R/W bit
DataOut[31:0] <=#Tp JTAG_DR_IN[64:33]; // latch data for write
RISCAccessTck <=#Tp 1'b1;
end
else
if(WishboneScanChain)
begin
wb_adr_o <=#Tp JTAG_DR_IN[31:0]; // Latching address for WISHBONE slave access
wb_we_o <=#Tp JTAG_DR_IN[32]; // latch R/W bit
wb_dat_o <=#Tp JTAG_DR_IN[64:33]; // latch data for write
wb_AccessTck <=#Tp 1'b1; //
end
end
else
begin
RegAccessTck <=#Tp 1'b0; // This signals are valid for one TCK clock period only
RISCAccessTck <=#Tp 1'b0;
wb_AccessTck <=#Tp 1'b0;
end
end
 
assign wb_sel_o[3:0] = 4'hf;
assign wb_cab_o = 1'b0;
 
 
// Synchronizing the RegAccess signal to risc_clk_i clock
dbg_sync_clk1_clk2 syn1 (.clk1(risc_clk_i), .clk2(TCK), .reset1(RESET), .reset2(RESET),
.set2(RegAccessTck), .sync_out(RegAccess)
);
 
// Synchronizing the RISCAccess signal to risc_clk_i clock
dbg_sync_clk1_clk2 syn2 (.clk1(risc_clk_i), .clk2(TCK), .reset1(RESET), .reset2(RESET),
.set2(RISCAccessTck), .sync_out(RISCAccess)
);
 
 
// Synchronizing the wb_Access signal to wishbone clock
dbg_sync_clk1_clk2 syn3 (.clk1(wb_clk_i), .clk2(TCK), .reset1(RESET), .reset2(RESET),
.set2(wb_AccessTck), .sync_out(wb_Access_wbClk)
);
 
 
 
 
 
// Delayed signals used for accessing registers and RISC
always @ (posedge risc_clk_i or posedge RESET)
begin
if(RESET)
begin
RegAccess_q <=#Tp 1'b0;
RegAccess_q2 <=#Tp 1'b0;
RISCAccess_q <=#Tp 1'b0;
RISCAccess_q2 <=#Tp 1'b0;
end
else
begin
RegAccess_q <=#Tp RegAccess;
RegAccess_q2 <=#Tp RegAccess_q;
RISCAccess_q <=#Tp RISCAccess;
RISCAccess_q2 <=#Tp RISCAccess_q;
end
end
 
 
// Latching data read from registers
always @ (posedge risc_clk_i or posedge RESET)
begin
if(RESET)
RegisterReadLatch[31:0]<=#Tp 0;
else
if(RegAccess_q & ~RegAccess_q2)
RegisterReadLatch[31:0]<=#Tp RegDataIn[31:0];
end
 
 
// Chip select and read/write signals for accessing RISC
assign RiscStall_write_access = RISCAccess & ~RISCAccess_q & RW;
assign RiscStall_read_access = RISCAccess & ~RISCAccess_q2 & ~RW;
assign RiscStall_access = RiscStall_write_access | RiscStall_read_access;
 
 
reg wb_Access_wbClk_q;
// Delayed signals used for accessing WISHBONE
always @ (posedge wb_clk_i or posedge RESET)
begin
if(RESET)
wb_Access_wbClk_q <=#Tp 1'b0;
else
wb_Access_wbClk_q <=#Tp wb_Access_wbClk;
end
 
always @ (posedge wb_clk_i or posedge RESET)
begin
if(RESET)
wb_cyc_o <=#Tp 1'b0;
else
if(wb_Access_wbClk & ~wb_Access_wbClk_q & ~(wb_ack_i | wb_err_i))
wb_cyc_o <=#Tp 1'b1;
else
if(wb_ack_i | wb_err_i)
wb_cyc_o <=#Tp 1'b0;
end
 
assign wb_stb_o = wb_cyc_o;
 
 
// Latching data read from registers
always @ (posedge risc_clk_i or posedge RESET)
begin
if(RESET)
WBReadLatch[31:0]<=#Tp 32'h0;
else
if(wb_ack_i)
WBReadLatch[31:0]<=#Tp wb_dat_i[31:0];
end
 
// Latching WISHBONE error cycle
always @ (posedge wb_clk_i or posedge RESET)
begin
if(RESET)
WBErrorLatch<=#Tp 1'b0;
else
if(wb_err_i)
WBErrorLatch<=#Tp 1'b1; // Latching wb_err_i while performing WISHBONE access
if(wb_ack_i)
WBErrorLatch<=#Tp 1'b0; // Clearing status
end
 
 
// Whan enabled, TRACE stalls RISC while saving data to the trace buffer.
`ifdef TRACE_ENABLED
assign risc_stall_o = RiscStall_access | RiscStall_reg | RiscStall_trace ;
`else
assign risc_stall_o = RiscStall_access | RiscStall_reg;
`endif
 
assign reset_o = RiscReset_reg;
 
 
`ifdef TRACE_ENABLED
always @ (RiscStall_write_access or RiscStall_read_access or opselect_trace)
`else
always @ (RiscStall_write_access or RiscStall_read_access)
`endif
begin
if(RiscStall_write_access)
opselect_o = `DEBUG_WRITE_SPR; // Write spr
else
if(RiscStall_read_access)
opselect_o = `DEBUG_READ_SPR; // Read spr
else
`ifdef TRACE_ENABLED
opselect_o = opselect_trace;
`else
opselect_o = 3'h0;
`endif
end
 
 
 
// Latching data read from RISC
always @ (posedge risc_clk_i or posedge RESET)
begin
if(RESET)
RISC_DATAINLatch[31:0]<=#Tp 0;
else
if(RISCAccess_q & ~RISCAccess_q2)
RISC_DATAINLatch[31:0]<=#Tp risc_data_i[31:0];
end
 
assign risc_addr_o = ADDR;
assign risc_data_o = DataOut;
 
 
 
/**********************************************************************************
* *
* Read Trace buffer logic *
* *
**********************************************************************************/
`ifdef TRACE_ENABLED
 
// Synchronizing the trace read buffer signal to risc_clk_i clock
dbg_sync_clk1_clk2 syn4 (.clk1(risc_clk_i), .clk2(TCK), .reset1(RESET), .reset2(RESET),
.set2(ReadBuffer_Tck), .sync_out(ReadTraceBuffer)
);
 
 
 
always @(posedge risc_clk_i or posedge RESET)
begin
if(RESET)
ReadTraceBuffer_q <=#Tp 0;
else
ReadTraceBuffer_q <=#Tp ReadTraceBuffer;
end
 
assign ReadTraceBufferPulse = ReadTraceBuffer & ~ReadTraceBuffer_q;
 
`endif
 
/**********************************************************************************
* *
* End: Read Trace buffer logic *
* *
**********************************************************************************/
 
 
/**********************************************************************************
* *
* Bypass logic *
* *
**********************************************************************************/
reg BypassRegister;
reg TDOBypassed;
 
always @ (posedge TCK)
begin
if(ShiftDR)
BypassRegister<=#Tp TDI;
end
 
always @ (negedge TCK)
begin
TDOBypassed<=#Tp BypassRegister;
end
/**********************************************************************************
* *
* End: Bypass logic *
* *
**********************************************************************************/
 
 
 
 
 
/**********************************************************************************
* *
* Activating Instructions *
* *
**********************************************************************************/
 
// Updating JTAG_IR (Instruction Register)
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
LatchedJTAG_IR <=#Tp `IDCODE; // IDCODE selected after reset
else
if(UpdateIR)
LatchedJTAG_IR <=#Tp JTAG_IR;
end
 
 
 
// Updating JTAG_IR (Instruction Register)
always @ (LatchedJTAG_IR)
begin
EXTESTSelected = 0;
SAMPLE_PRELOADSelected = 0;
IDCODESelected = 0;
CHAIN_SELECTSelected = 0;
INTESTSelected = 0;
CLAMPSelected = 0;
CLAMPZSelected = 0;
HIGHZSelected = 0;
DEBUGSelected = 0;
BYPASSSelected = 0;
 
case(LatchedJTAG_IR)
`EXTEST: EXTESTSelected = 1; // External test
`SAMPLE_PRELOAD: SAMPLE_PRELOADSelected = 1; // Sample preload
`IDCODE: IDCODESelected = 1; // ID Code
`CHAIN_SELECT: CHAIN_SELECTSelected = 1; // Chain select
`INTEST: INTESTSelected = 1; // Internal test
`CLAMP: CLAMPSelected = 1; // Clamp
`CLAMPZ: CLAMPZSelected = 1; // ClampZ
`HIGHZ: HIGHZSelected = 1; // High Z
`DEBUG: DEBUGSelected = 1; // Debug
`BYPASS: BYPASSSelected = 1; // BYPASS
default: BYPASSSelected = 1; // BYPASS
endcase
end
 
 
/**********************************************************************************
* *
* Multiplexing TDO and Tristate control *
* *
**********************************************************************************/
wire TDOShifted;
assign TDOShifted = (ShiftIR | Exit1IR)? TDOInstruction : TDOData;
/**********************************************************************************
* *
* End: Multiplexing TDO and Tristate control *
* *
**********************************************************************************/
 
 
 
// This multiplexer can be expanded with number of user registers
reg TDOMuxed;
always @ (JTAG_IR or TDOShifted or TDOBypassed or BS_CHAIN_I)
begin
case(JTAG_IR)
`IDCODE: // Reading ID code
begin
TDOMuxed<=#Tp TDOShifted;
end
`CHAIN_SELECT: // Selecting the chain
begin
TDOMuxed<=#Tp TDOShifted;
end
`DEBUG: // Debug
begin
TDOMuxed<=#Tp TDOShifted;
end
`SAMPLE_PRELOAD: // Sampling/Preloading
begin
TDOMuxed<=#Tp BS_CHAIN_I;
end
`EXTEST: // External test
begin
TDOMuxed<=#Tp BS_CHAIN_I;
end
default: // BYPASS instruction
begin
TDOMuxed<=#Tp TDOBypassed;
end
endcase
end
 
// Tristate control for tdo_pad_o pin
assign tdo_pad_o = (ShiftIR | ShiftDR | Exit1IR | Exit1DR | UpdateDR)? TDOMuxed : 1'bz;
 
/**********************************************************************************
* *
* End: Activating Instructions *
* *
**********************************************************************************/
 
/**********************************************************************************
* *
* Bit counter *
* *
**********************************************************************************/
 
 
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
BitCounter[7:0]<=#Tp 0;
else
if(ShiftDR)
BitCounter[7:0]<=#Tp BitCounter[7:0]+1;
else
if(UpdateDR)
BitCounter[7:0]<=#Tp 0;
end
 
 
 
/**********************************************************************************
* *
* End: Bit counter *
* *
**********************************************************************************/
 
 
 
/**********************************************************************************
* *
* Connecting Registers *
* *
**********************************************************************************/
dbg_registers dbgregs(.DataIn(DataOut[31:0]), .DataOut(RegDataIn[31:0]),
.Address(ADDR[4:0]), .RW(RW), .Access(RegAccess & ~RegAccess_q), .Clk(risc_clk_i),
.Bp(bp_i), .Reset(wb_rst_i),
`ifdef TRACE_ENABLED
.ContinMode(ContinMode), .TraceEnable(TraceEnable),
.WpTrigger(WpTrigger), .BpTrigger(BpTrigger), .LSSTrigger(LSSTrigger),
.ITrigger(ITrigger), .TriggerOper(TriggerOper), .WpQualif(WpQualif),
.BpQualif(BpQualif), .LSSQualif(LSSQualif), .IQualif(IQualif),
.QualifOper(QualifOper), .RecordPC(RecordPC),
.RecordLSEA(RecordLSEA), .RecordLDATA(RecordLDATA),
.RecordSDATA(RecordSDATA), .RecordReadSPR(RecordReadSPR),
.RecordWriteSPR(RecordWriteSPR), .RecordINSTR(RecordINSTR),
.WpTriggerValid(WpTriggerValid),
.BpTriggerValid(BpTriggerValid), .LSSTriggerValid(LSSTriggerValid),
.ITriggerValid(ITriggerValid), .WpQualifValid(WpQualifValid),
.BpQualifValid(BpQualifValid), .LSSQualifValid(LSSQualifValid),
.IQualifValid(IQualifValid),
.WpStop(WpStop), .BpStop(BpStop), .LSSStop(LSSStop), .IStop(IStop),
.StopOper(StopOper), .WpStopValid(WpStopValid), .BpStopValid(BpStopValid),
.LSSStopValid(LSSStopValid), .IStopValid(IStopValid),
`endif
.RiscStall(RiscStall_reg), .RiscReset(RiscReset_reg)
 
);
 
/**********************************************************************************
* *
* End: Connecting Registers *
* *
**********************************************************************************/
 
 
/**********************************************************************************
* *
* Connecting CRC module *
* *
**********************************************************************************/
wire AsyncResetCrc = RESET;
wire SyncResetCrc = UpdateDR_q;
wire [7:0] CalculatedCrcIn; // crc calculated from the input data (shifted in)
 
wire EnableCrcIn = ShiftDR &
( (CHAIN_SELECTSelected & (BitCounter<4)) |
((DEBUGSelected & RegisterScanChain) & (BitCounter<38)) |
((DEBUGSelected & RiscDebugScanChain) & (BitCounter<65)) |
((DEBUGSelected & WishboneScanChain) & (BitCounter<65))
);
 
wire EnableCrcOut= ShiftDR &
(
((DEBUGSelected & RegisterScanChain) & (BitCounter<38)) |
((DEBUGSelected & RiscDebugScanChain) & (BitCounter<65)) |
((DEBUGSelected & WishboneScanChain) & (BitCounter<65))
`ifdef TRACE_ENABLED
|
((DEBUGSelected & TraceTestScanChain) & (BitCounter<40))
`endif
);
 
// Calculating crc for input data
dbg_crc8_d1 crc1 (.Data(TDI), .EnableCrc(EnableCrcIn), .Reset(AsyncResetCrc), .SyncResetCrc(SyncResetCrc),
.CrcOut(CalculatedCrcIn), .Clk(TCK));
 
// Calculating crc for output data
dbg_crc8_d1 crc2 (.Data(TDOData), .EnableCrc(EnableCrcOut), .Reset(AsyncResetCrc), .SyncResetCrc(SyncResetCrc),
.CrcOut(CalculatedCrcOut), .Clk(TCK));
 
 
// Generating CrcMatch signal
always @ (posedge TCK or posedge RESET)
begin
if(RESET)
CrcMatch <=#Tp 1'b0;
else
if(Exit1DR)
begin
if(CHAIN_SELECTSelected)
CrcMatch <=#Tp CalculatedCrcIn == JTAG_DR_IN[11:4];
else
if(RegisterScanChain & ~CHAIN_SELECTSelected)
CrcMatch <=#Tp CalculatedCrcIn == JTAG_DR_IN[45:38];
else
if(RiscDebugScanChain & ~CHAIN_SELECTSelected)
CrcMatch <=#Tp CalculatedCrcIn == JTAG_DR_IN[72:65];
else
if(WishboneScanChain & ~CHAIN_SELECTSelected)
CrcMatch <=#Tp CalculatedCrcIn == JTAG_DR_IN[72:65];
end
end
 
 
// Active chain
assign RegisterScanChain = Chain == `REGISTER_SCAN_CHAIN;
assign RiscDebugScanChain = Chain == `RISC_DEBUG_CHAIN;
assign WishboneScanChain = Chain == `WISHBONE_SCAN_CHAIN;
 
`ifdef TRACE_ENABLED
assign TraceTestScanChain = Chain == `TRACE_TEST_CHAIN;
`endif
 
/**********************************************************************************
* *
* End: Connecting CRC module *
* *
**********************************************************************************/
 
/**********************************************************************************
* *
* Connecting trace module *
* *
**********************************************************************************/
`ifdef TRACE_ENABLED
dbg_trace dbgTrace1(.Wp(wp_i), .Bp(bp_i), .DataIn(risc_data_i), .OpSelect(opselect_trace),
.LsStatus(lsstatus_i), .IStatus(istatus_i), .RiscStall_O(RiscStall_trace),
.Mclk(risc_clk_i), .Reset(RESET), .TraceChain(TraceChain),
.ContinMode(ContinMode), .TraceEnable_reg(TraceEnable),
.WpTrigger(WpTrigger),
.BpTrigger(BpTrigger), .LSSTrigger(LSSTrigger), .ITrigger(ITrigger),
.TriggerOper(TriggerOper), .WpQualif(WpQualif), .BpQualif(BpQualif),
.LSSQualif(LSSQualif), .IQualif(IQualif), .QualifOper(QualifOper),
.RecordPC(RecordPC), .RecordLSEA(RecordLSEA),
.RecordLDATA(RecordLDATA), .RecordSDATA(RecordSDATA),
.RecordReadSPR(RecordReadSPR), .RecordWriteSPR(RecordWriteSPR),
.RecordINSTR(RecordINSTR),
.WpTriggerValid(WpTriggerValid), .BpTriggerValid(BpTriggerValid),
.LSSTriggerValid(LSSTriggerValid), .ITriggerValid(ITriggerValid),
.WpQualifValid(WpQualifValid), .BpQualifValid(BpQualifValid),
.LSSQualifValid(LSSQualifValid), .IQualifValid(IQualifValid),
.ReadBuffer(ReadTraceBufferPulse),
.WpStop(WpStop), .BpStop(BpStop), .LSSStop(LSSStop), .IStop(IStop),
.StopOper(StopOper), .WpStopValid(WpStopValid), .BpStopValid(BpStopValid),
.LSSStopValid(LSSStopValid), .IStopValid(IStopValid)
);
`endif
/**********************************************************************************
* *
* End: Connecting trace module *
* *
**********************************************************************************/
 
 
 
endmodule
/verilog/dbg_interface/dbg_crc8_d1.v
0,0 → 1,150
//////////////////////////////////////////////////////////////////////
//// ////
//// dbg_crc8_d1 crc1.v ////
//// ////
//// ////
//// This file is part of the SoC/OpenRISC Development Interface ////
//// http://www.opencores.org/cores/DebugInterface/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@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 $
// Revision 1.1.1.1 2001/10/06 10:19:09 igorm
// no message
//
// Revision 1.2 2001/09/20 10:11:25 mohor
// Working version. Few bugs fixed, comments added.
//
// Revision 1.1.1.1 2001/09/13 13:49:19 mohor
// Initial official release.
//
// Revision 1.3 2001/06/01 22:22:36 mohor
// This is a backup. It is not a fully working version. Not for use, yet.
//
// Revision 1.2 2001/05/18 13:10:00 mohor
// Headers changed. All additional information is now avaliable in the README.txt file.
//
// Revision 1.1.1.1 2001/05/18 06:35:03 mohor
// Initial release
//
//
///////////////////////////////////////////////////////////////////////
// File: CRC8_D1.v
// Date: Fri Apr 27 20:56:55 2001
//
// Copyright (C) 1999 Easics NV.
// 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 PROVIDED "AS IS" AND WITHOUT ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// Purpose: Verilog module containing a synthesizable CRC function
// * polynomial: (0 1 2 8)
// * data width: 1
//
// Info: jand@easics.be (Jan Decaluwe)
// http://www.easics.com
///////////////////////////////////////////////////////////////////////
 
`include "dbg_timescale.v"
`include "dbg_defines.v"
 
 
module dbg_crc8_d1 (Data, EnableCrc, Reset, SyncResetCrc, CrcOut, Clk);
 
parameter Tp = 1;
 
 
input Data;
input EnableCrc;
input Reset;
input SyncResetCrc;
input Clk;
 
 
output [7:0] CrcOut;
reg [7:0] CrcOut;
 
 
always @ (posedge Clk or posedge Reset)
begin
if(Reset)
CrcOut[7:0] <= #Tp 0;
else
if(SyncResetCrc)
CrcOut[7:0] <= #Tp 0;
else
if(EnableCrc)
CrcOut[7:0] <= #Tp nextCRC8_D1(Data, CrcOut);
end
 
 
// polynomial: (0 1 2 8)
// data width: 1
function [7:0] nextCRC8_D1;
 
input Data;
input [7:0] Crc;
reg [0:0] D;
reg [7:0] C;
reg [7:0] NewCRC;
begin
D[0] = Data;
C = Crc;
NewCRC[0] = D[0] ^ C[7];
NewCRC[1] = D[0] ^ C[0] ^ C[7];
NewCRC[2] = D[0] ^ C[1] ^ C[7];
NewCRC[3] = C[2];
NewCRC[4] = C[3];
NewCRC[5] = C[4];
NewCRC[6] = C[5];
NewCRC[7] = C[6];
nextCRC8_D1 = NewCRC;
end
endfunction
 
endmodule
/verilog/dbg_interface/dbg_register.v
0,0 → 1,89
//////////////////////////////////////////////////////////////////////
//// ////
//// dbg_register.v ////
//// ////
//// ////
//// This file is part of the SoC/OpenRISC Development Interface ////
//// http://www.opencores.org/cores/DebugInterface/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@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 $
// Revision 1.1.1.1 2001/10/06 10:19:09 igorm
// no message
//
// Revision 1.1.1.1 2001/09/13 13:49:19 mohor
// Initial official release.
//
//
//
//
//
 
`include "dbg_timescale.v"
 
module dbg_register(DataIn, DataOut, Write, Clk, Reset, Default);
 
parameter WIDTH = 8; // default parameter of the register width
 
input [WIDTH-1:0] DataIn;
 
input Write;
input Clk;
input Reset;
input [WIDTH-1:0] Default;
 
output [WIDTH-1:0] DataOut;
reg [WIDTH-1:0] DataOut;
 
//always @ (posedge Clk or posedge Reset)
always @ (posedge Clk)
begin
if(Reset)
DataOut[WIDTH-1:0]<=#1 Default;
else
begin
if(Write) // write
DataOut[WIDTH-1:0]<=#1 DataIn[WIDTH-1:0];
end
end
 
 
endmodule // Register
 
/verilog/dbg_interface/dbg_timescale.v
0,0 → 1,25
//////////////////////////////////////////////////////////////////////
//// ////
//// Flextronics Semiconductor ////
//// ////
//// CONFIDENTIAL ////
//// ////
//// File name : timescale.v ////
//// ////
//// Author(s): ////
//// - Yair Amitay ////
//// ////
//// Created: 22.7.01 ////
//// Last Updated: 22.7.01 ////
//// ////
//// Overview (main Features): ////
//// ////
//// ////
//// Known problems (limits): ////
//// None ////
//// ////
//// To Do: ////
//// ////
//////////////////////////////////////////////////////////////////////
 
`timescale 1ns/10ps
/verilog/dbg_interface/dbg_registers.v
0,0 → 1,287
//////////////////////////////////////////////////////////////////////
//// ////
//// dbg_registers.v ////
//// ////
//// ////
//// This file is part of the SoC/OpenRISC Development Interface ////
//// http://www.opencores.org/cores/DebugInterface/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@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 $
// Revision 1.2 2001/09/18 14:13:47 mohor
// Trace fixed. Some registers changed, trace simplified.
//
// Revision 1.1.1.1 2001/09/13 13:49:19 mohor
// Initial official release.
//
// Revision 1.3 2001/06/01 22:22:35 mohor
// This is a backup. It is not a fully working version. Not for use, yet.
//
// Revision 1.2 2001/05/18 13:10:00 mohor
// Headers changed. All additional information is now avaliable in the README.txt file.
//
// Revision 1.1.1.1 2001/05/18 06:35:10 mohor
// Initial release
//
//
 
`include "dbg_timescale.v"
`include "dbg_defines.v"
 
module dbg_registers(DataIn, DataOut, Address, RW, Access, Clk, Bp, Reset,
`ifdef TRACE_ENABLED
ContinMode,
TraceEnable, WpTrigger, BpTrigger, LSSTrigger,
ITrigger, TriggerOper, WpQualif, BpQualif, LSSQualif, IQualif,
QualifOper, RecordPC, RecordLSEA, RecordLDATA,
RecordSDATA, RecordReadSPR, RecordWriteSPR, RecordINSTR,
WpTriggerValid, BpTriggerValid, LSSTriggerValid, ITriggerValid,
WpQualifValid, BpQualifValid, LSSQualifValid, IQualifValid,
WpStop, BpStop, LSSStop, IStop, StopOper, WpStopValid, BpStopValid,
LSSStopValid, IStopValid,
`endif
RiscStall, RiscReset
);
 
parameter Tp = 1;
 
input [31:0] DataIn;
input [4:0] Address;
 
input RW;
input Access;
input Clk;
input Bp;
input Reset;
 
output [31:0] DataOut;
reg [31:0] DataOut;
 
`ifdef TRACE_ENABLED
output ContinMode;
output TraceEnable;
output [10:0] WpTrigger;
output BpTrigger;
output [3:0] LSSTrigger;
output [1:0] ITrigger;
output [1:0] TriggerOper;
output WpTriggerValid;
output BpTriggerValid;
output LSSTriggerValid;
output ITriggerValid;
output [10:0] WpQualif;
output BpQualif;
output [3:0] LSSQualif;
output [1:0] IQualif;
output [1:0] QualifOper;
output WpQualifValid;
output BpQualifValid;
output LSSQualifValid;
output IQualifValid;
output [10:0] WpStop;
output BpStop;
output [3:0] LSSStop;
output [1:0] IStop;
output [1:0] StopOper;
output WpStopValid;
output BpStopValid;
output LSSStopValid;
output IStopValid;
output RecordPC;
output RecordLSEA;
output RecordLDATA;
output RecordSDATA;
output RecordReadSPR;
output RecordWriteSPR;
output RecordINSTR;
`endif
 
output RiscStall;
output RiscReset;
 
wire MODER_Acc = (Address == `MODER_ADR) & Access;
wire RISCOP_Acc = (Address == `RISCOP_ADR) & Access;
`ifdef TRACE_ENABLED
wire TSEL_Acc = (Address == `TSEL_ADR) & Access;
wire QSEL_Acc = (Address == `QSEL_ADR) & Access;
wire SSEL_Acc = (Address == `SSEL_ADR) & Access;
wire RECSEL_Acc = (Address == `RECSEL_ADR) & Access;
`endif
 
wire MODER_Wr = MODER_Acc & RW;
wire RISCOP_Wr = RISCOP_Acc & RW;
`ifdef TRACE_ENABLED
wire TSEL_Wr = TSEL_Acc & RW;
wire QSEL_Wr = QSEL_Acc & RW;
wire SSEL_Wr = SSEL_Acc & RW;
wire RECSEL_Wr = RECSEL_Acc & RW;
`endif
 
 
wire MODER_Rd = MODER_Acc & ~RW;
wire RISCOP_Rd = RISCOP_Acc & ~RW;
`ifdef TRACE_ENABLED
wire TSEL_Rd = TSEL_Acc & ~RW;
wire QSEL_Rd = QSEL_Acc & ~RW;
wire SSEL_Rd = SSEL_Acc & ~RW;
wire RECSEL_Rd = RECSEL_Acc & ~RW;
`endif
 
 
wire [31:0] MODEROut;
wire [1:1] RISCOPOut;
 
`ifdef TRACE_ENABLED
wire [31:0] TSELOut;
wire [31:0] QSELOut;
wire [31:0] SSELOut;
wire [6:0] RECSELOut;
`endif
 
 
`ifdef TRACE_ENABLED
assign MODEROut[15:0] = 16'h0001;
assign MODEROut[31:18] = 14'h0;
`else
assign MODEROut[31:0] = 32'h0000;
`endif
 
 
reg RiscStallBp;
always @(posedge Clk or posedge Reset)
begin
if(Reset)
RiscStallBp <= 1'b0;
else
if(Bp) // Breakpoint sets bit
RiscStallBp <= 1'b1;
else
if(RISCOP_Wr) // Register access can set or clear bit
RiscStallBp <= DataIn[0];
end
 
dbg_register #(1) RISCOP (.DataIn(DataIn[1]), .DataOut(RISCOPOut[1]), .Write(RISCOP_Wr), .Clk(Clk), .Reset(Reset), .Default(1'b0));
 
 
`ifdef TRACE_ENABLED
dbg_register #(2) MODER (.DataIn(DataIn[17:16]), .DataOut(MODEROut[17:16]), .Write(MODER_Wr), .Clk(Clk), .Reset(Reset), .Default(`MODER_DEF));
dbg_register #(32) TSEL (.DataIn(DataIn), .DataOut(TSELOut), .Write(TSEL_Wr), .Clk(Clk), .Reset(Reset), .Default(`TSEL_DEF));
dbg_register #(32) QSEL (.DataIn(DataIn), .DataOut(QSELOut), .Write(QSEL_Wr), .Clk(Clk), .Reset(Reset), .Default(`QSEL_DEF));
dbg_register #(32) SSEL (.DataIn(DataIn), .DataOut(SSELOut), .Write(SSEL_Wr), .Clk(Clk), .Reset(Reset), .Default(`SSEL_DEF));
dbg_register #(7) RECSEL (.DataIn(DataIn[6:0]), .DataOut(RECSELOut), .Write(RECSEL_Wr), .Clk(Clk), .Reset(Reset), .Default(`RECSEL_DEF));
`endif
 
 
 
always @ (posedge Clk)
begin
if(MODER_Rd) DataOut<= #Tp MODEROut;
else
if(RISCOP_Rd) DataOut<= #Tp {30'h0, RISCOPOut[1], RiscStall};
`ifdef TRACE_ENABLED
else
if(TSEL_Rd) DataOut<= #Tp TSELOut;
else
if(QSEL_Rd) DataOut<= #Tp QSELOut;
else
if(SSEL_Rd) DataOut<= #Tp SSELOut;
else
if(RECSEL_Rd) DataOut<= #Tp {25'h0, RECSELOut};
`endif
else DataOut<= #Tp 'h0;
end
 
`ifdef TRACE_ENABLED
assign TraceEnable = MODEROut[16];
assign ContinMode = MODEROut[17];
assign WpTrigger[10:0] = TSELOut[10:0];
assign WpTriggerValid = TSELOut[11];
assign BpTrigger = TSELOut[12];
assign BpTriggerValid = TSELOut[13];
assign LSSTrigger[3:0] = TSELOut[19:16];
assign LSSTriggerValid = TSELOut[20];
assign ITrigger[1:0] = TSELOut[22:21];
assign ITriggerValid = TSELOut[23];
assign TriggerOper[1:0] = TSELOut[31:30];
assign WpQualif[10:0] = QSELOut[10:0];
assign WpQualifValid = QSELOut[11];
assign BpQualif = QSELOut[12];
assign BpQualifValid = QSELOut[13];
assign LSSQualif[3:0] = QSELOut[19:16];
assign LSSQualifValid = QSELOut[20];
assign IQualif[1:0] = QSELOut[22:21];
assign IQualifValid = QSELOut[23];
assign QualifOper[1:0] = QSELOut[31:30];
assign WpStop[10:0] = SSELOut[10:0];
assign WpStopValid = SSELOut[11];
assign BpStop = SSELOut[12];
assign BpStopValid = SSELOut[13];
assign LSSStop[3:0] = SSELOut[19:16];
assign LSSStopValid = SSELOut[20];
assign IStop[1:0] = SSELOut[22:21];
assign IStopValid = SSELOut[23];
assign StopOper[1:0] = SSELOut[31:30];
assign RecordPC = RECSELOut[0];
assign RecordLSEA = RECSELOut[1];
assign RecordLDATA = RECSELOut[2];
assign RecordSDATA = RECSELOut[3];
assign RecordReadSPR = RECSELOut[4];
assign RecordWriteSPR = RECSELOut[5];
assign RecordINSTR = RECSELOut[6];
`endif
 
assign RiscStall = Bp | RiscStallBp; // Bp asynchronously sets the RiscStall, then RiscStallBp (from register) holds it active
assign RiscReset = RISCOPOut[1];
 
endmodule
/verilog/dbg_interface/timescale.v
0,0 → 1,25
//////////////////////////////////////////////////////////////////////
//// ////
//// Flextronics Semiconductor ////
//// ////
//// CONFIDENTIAL ////
//// ////
//// File name : timescale.v ////
//// ////
//// Author(s): ////
//// - Yair Amitay ////
//// ////
//// Created: 22.7.01 ////
//// Last Updated: 22.7.01 ////
//// ////
//// Overview (main Features): ////
//// ////
//// ////
//// Known problems (limits): ////
//// None ////
//// ////
//// To Do: ////
//// ////
//////////////////////////////////////////////////////////////////////
 
`timescale 1ns/10ps
/verilog/dbg_interface/dbg_defines.v
0,0 → 1,151
//////////////////////////////////////////////////////////////////////
//// ////
//// dbg_defines.v ////
//// ////
//// ////
//// This file is part of the SoC/OpenRISC Development Interface ////
//// http://www.opencores.org/cores/DebugInterface/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@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 $
// Revision 1.4 2001/09/24 14:06:42 mohor
// Changes connected to the OpenRISC access (SPR read, SPR write).
//
// Revision 1.3 2001/09/20 10:11:25 mohor
// Working version. Few bugs fixed, comments added.
//
// Revision 1.2 2001/09/18 14:13:47 mohor
// Trace fixed. Some registers changed, trace simplified.
//
// Revision 1.1.1.1 2001/09/13 13:49:19 mohor
// Initial official release.
//
// Revision 1.3 2001/06/01 22:22:35 mohor
// This is a backup. It is not a fully working version. Not for use, yet.
//
// Revision 1.2 2001/05/18 13:10:00 mohor
// Headers changed. All additional information is now avaliable in the README.txt file.
//
// Revision 1.1.1.1 2001/05/18 06:35:08 mohor
// Initial release
//
//
 
 
 
// Enable TRACE
`define TRACE_ENABLED // Uncomment this define to activate the trace
 
 
// Define IDCODE Value
`define IDCODE_VALUE 32'hdeadbeef
 
// Define master clock (RISC clock)
//`define RISC_CLOCK 50 // Half period = 50 ns => MCLK = 10 Mhz
`define RISC_CLOCK 2.5 // Half period = 5 ns => MCLK = 200 Mhz
 
// Length of the Instruction register
`define IR_LENGTH 4
 
// Length of the Data register (must be equal to the longest scan chain)
`define DR_LENGTH 73
 
// Length of the CHAIN ID register
`define CHAIN_ID_LENGTH 4
 
// Length of the CRC
`define CRC_LENGTH 8
 
// Trace buffer size and counter and write/read pointer width. This can be expanded when more RAM is avaliable
`define TRACECOUNTERWIDTH 5
`define TRACEBUFFERLENGTH 32 // 2^5
 
`define TRACESAMPLEWIDTH 36
 
// OpSelect width
`define OPSELECTWIDTH 3
`define OPSELECTIONCOUNTER 8 //2^3
 
// OpSelect (dbg_op_i) signal meaning
`define DEBUG_READ_PC 0
`define DEBUG_READ_LSEA 1
`define DEBUG_READ_LDATA 2
`define DEBUG_READ_SDATA 3
`define DEBUG_READ_SPR 4
`define DEBUG_WRITE_SPR 5
`define DEBUG_READ_INSTR 6
//`define Reserved 7
 
// Supported Instructions
`define EXTEST 5'b00000
`define SAMPLE_PRELOAD 5'b00001
`define IDCODE 5'b00010
`define CHAIN_SELECT 5'b00011
`define INTEST 5'b00100
`define CLAMP 5'b00101
`define CLAMPZ 5'b00110
`define HIGHZ 5'b00111
`define DEBUG 5'b01000
`define BYPASS 5'b01111
 
// Chains
`define GLOBAL_BS_CHAIN 4'b0000
`define RISC_DEBUG_CHAIN 4'b0001
`define RISC_TEST_CHAIN 4'b0010
`define TRACE_TEST_CHAIN 4'b0011
`define REGISTER_SCAN_CHAIN 4'b0100
`define WISHBONE_SCAN_CHAIN 4'b0101
 
// Registers addresses
`define MODER_ADR 5'h00
`define TSEL_ADR 5'h01
`define QSEL_ADR 5'h02
`define SSEL_ADR 5'h03
`define RISCOP_ADR 5'h04
`define RECSEL_ADR 5'h10
 
 
// Registers default values (after reset)
`define MODER_DEF 2'h0
`define TSEL_DEF 32'h00000000
`define QSEL_DEF 32'h00000000
`define SSEL_DEF 32'h00000000
`define RISCOP_DEF 2'h0
`define RECSEL_DEF 7'h0
/verilog/dbg_interface/dbg_trace.v
0,0 → 1,467
//////////////////////////////////////////////////////////////////////
//// ////
//// dbg_trace.v ////
//// ////
//// ////
//// This file is part of the SoC/OpenRISC Development Interface ////
//// http://www.opencores.org/cores/DebugInterface/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@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 $
// Revision 1.1.1.1 2001/10/06 10:19:09 igorm
// no message
//
// Revision 1.4 2001/09/20 10:11:25 mohor
// Working version. Few bugs fixed, comments added.
//
// Revision 1.3 2001/09/19 11:55:13 mohor
// Asynchronous set/reset not used in trace any more.
//
// Revision 1.2 2001/09/18 14:13:47 mohor
// Trace fixed. Some registers changed, trace simplified.
//
// Revision 1.1.1.1 2001/09/13 13:49:19 mohor
// Initial official release.
//
// Revision 1.3 2001/06/01 22:22:35 mohor
// This is a backup. It is not a fully working version. Not for use, yet.
//
// Revision 1.2 2001/05/18 13:10:00 mohor
// Headers changed. All additional information is now avaliable in the README.txt file.
//
// Revision 1.1.1.1 2001/05/18 06:35:06 mohor
// Initial release
//
//
 
 
`include "dbg_timescale.v"
`include "dbg_defines.v"
 
// module Trace
module dbg_trace (Wp, Bp, DataIn, OpSelect, LsStatus, IStatus, RiscStall_O,
Mclk, Reset, TraceChain, ContinMode, TraceEnable_reg,
WpTrigger, BpTrigger, LSSTrigger, ITrigger, TriggerOper, WpQualif,
BpQualif, LSSQualif, IQualif, QualifOper, RecordPC, RecordLSEA,
RecordLDATA, RecordSDATA, RecordReadSPR, RecordWriteSPR,
RecordINSTR,
WpTriggerValid, BpTriggerValid, LSSTriggerValid, ITriggerValid,
WpQualifValid, BpQualifValid, LSSQualifValid, IQualifValid, ReadBuffer,
WpStop, BpStop, LSSStop, IStop, StopOper, WpStopValid, BpStopValid,
LSSStopValid, IStopValid
);
 
parameter Tp = 1;
 
 
input [10:0] Wp; // Watchpoints
input Bp; // Breakpoint
input [31:0] DataIn; // Data from the RISC
input [3:0] LsStatus; // Load/Store status
input [1:0] IStatus; // Instruction status
 
input Mclk; // Master clock (RISC clock)
input Reset; // Reset
input ReadBuffer; // Instruction for reading a sample from the Buffer
 
// from registers
input ContinMode; // Continous mode of the trace
input TraceEnable_reg; // Trace is enabled (enabled by writing a bit in the register)
 
input [10:0] WpTrigger; // Signals that come from registers to set the trigger
input BpTrigger; // Signals that come from registers to set the trigger
input [3:0] LSSTrigger; // Signals that come from registers to set the trigger
input [1:0] ITrigger; // Signals that come from registers to set the trigger
input [1:0] TriggerOper; // Signals that come from registers to set the trigger
 
input [10:0] WpQualif; // Signals that come from registers to set the qualifier
input BpQualif; // Signals that come from registers to set the qualifier
input [3:0] LSSQualif; // Signals that come from registers to set the qualifier
input [1:0] IQualif; // Signals that come from registers to set the qualifier
input [1:0] QualifOper; // Signals that come from registers to set the qualifier
 
input [10:0] WpStop; // Signals that come from registers to set the stop condition
input BpStop; // Signals that come from registers to set the stop condition
input [3:0] LSSStop; // Signals that come from registers to set the stop condition
input [1:0] IStop; // Signals that come from registers to set the stop condition
input [1:0] StopOper; // Signals that come from registers to set the stop condition
 
input RecordPC; // Signals that come from registers for defining the sample for recording
input RecordLSEA; // Signals that come from registers for defining the sample for recording
input RecordLDATA; // Signals that come from registers for defining the sample for recording
input RecordSDATA; // Signals that come from registers for defining the sample for recording
input RecordReadSPR; // Signals that come from registers for defining the sample for recording
input RecordWriteSPR; // Signals that come from registers for defining the sample for recording
input RecordINSTR; // Signals that come from registers for defining the sample for recording
 
input WpTriggerValid; // Signals that come from registers and indicate which trigger conditions are valid
input BpTriggerValid; // Signals that come from registers and indicate which trigger conditions are valid
input LSSTriggerValid; // Signals that come from registers and indicate which trigger conditions are valid
input ITriggerValid; // Signals that come from registers and indicate which trigger conditions are valid
 
input WpQualifValid; // Signals that come from registers and indicate which qualifier conditions are valid
input BpQualifValid; // Signals that come from registers and indicate which qualifier conditions are valid
input LSSQualifValid; // Signals that come from registers and indicate which qualifier conditions are valid
input IQualifValid; // Signals that come from registers and indicate which qualifier conditions are valid
 
input WpStopValid; // Signals that come from registers and indicate which stop conditions are valid
input BpStopValid; // Signals that come from registers and indicate which stop conditions are valid
input LSSStopValid; // Signals that come from registers and indicate which stop conditions are valid
input IStopValid; // Signals that come from registers and indicate which stop conditions are valid
// end: from registers
 
 
output [`OPSELECTWIDTH-1:0] OpSelect; // Operation select (what kind of information is avaliable on the DataIn)
output RiscStall_O; // CPU stall (stalls the RISC)
output [39:0] TraceChain; // Scan shain from the trace module
 
reg TraceEnable_d;
reg TraceEnable;
 
 
 
reg [`TRACECOUNTERWIDTH:0] Counter;
reg [`TRACECOUNTERWIDTH-1:0] WritePointer;
reg [`TRACECOUNTERWIDTH-1:0] ReadPointer;
reg RiscStall;
reg RiscStall_q;
reg [`OPSELECTWIDTH-1:0] StallCounter;
 
reg [`TRACESAMPLEWIDTH-1:0] Buffer[0:`TRACEBUFFERLENGTH-1];
 
reg TriggerLatch;
 
 
/**********************************************************************************
* *
* Generation of the trigger *
* *
**********************************************************************************/
wire TempWpTrigger = |(Wp[10:0] & WpTrigger[10:0]);
wire TempBpTrigger = Bp & BpTrigger;
wire TempLSSTrigger = LsStatus[3:0] == LSSTrigger[3:0];
wire TempITrigger = IStatus[1:0] == ITrigger[1:0];
 
wire TempTriggerAND = ( (TempWpTrigger | ~WpTriggerValid)
& (TempBpTrigger | ~BpTriggerValid)
& (TempLSSTrigger | ~LSSTriggerValid)
& (TempITrigger | ~ITriggerValid)
)
& (WpTriggerValid | BpTriggerValid | LSSTriggerValid | ITriggerValid);
 
wire TempTriggerOR = ( (TempWpTrigger & WpTriggerValid)
| (TempBpTrigger & BpTriggerValid)
| (TempLSSTrigger & LSSTriggerValid)
| (TempITrigger & ITriggerValid)
);
 
wire Trigger = TraceEnable & (~TriggerOper[1]? 1 : // any
TriggerOper[0]? TempTriggerAND : TempTriggerOR // AND : OR
);
 
/**********************************************************************************
* *
* Generation of the qualifier *
* *
**********************************************************************************/
wire TempWpQualifier = |(Wp[10:0] & WpQualif[10:0]);
wire TempBpQualifier = Bp & BpQualif;
wire TempLSSQualifier = LsStatus[3:0] == LSSQualif[3:0];
wire TempIQualifier = IStatus[1:0] == IQualif[1:0];
 
wire TempQualifierAND = ( (TempWpQualifier | ~WpQualifValid)
& (TempBpQualifier | ~BpQualifValid)
& (TempLSSQualifier | ~LSSQualifValid)
& (TempIQualifier | ~IQualifValid)
)
& (WpQualifValid | BpQualifValid | LSSQualifValid | IQualifValid);
 
wire TempQualifierOR = ( (TempWpQualifier & WpQualifValid)
| (TempBpQualifier & BpQualifValid)
| (TempLSSQualifier & LSSQualifValid)
| (TempIQualifier & IQualifValid)
);
 
 
wire Stop;
wire Qualifier = TraceEnable & ~Stop & (~QualifOper[1]? 1 : // any
QualifOper[0]? TempQualifierAND : TempQualifierOR // AND : OR
);
 
/**********************************************************************************
* *
* Generation of the stop signal *
* *
**********************************************************************************/
wire TempWpStop = |(Wp[10:0] & WpStop[10:0]);
wire TempBpStop = Bp & BpStop;
wire TempLSSStop = LsStatus[3:0] == LSSStop[3:0];
wire TempIStop = IStatus[1:0] == IStop[1:0];
 
wire TempStopAND = ( (TempWpStop | ~WpStopValid)
& (TempBpStop | ~BpStopValid)
& (TempLSSStop | ~LSSStopValid)
& (TempIStop | ~IStopValid)
)
& (WpStopValid | BpStopValid | LSSStopValid | IStopValid);
 
wire TempStopOR = ( (TempWpStop & WpStopValid)
| (TempBpStop & BpStopValid)
| (TempLSSStop & LSSStopValid)
| (TempIStop & IStopValid)
);
 
 
assign Stop = TraceEnable & (~StopOper[1]? 0 : // nothing
StopOper[0]? TempStopAND : TempStopOR // AND : OR
);
 
 
 
/**********************************************************************************
* *
* Generation of the TriggerLatch *
* *
**********************************************************************************/
always @(posedge Mclk or posedge Reset)
begin
if(Reset)
TriggerLatch<=#Tp 0;
else
if(TriggerLatch & ~TraceEnable)
TriggerLatch<=#Tp 0;
else
if(Trigger)
TriggerLatch<=#Tp 1;
end
 
 
 
 
/**********************************************************************************
* *
* TraceEnable Synchronization *
* *
**********************************************************************************/
always @(posedge Mclk or posedge Reset)
begin
if(Reset)
begin
TraceEnable_d<=#Tp 0;
TraceEnable<=#Tp 0;
end
else
begin
TraceEnable_d<=#Tp TraceEnable_reg;
TraceEnable<=#Tp TraceEnable_d;
end
end
 
 
 
 
/**********************************************************************************
* *
* RiscStall, counter and pointers generation *
* *
**********************************************************************************/
reg BufferFullDetected;
wire [`OPSELECTIONCOUNTER-1:0] RecEnable;
 
wire BufferFull = Counter[`TRACECOUNTERWIDTH:0]==`TRACEBUFFERLENGTH;
wire BufferEmpty = Counter[`TRACECOUNTERWIDTH:0]==0;
wire IncrementCounter = RiscStall_q & ~(BufferFull | BufferFullDetected) & Qualifier & RecEnable[StallCounter];
wire IncrementPointer = RiscStall_q & (~BufferFull | ContinMode) & Qualifier & RecEnable[StallCounter];
 
wire WriteSample = IncrementPointer;
 
wire Decrement = ReadBuffer & ~BufferEmpty & (~ContinMode | ContinMode & ~TraceEnable);
wire CounterEn = IncrementCounter ^ Decrement;
 
wire SyncResetCpuStall;
wire ResetStallCounter;
reg BufferFull_q;
reg BufferFull_2q;
 
reg Qualifier_mclk;
 
always @(posedge Mclk)
begin
Qualifier_mclk<=#Tp Qualifier;
BufferFull_q<=#Tp BufferFull;
BufferFull_2q<=#Tp BufferFull_q;
RiscStall_q <=#Tp RiscStall_O;
end
 
 
wire FirstCpuStall = Qualifier & ~Qualifier_mclk & TriggerLatch |
Qualifier_mclk & Trigger & ~TriggerLatch |
Qualifier & Trigger & ~Qualifier_mclk & ~TriggerLatch ;
 
 
//wire SyncSetCpuStall = Qualifier_mclk & TriggerLatch &
 
wire SyncSetCpuStall = RiscStall_O & ~RiscStall_q |
Qualifier_mclk & TriggerLatch &
(
(~ContinMode & ~BufferFull & ~BufferFull_q & StallCounter==`OPSELECTIONCOUNTER-1) |
(~ContinMode & ~BufferFull_q & BufferFull_2q & StallCounter==0) |
( ContinMode & StallCounter==`OPSELECTIONCOUNTER-1)
);
 
assign SyncResetCpuStall = (
(~ContinMode & ~BufferFull & ~BufferFull_q & StallCounter==`OPSELECTIONCOUNTER-2) |
(~ContinMode & ~BufferFull & BufferFull_q & StallCounter==`OPSELECTIONCOUNTER-1) |
( ContinMode & StallCounter==`OPSELECTIONCOUNTER-2)
);
 
assign RiscStall_O = FirstCpuStall | RiscStall;
 
 
always @(posedge Mclk or posedge Reset)
begin
if(Reset)
Counter<=#Tp 0;
else
if(CounterEn)
if(IncrementCounter)
Counter[`TRACECOUNTERWIDTH:0]<=#Tp Counter[`TRACECOUNTERWIDTH:0] + 1;
else
Counter[`TRACECOUNTERWIDTH:0]<=#Tp Counter[`TRACECOUNTERWIDTH:0] - 1;
end
 
 
always @(posedge Mclk or posedge Reset)
begin
if(Reset)
WritePointer<=#Tp 0;
else
if(IncrementPointer)
WritePointer[`TRACECOUNTERWIDTH-1:0]<=#Tp WritePointer[`TRACECOUNTERWIDTH-1:0] + 1;
end
 
always @(posedge Mclk or posedge Reset)
begin
if(Reset)
ReadPointer<=#Tp 0;
else
if(Decrement & ~ContinMode | Decrement & ContinMode & ~TraceEnable)
ReadPointer[`TRACECOUNTERWIDTH-1:0]<=#Tp ReadPointer[`TRACECOUNTERWIDTH-1:0] + 1;
else
if(ContinMode & IncrementPointer & (BufferFull | BufferFullDetected))
ReadPointer[`TRACECOUNTERWIDTH-1:0]<=#Tp WritePointer[`TRACECOUNTERWIDTH-1:0] + 1;
end
 
always @(posedge Mclk)
begin
if(~TraceEnable)
BufferFullDetected<=#Tp 0;
else
if(ContinMode & BufferFull)
BufferFullDetected<=#Tp 1;
end
 
 
always @(posedge Mclk or posedge Reset)
begin
if(Reset)
RiscStall<=#Tp 0;
else
if(SyncResetCpuStall)
RiscStall<=#Tp 0;
else
if(SyncSetCpuStall)
RiscStall<=#Tp 1;
end
 
 
always @(posedge Mclk)
begin
if(ResetStallCounter)
StallCounter<=#Tp 0;
else
if(RiscStall_q & (~BufferFull | ContinMode))
StallCounter<=#Tp StallCounter+1;
end
 
assign ResetStallCounter = StallCounter==(`OPSELECTIONCOUNTER-1) & ~BufferFull | Reset;
 
 
/**********************************************************************************
* *
* Valid status *
* *
**********************************************************************************/
wire Valid = ~BufferEmpty;
 
 
/**********************************************************************************
* *
* Writing and reading the sample to/from the buffer *
* *
**********************************************************************************/
always @ (posedge Mclk)
begin
if(WriteSample)
Buffer[WritePointer[`TRACECOUNTERWIDTH-1:0]]<={DataIn, 1'b0, OpSelect[`OPSELECTWIDTH-1:0]};
end
 
assign TraceChain = {Buffer[ReadPointer], 3'h0, Valid};
 
 
/**********************************************************************************
* *
* Operation select (to select which kind of data appears on the DATAIN lines) *
* *
**********************************************************************************/
assign OpSelect[`OPSELECTWIDTH-1:0] = StallCounter[`OPSELECTWIDTH-1:0];
 
 
 
/**********************************************************************************
* *
* Selecting which parts are going to be recorded as part of the sample *
* *
**********************************************************************************/
assign RecEnable = {1'b0, RecordINSTR, RecordWriteSPR, RecordReadSPR, RecordSDATA, RecordLDATA, RecordLSEA, RecordPC};
 
 
endmodule
/verilog/mem_if/flash_top.v
0,0 → 1,162
//////////////////////////////////////////////////////////////////////
//// ////
//// MP3 demo Flash interface ////
//// ////
//// This file is part of the MP3 demo application ////
//// http://www.opencores.org/cores/or1k/mp3/ ////
//// ////
//// Description ////
//// Connects MP3 demo tp Flash found on XSV board. ////
//// ////
//// To Do: ////
//// - nothing really ////
//// ////
//// Author(s): ////
//// - Lior Shtram, lior.shtram@flextronicssemi.com ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 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 $
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
module flash_top (
clk, rstn,
 
wb_dat_i, wb_dat_o, wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i,
wb_stb_i, wb_ack_o, wb_err_o,
 
flash_rstn, cen, oen, wen, rdy, d, a, a_oe
);
 
input clk;
input rstn;
 
input [31:0] wb_dat_i;
output [31:0] wb_dat_o;
input [31:0] wb_adr_i;
input [3:0] wb_sel_i;
input wb_we_i;
input wb_cyc_i;
input wb_stb_i;
output wb_ack_o;
output wb_err_o;
 
output flash_rstn;
output oen;
output cen;
output wen;
input rdy;
inout [7:0] d;
output [20:0] a;
output a_oe;
 
reg [4:0] counter;
reg [31:0] data_sr;
reg f_ack;
reg [3:0] middle_tphqv;
 
always @(posedge clk or negedge rstn)
begin
if(!rstn)
counter <= 5'h0;
else
if(!wb_cyc_i | (counter == 5'h10) | (|middle_tphqv))
counter <= #1 5'h0;
else
counter <= #1 counter + 1;
end
 
 
always @(posedge clk or negedge rstn)
begin
if(!rstn)
f_ack <= 1'h0;
else
if(counter == 5'h0f && !(|middle_tphqv))
f_ack <= #1 1'h1;
else
f_ack <= #1 1'h0;
end
 
 
assign wb_ack_o = f_ack;
 
assign flash_rstn = rstn;
assign a = { ~wb_adr_i[20], wb_adr_i[19:2], counter[3:2] };
assign a_oe = (wb_cyc_i &! (|middle_tphqv));
assign wb_dat_o = data_sr;
assign oen = |middle_tphqv;
assign wen = 1'b1;
/* SIMON */
//assign cen = |middle_tphqv | (counter[1:0] == 2'b01);
assign cen = |middle_tphqv | (counter[1:0] == 2'b01) | (counter[4:0] == 5'b0);
assign wb_err_o = 1'b0;
 
 
// synopsys translate_off
integer fflash;
initial fflash = $fopen("flash.log");
always @(posedge clk)
if (wb_cyc_i & !(|middle_tphqv)) begin // wb_ack_o should be qualified with wb_stb_i as well however OR1200 doesn't do this currently
if (wb_stb_i & wb_we_i) begin
// $fdisplay(fflash, "%t Trying to write into flash at %h", $time, wb_adr_i);
// #100 $finish;
end else if (wb_ack_o)
$fdisplay(fflash, "%t [%h] -> read %h", $time, wb_adr_i, wb_dat_o);
end
// synopsys translate_on
 
always @(posedge clk or negedge rstn)
if (!rstn)
middle_tphqv <= #1 4'hf;
else if (middle_tphqv)
middle_tphqv <= #1 middle_tphqv - 1;
 
always @(posedge clk or negedge rstn)
begin
if (!rstn) data_sr <= 32'b0;
else
if (counter[1:0] == 2'h3)
begin
case (counter[3:2])
2'h0 : data_sr[31:24] <= #1 d;
2'h1 : data_sr[23:16] <= #1 d;
2'h2 : data_sr[15:8] <= #1 d;
2'h3 : data_sr[7:0] <= #1 d;
default : data_sr <= 32'bx;
endcase
end
end
endmodule
/verilog/mem_if/sram_top.v
0,0 → 1,286
//////////////////////////////////////////////////////////////////////
//// ////
//// MP3 demo SRAM interface ////
//// ////
//// This file is part of the MP3 demo application ////
//// http://www.opencores.org/cores/or1k/mp3/ ////
//// ////
//// Description ////
//// Connects MP3 demo to SRAM. It does RMW for byte accesses ////
//// because XSV board has WEs on a 16-bit basis. ////
//// ////
//// To Do: ////
//// - nothing really ////
//// ////
//// Author(s): ////
//// - Simon Srot, simons@opencores.org ////
//// - Igor Mohor, igorm@opencores.org ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 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 $
//
 
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
 
module sram_top (
clk, rstn,
 
wb_dat_i, wb_dat_o, wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i,
wb_stb_i, wb_ack_o, wb_err_o,
 
r_cen, r0_wen, r1_wen, r_oen, r_a, r_d,
l_cen, l0_wen, l1_wen, l_oen, l_a, l_d
 
);
 
parameter addr_width = 19;
 
input clk;
input rstn;
 
input [31:0] wb_dat_i;
output [31:0] wb_dat_o;
input [31:0] wb_adr_i;
input [3:0] wb_sel_i;
input wb_we_i;
input wb_cyc_i;
input wb_stb_i;
output wb_ack_o;
output wb_err_o;
 
output r_oen;
output r0_wen;
output r1_wen;
output r_cen;
inout [15:0] r_d;
output [addr_width-1:0] r_a;
 
output l_oen;
output l0_wen;
output l1_wen;
output l_cen;
inout [15:0] l_d;
output [addr_width-1:0] l_a;
 
reg [15:0] r_data;
reg [15:0] l_data;
 
 
reg l0_wen;
wire l1_wen = l0_wen;
reg r0_wen;
wire r1_wen = r0_wen;
 
 
reg [31:0] latch_data;
reg ack_we;
 
wire l_oe;
wire r_oe;
 
assign l_oen = ~l_oe;
assign r_oen = ~r_oe;
 
 
reg Mux;
always @ (negedge clk or negedge rstn)
begin
if(~rstn)
Mux <= 1'b0;
else
if(ack_we)
Mux <= #1 1'b1;
else
Mux <= #1 1'b0;
end
 
 
reg [addr_width-1:0] LatchedAddr;
always @ (negedge clk or negedge rstn)
begin
if(~rstn)
LatchedAddr <= 'h0;
else
if(wb_cyc_i & wb_stb_i)
LatchedAddr <= #1 wb_adr_i[addr_width+1:2];
end
 
 
assign l_a = Mux? LatchedAddr : wb_adr_i[addr_width+1:2];
assign r_a = l_a;
 
 
reg [15:0] l_read;
reg [15:0] r_read;
// Data latch from RAM (read data)
always @ (posedge clk or negedge rstn)
begin
if(~rstn)
begin
l_read <= 16'h0;
r_read <= 16'h0;
end
else
if(wb_cyc_i & wb_stb_i)
begin
l_read <= #1 l_d[15:0];
r_read <= #1 r_d[15:0];
end
end
 
assign wb_dat_o = {r_d, l_d};
 
// Mux and latch data for writing (bytes 0 and 1)
reg [15:0] l_mux;
always @ (negedge clk or negedge rstn)
begin
if(~rstn)
l_mux <= 16'h0;
else
if(~l0_wen)
begin
if(wb_sel_i[0])
l_mux[7:0] <= #1 wb_dat_i[7:0];
else
l_mux[7:0] <= #1 l_read[7:0];
if(wb_sel_i[1])
l_mux[15:8] <= #1 wb_dat_i[15:8];
else
l_mux[15:8] <= #1 l_read[15:8];
end
else
l_mux[15:0] <= #1 16'hz;
end
 
 
 
// Mux and latch data for writing (bytes 2 and 3)
reg [15:0] r_mux;
always @ (negedge clk or negedge rstn)
begin
if(~rstn)
r_mux <= 16'h0;
else
if(~r0_wen)
begin
if(wb_sel_i[2])
r_mux[7:0] <= #1 wb_dat_i[23:16];
else
r_mux[7:0] <= #1 r_read[7:0];
if(wb_sel_i[3])
r_mux[15:8] <= #1 wb_dat_i[31:24];
else
r_mux[15:8] <= #1 r_read[15:8];
end
else
r_mux <= #1 16'hz;
end
 
 
assign l_d = l_mux;
assign r_d = r_mux;
 
 
// Output enable
assign l_oe = wb_cyc_i & wb_stb_i & l0_wen;
assign r_oe = wb_cyc_i & wb_stb_i & r0_wen;
 
 
// WE
always @ (posedge clk or negedge rstn)
begin
if(~rstn)
l0_wen <= 1'b1;
else
if(wb_cyc_i & wb_stb_i & wb_we_i & (|wb_sel_i[1:0]) & ~wb_ack_o)
l0_wen <= #1 1'b0;
else
l0_wen <= 1'b1;
end
 
 
// WE
always @ (posedge clk or negedge rstn)
begin
if(~rstn)
r0_wen <= 1'b1;
else
if(wb_cyc_i & wb_stb_i & wb_we_i & (|wb_sel_i[3:2]) & ~wb_ack_o)
r0_wen <= #1 1'b0;
else
r0_wen <= 1'b1;
end
 
 
// CE
assign l_cen = ~(wb_cyc_i & wb_stb_i);
assign r_cen = l_cen;
 
 
always @ (posedge clk or negedge rstn)
begin
if(~rstn)
ack_we <= 1'b0;
else
if(wb_cyc_i & wb_stb_i & wb_we_i & ~ack_we)
ack_we <= #1 1'b1;
else
ack_we <= #1 1'b0;
end
 
 
assign wb_ack_o = (wb_cyc_i & wb_stb_i & ~wb_we_i) | ack_we;
assign wb_err_o = 1'b0;
 
 
 
 
 
 
 
// synopsys translate_off
integer fsram;
initial fsram = $fopen("sram.log");
always @(posedge clk)
begin
if (~l0_wen | ~r0_wen)
$fdisplay(fsram, "%t [%h] <- write %h", $time, wb_adr_i, {r_d, l_d});
else
if(l_oe | r_oe)
$fdisplay(fsram, "%t [%h] -> read %h", $time, wb_adr_i, {r_d, l_d});
end
// synopsys translate_on
 
 
 
endmodule

powered by: WebSVN 2.1.0

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