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 |