Removed test cases that have been moved to yosys-test.
https://github.com/cliffordwolf/yosys-tests/
This commit is contained in:
parent
3ecc314238
commit
fbadb54b9b
83 changed files with 0 additions and 18963 deletions
|
@ -1,7 +0,0 @@
|
|||
|
||||
A collection of smaller rtl examples from the IWLS 2005 benchmark [1].
|
||||
We have no testbenches for these but we can check if we can
|
||||
parse and synthesize them.
|
||||
|
||||
[1] http://iwls.org/iwls2005/benchmarks.html
|
||||
|
|
@ -1,256 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// AES Cipher Top Level ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/aes_core/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: aes_cipher_top.v,v 1.1.1.1 2002/11/09 11:22:48 rudi Exp $
|
||||
//
|
||||
// $Date: 2002/11/09 11:22:48 $
|
||||
// $Revision: 1.1.1.1 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: aes_cipher_top.v,v $
|
||||
// Revision 1.1.1.1 2002/11/09 11:22:48 rudi
|
||||
// Initial Checkin
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
`include "timescale.v"
|
||||
|
||||
module aes_cipher_top(clk, rst, ld, done, key, text_in, text_out );
|
||||
input clk, rst;
|
||||
input ld;
|
||||
output done;
|
||||
input [127:0] key;
|
||||
input [127:0] text_in;
|
||||
output [127:0] text_out;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires
|
||||
//
|
||||
|
||||
wire [31:0] w0, w1, w2, w3;
|
||||
reg [127:0] text_in_r;
|
||||
reg [127:0] text_out;
|
||||
reg [7:0] sa00, sa01, sa02, sa03;
|
||||
reg [7:0] sa10, sa11, sa12, sa13;
|
||||
reg [7:0] sa20, sa21, sa22, sa23;
|
||||
reg [7:0] sa30, sa31, sa32, sa33;
|
||||
wire [7:0] sa00_next, sa01_next, sa02_next, sa03_next;
|
||||
wire [7:0] sa10_next, sa11_next, sa12_next, sa13_next;
|
||||
wire [7:0] sa20_next, sa21_next, sa22_next, sa23_next;
|
||||
wire [7:0] sa30_next, sa31_next, sa32_next, sa33_next;
|
||||
wire [7:0] sa00_sub, sa01_sub, sa02_sub, sa03_sub;
|
||||
wire [7:0] sa10_sub, sa11_sub, sa12_sub, sa13_sub;
|
||||
wire [7:0] sa20_sub, sa21_sub, sa22_sub, sa23_sub;
|
||||
wire [7:0] sa30_sub, sa31_sub, sa32_sub, sa33_sub;
|
||||
wire [7:0] sa00_sr, sa01_sr, sa02_sr, sa03_sr;
|
||||
wire [7:0] sa10_sr, sa11_sr, sa12_sr, sa13_sr;
|
||||
wire [7:0] sa20_sr, sa21_sr, sa22_sr, sa23_sr;
|
||||
wire [7:0] sa30_sr, sa31_sr, sa32_sr, sa33_sr;
|
||||
wire [7:0] sa00_mc, sa01_mc, sa02_mc, sa03_mc;
|
||||
wire [7:0] sa10_mc, sa11_mc, sa12_mc, sa13_mc;
|
||||
wire [7:0] sa20_mc, sa21_mc, sa22_mc, sa23_mc;
|
||||
wire [7:0] sa30_mc, sa31_mc, sa32_mc, sa33_mc;
|
||||
reg done, ld_r;
|
||||
reg [3:0] dcnt;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc Logic
|
||||
//
|
||||
|
||||
always @(posedge clk)
|
||||
if(!rst) dcnt <= #1 4'h0;
|
||||
else
|
||||
if(ld) dcnt <= #1 4'hb;
|
||||
else
|
||||
if(|dcnt) dcnt <= #1 dcnt - 4'h1;
|
||||
|
||||
always @(posedge clk) done <= #1 !(|dcnt[3:1]) & dcnt[0] & !ld;
|
||||
always @(posedge clk) if(ld) text_in_r <= #1 text_in;
|
||||
always @(posedge clk) ld_r <= #1 ld;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initial Permutation (AddRoundKey)
|
||||
//
|
||||
|
||||
always @(posedge clk) sa33 <= #1 ld_r ? text_in_r[007:000] ^ w3[07:00] : sa33_next;
|
||||
always @(posedge clk) sa23 <= #1 ld_r ? text_in_r[015:008] ^ w3[15:08] : sa23_next;
|
||||
always @(posedge clk) sa13 <= #1 ld_r ? text_in_r[023:016] ^ w3[23:16] : sa13_next;
|
||||
always @(posedge clk) sa03 <= #1 ld_r ? text_in_r[031:024] ^ w3[31:24] : sa03_next;
|
||||
always @(posedge clk) sa32 <= #1 ld_r ? text_in_r[039:032] ^ w2[07:00] : sa32_next;
|
||||
always @(posedge clk) sa22 <= #1 ld_r ? text_in_r[047:040] ^ w2[15:08] : sa22_next;
|
||||
always @(posedge clk) sa12 <= #1 ld_r ? text_in_r[055:048] ^ w2[23:16] : sa12_next;
|
||||
always @(posedge clk) sa02 <= #1 ld_r ? text_in_r[063:056] ^ w2[31:24] : sa02_next;
|
||||
always @(posedge clk) sa31 <= #1 ld_r ? text_in_r[071:064] ^ w1[07:00] : sa31_next;
|
||||
always @(posedge clk) sa21 <= #1 ld_r ? text_in_r[079:072] ^ w1[15:08] : sa21_next;
|
||||
always @(posedge clk) sa11 <= #1 ld_r ? text_in_r[087:080] ^ w1[23:16] : sa11_next;
|
||||
always @(posedge clk) sa01 <= #1 ld_r ? text_in_r[095:088] ^ w1[31:24] : sa01_next;
|
||||
always @(posedge clk) sa30 <= #1 ld_r ? text_in_r[103:096] ^ w0[07:00] : sa30_next;
|
||||
always @(posedge clk) sa20 <= #1 ld_r ? text_in_r[111:104] ^ w0[15:08] : sa20_next;
|
||||
always @(posedge clk) sa10 <= #1 ld_r ? text_in_r[119:112] ^ w0[23:16] : sa10_next;
|
||||
always @(posedge clk) sa00 <= #1 ld_r ? text_in_r[127:120] ^ w0[31:24] : sa00_next;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Round Permutations
|
||||
//
|
||||
|
||||
assign sa00_sr = sa00_sub;
|
||||
assign sa01_sr = sa01_sub;
|
||||
assign sa02_sr = sa02_sub;
|
||||
assign sa03_sr = sa03_sub;
|
||||
assign sa10_sr = sa11_sub;
|
||||
assign sa11_sr = sa12_sub;
|
||||
assign sa12_sr = sa13_sub;
|
||||
assign sa13_sr = sa10_sub;
|
||||
assign sa20_sr = sa22_sub;
|
||||
assign sa21_sr = sa23_sub;
|
||||
assign sa22_sr = sa20_sub;
|
||||
assign sa23_sr = sa21_sub;
|
||||
assign sa30_sr = sa33_sub;
|
||||
assign sa31_sr = sa30_sub;
|
||||
assign sa32_sr = sa31_sub;
|
||||
assign sa33_sr = sa32_sub;
|
||||
assign {sa00_mc, sa10_mc, sa20_mc, sa30_mc} = mix_col(sa00_sr,sa10_sr,sa20_sr,sa30_sr);
|
||||
assign {sa01_mc, sa11_mc, sa21_mc, sa31_mc} = mix_col(sa01_sr,sa11_sr,sa21_sr,sa31_sr);
|
||||
assign {sa02_mc, sa12_mc, sa22_mc, sa32_mc} = mix_col(sa02_sr,sa12_sr,sa22_sr,sa32_sr);
|
||||
assign {sa03_mc, sa13_mc, sa23_mc, sa33_mc} = mix_col(sa03_sr,sa13_sr,sa23_sr,sa33_sr);
|
||||
assign sa00_next = sa00_mc ^ w0[31:24];
|
||||
assign sa01_next = sa01_mc ^ w1[31:24];
|
||||
assign sa02_next = sa02_mc ^ w2[31:24];
|
||||
assign sa03_next = sa03_mc ^ w3[31:24];
|
||||
assign sa10_next = sa10_mc ^ w0[23:16];
|
||||
assign sa11_next = sa11_mc ^ w1[23:16];
|
||||
assign sa12_next = sa12_mc ^ w2[23:16];
|
||||
assign sa13_next = sa13_mc ^ w3[23:16];
|
||||
assign sa20_next = sa20_mc ^ w0[15:08];
|
||||
assign sa21_next = sa21_mc ^ w1[15:08];
|
||||
assign sa22_next = sa22_mc ^ w2[15:08];
|
||||
assign sa23_next = sa23_mc ^ w3[15:08];
|
||||
assign sa30_next = sa30_mc ^ w0[07:00];
|
||||
assign sa31_next = sa31_mc ^ w1[07:00];
|
||||
assign sa32_next = sa32_mc ^ w2[07:00];
|
||||
assign sa33_next = sa33_mc ^ w3[07:00];
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Final text output
|
||||
//
|
||||
|
||||
always @(posedge clk) text_out[127:120] <= #1 sa00_sr ^ w0[31:24];
|
||||
always @(posedge clk) text_out[095:088] <= #1 sa01_sr ^ w1[31:24];
|
||||
always @(posedge clk) text_out[063:056] <= #1 sa02_sr ^ w2[31:24];
|
||||
always @(posedge clk) text_out[031:024] <= #1 sa03_sr ^ w3[31:24];
|
||||
always @(posedge clk) text_out[119:112] <= #1 sa10_sr ^ w0[23:16];
|
||||
always @(posedge clk) text_out[087:080] <= #1 sa11_sr ^ w1[23:16];
|
||||
always @(posedge clk) text_out[055:048] <= #1 sa12_sr ^ w2[23:16];
|
||||
always @(posedge clk) text_out[023:016] <= #1 sa13_sr ^ w3[23:16];
|
||||
always @(posedge clk) text_out[111:104] <= #1 sa20_sr ^ w0[15:08];
|
||||
always @(posedge clk) text_out[079:072] <= #1 sa21_sr ^ w1[15:08];
|
||||
always @(posedge clk) text_out[047:040] <= #1 sa22_sr ^ w2[15:08];
|
||||
always @(posedge clk) text_out[015:008] <= #1 sa23_sr ^ w3[15:08];
|
||||
always @(posedge clk) text_out[103:096] <= #1 sa30_sr ^ w0[07:00];
|
||||
always @(posedge clk) text_out[071:064] <= #1 sa31_sr ^ w1[07:00];
|
||||
always @(posedge clk) text_out[039:032] <= #1 sa32_sr ^ w2[07:00];
|
||||
always @(posedge clk) text_out[007:000] <= #1 sa33_sr ^ w3[07:00];
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generic Functions
|
||||
//
|
||||
|
||||
function [31:0] mix_col;
|
||||
input [7:0] s0,s1,s2,s3;
|
||||
reg [7:0] s0_o,s1_o,s2_o,s3_o;
|
||||
begin
|
||||
mix_col[31:24]=xtime(s0)^xtime(s1)^s1^s2^s3;
|
||||
mix_col[23:16]=s0^xtime(s1)^xtime(s2)^s2^s3;
|
||||
mix_col[15:08]=s0^s1^xtime(s2)^xtime(s3)^s3;
|
||||
mix_col[07:00]=xtime(s0)^s0^s1^s2^xtime(s3);
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [7:0] xtime;
|
||||
input [7:0] b; xtime={b[6:0],1'b0}^(8'h1b&{8{b[7]}});
|
||||
endfunction
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Modules
|
||||
//
|
||||
|
||||
aes_key_expand_128 u0(
|
||||
.clk( clk ),
|
||||
.kld( ld ),
|
||||
.key( key ),
|
||||
.wo_0( w0 ),
|
||||
.wo_1( w1 ),
|
||||
.wo_2( w2 ),
|
||||
.wo_3( w3 ));
|
||||
|
||||
aes_sbox us00( .a( sa00 ), .d( sa00_sub ));
|
||||
aes_sbox us01( .a( sa01 ), .d( sa01_sub ));
|
||||
aes_sbox us02( .a( sa02 ), .d( sa02_sub ));
|
||||
aes_sbox us03( .a( sa03 ), .d( sa03_sub ));
|
||||
aes_sbox us10( .a( sa10 ), .d( sa10_sub ));
|
||||
aes_sbox us11( .a( sa11 ), .d( sa11_sub ));
|
||||
aes_sbox us12( .a( sa12 ), .d( sa12_sub ));
|
||||
aes_sbox us13( .a( sa13 ), .d( sa13_sub ));
|
||||
aes_sbox us20( .a( sa20 ), .d( sa20_sub ));
|
||||
aes_sbox us21( .a( sa21 ), .d( sa21_sub ));
|
||||
aes_sbox us22( .a( sa22 ), .d( sa22_sub ));
|
||||
aes_sbox us23( .a( sa23 ), .d( sa23_sub ));
|
||||
aes_sbox us30( .a( sa30 ), .d( sa30_sub ));
|
||||
aes_sbox us31( .a( sa31 ), .d( sa31_sub ));
|
||||
aes_sbox us32( .a( sa32 ), .d( sa32_sub ));
|
||||
aes_sbox us33( .a( sa33 ), .d( sa33_sub ));
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -1,327 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// AES Inverse Cipher Top Level ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/aes_core/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: aes_inv_cipher_top.v,v 1.1.1.1 2002/11/09 11:22:53 rudi Exp $
|
||||
//
|
||||
// $Date: 2002/11/09 11:22:53 $
|
||||
// $Revision: 1.1.1.1 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: aes_inv_cipher_top.v,v $
|
||||
// Revision 1.1.1.1 2002/11/09 11:22:53 rudi
|
||||
// Initial Checkin
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
`include "timescale.v"
|
||||
|
||||
module aes_inv_cipher_top(clk, rst, kld, ld, done, key, text_in, text_out );
|
||||
input clk, rst;
|
||||
input kld, ld;
|
||||
output done;
|
||||
input [127:0] key;
|
||||
input [127:0] text_in;
|
||||
output [127:0] text_out;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires
|
||||
//
|
||||
|
||||
wire [31:0] wk0, wk1, wk2, wk3;
|
||||
reg [31:0] w0, w1, w2, w3;
|
||||
reg [127:0] text_in_r;
|
||||
reg [127:0] text_out;
|
||||
reg [7:0] sa00, sa01, sa02, sa03;
|
||||
reg [7:0] sa10, sa11, sa12, sa13;
|
||||
reg [7:0] sa20, sa21, sa22, sa23;
|
||||
reg [7:0] sa30, sa31, sa32, sa33;
|
||||
wire [7:0] sa00_next, sa01_next, sa02_next, sa03_next;
|
||||
wire [7:0] sa10_next, sa11_next, sa12_next, sa13_next;
|
||||
wire [7:0] sa20_next, sa21_next, sa22_next, sa23_next;
|
||||
wire [7:0] sa30_next, sa31_next, sa32_next, sa33_next;
|
||||
wire [7:0] sa00_sub, sa01_sub, sa02_sub, sa03_sub;
|
||||
wire [7:0] sa10_sub, sa11_sub, sa12_sub, sa13_sub;
|
||||
wire [7:0] sa20_sub, sa21_sub, sa22_sub, sa23_sub;
|
||||
wire [7:0] sa30_sub, sa31_sub, sa32_sub, sa33_sub;
|
||||
wire [7:0] sa00_sr, sa01_sr, sa02_sr, sa03_sr;
|
||||
wire [7:0] sa10_sr, sa11_sr, sa12_sr, sa13_sr;
|
||||
wire [7:0] sa20_sr, sa21_sr, sa22_sr, sa23_sr;
|
||||
wire [7:0] sa30_sr, sa31_sr, sa32_sr, sa33_sr;
|
||||
wire [7:0] sa00_ark, sa01_ark, sa02_ark, sa03_ark;
|
||||
wire [7:0] sa10_ark, sa11_ark, sa12_ark, sa13_ark;
|
||||
wire [7:0] sa20_ark, sa21_ark, sa22_ark, sa23_ark;
|
||||
wire [7:0] sa30_ark, sa31_ark, sa32_ark, sa33_ark;
|
||||
reg ld_r, go, done;
|
||||
reg [3:0] dcnt;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc Logic
|
||||
//
|
||||
|
||||
always @(posedge clk)
|
||||
if(!rst) dcnt <= #1 4'h0;
|
||||
else
|
||||
if(done) dcnt <= #1 4'h0;
|
||||
else
|
||||
if(ld) dcnt <= #1 4'h1;
|
||||
else
|
||||
if(go) dcnt <= #1 dcnt + 4'h1;
|
||||
|
||||
always @(posedge clk) done <= #1 (dcnt==4'hb) & !ld;
|
||||
|
||||
always @(posedge clk)
|
||||
if(!rst) go <= #1 1'b0;
|
||||
else
|
||||
if(ld) go <= #1 1'b1;
|
||||
else
|
||||
if(done) go <= #1 1'b0;
|
||||
|
||||
always @(posedge clk) if(ld) text_in_r <= #1 text_in;
|
||||
|
||||
always @(posedge clk) ld_r <= #1 ld;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initial Permutation
|
||||
//
|
||||
|
||||
always @(posedge clk) sa33 <= #1 ld_r ? text_in_r[007:000] ^ w3[07:00] : sa33_next;
|
||||
always @(posedge clk) sa23 <= #1 ld_r ? text_in_r[015:008] ^ w3[15:08] : sa23_next;
|
||||
always @(posedge clk) sa13 <= #1 ld_r ? text_in_r[023:016] ^ w3[23:16] : sa13_next;
|
||||
always @(posedge clk) sa03 <= #1 ld_r ? text_in_r[031:024] ^ w3[31:24] : sa03_next;
|
||||
always @(posedge clk) sa32 <= #1 ld_r ? text_in_r[039:032] ^ w2[07:00] : sa32_next;
|
||||
always @(posedge clk) sa22 <= #1 ld_r ? text_in_r[047:040] ^ w2[15:08] : sa22_next;
|
||||
always @(posedge clk) sa12 <= #1 ld_r ? text_in_r[055:048] ^ w2[23:16] : sa12_next;
|
||||
always @(posedge clk) sa02 <= #1 ld_r ? text_in_r[063:056] ^ w2[31:24] : sa02_next;
|
||||
always @(posedge clk) sa31 <= #1 ld_r ? text_in_r[071:064] ^ w1[07:00] : sa31_next;
|
||||
always @(posedge clk) sa21 <= #1 ld_r ? text_in_r[079:072] ^ w1[15:08] : sa21_next;
|
||||
always @(posedge clk) sa11 <= #1 ld_r ? text_in_r[087:080] ^ w1[23:16] : sa11_next;
|
||||
always @(posedge clk) sa01 <= #1 ld_r ? text_in_r[095:088] ^ w1[31:24] : sa01_next;
|
||||
always @(posedge clk) sa30 <= #1 ld_r ? text_in_r[103:096] ^ w0[07:00] : sa30_next;
|
||||
always @(posedge clk) sa20 <= #1 ld_r ? text_in_r[111:104] ^ w0[15:08] : sa20_next;
|
||||
always @(posedge clk) sa10 <= #1 ld_r ? text_in_r[119:112] ^ w0[23:16] : sa10_next;
|
||||
always @(posedge clk) sa00 <= #1 ld_r ? text_in_r[127:120] ^ w0[31:24] : sa00_next;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Round Permutations
|
||||
//
|
||||
|
||||
assign sa00_sr = sa00;
|
||||
assign sa01_sr = sa01;
|
||||
assign sa02_sr = sa02;
|
||||
assign sa03_sr = sa03;
|
||||
assign sa10_sr = sa13;
|
||||
assign sa11_sr = sa10;
|
||||
assign sa12_sr = sa11;
|
||||
assign sa13_sr = sa12;
|
||||
assign sa20_sr = sa22;
|
||||
assign sa21_sr = sa23;
|
||||
assign sa22_sr = sa20;
|
||||
assign sa23_sr = sa21;
|
||||
assign sa30_sr = sa31;
|
||||
assign sa31_sr = sa32;
|
||||
assign sa32_sr = sa33;
|
||||
assign sa33_sr = sa30;
|
||||
assign sa00_ark = sa00_sub ^ w0[31:24];
|
||||
assign sa01_ark = sa01_sub ^ w1[31:24];
|
||||
assign sa02_ark = sa02_sub ^ w2[31:24];
|
||||
assign sa03_ark = sa03_sub ^ w3[31:24];
|
||||
assign sa10_ark = sa10_sub ^ w0[23:16];
|
||||
assign sa11_ark = sa11_sub ^ w1[23:16];
|
||||
assign sa12_ark = sa12_sub ^ w2[23:16];
|
||||
assign sa13_ark = sa13_sub ^ w3[23:16];
|
||||
assign sa20_ark = sa20_sub ^ w0[15:08];
|
||||
assign sa21_ark = sa21_sub ^ w1[15:08];
|
||||
assign sa22_ark = sa22_sub ^ w2[15:08];
|
||||
assign sa23_ark = sa23_sub ^ w3[15:08];
|
||||
assign sa30_ark = sa30_sub ^ w0[07:00];
|
||||
assign sa31_ark = sa31_sub ^ w1[07:00];
|
||||
assign sa32_ark = sa32_sub ^ w2[07:00];
|
||||
assign sa33_ark = sa33_sub ^ w3[07:00];
|
||||
assign {sa00_next, sa10_next, sa20_next, sa30_next} = inv_mix_col(sa00_ark,sa10_ark,sa20_ark,sa30_ark);
|
||||
assign {sa01_next, sa11_next, sa21_next, sa31_next} = inv_mix_col(sa01_ark,sa11_ark,sa21_ark,sa31_ark);
|
||||
assign {sa02_next, sa12_next, sa22_next, sa32_next} = inv_mix_col(sa02_ark,sa12_ark,sa22_ark,sa32_ark);
|
||||
assign {sa03_next, sa13_next, sa23_next, sa33_next} = inv_mix_col(sa03_ark,sa13_ark,sa23_ark,sa33_ark);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Final Text Output
|
||||
//
|
||||
|
||||
always @(posedge clk) text_out[127:120] <= #1 sa00_ark;
|
||||
always @(posedge clk) text_out[095:088] <= #1 sa01_ark;
|
||||
always @(posedge clk) text_out[063:056] <= #1 sa02_ark;
|
||||
always @(posedge clk) text_out[031:024] <= #1 sa03_ark;
|
||||
always @(posedge clk) text_out[119:112] <= #1 sa10_ark;
|
||||
always @(posedge clk) text_out[087:080] <= #1 sa11_ark;
|
||||
always @(posedge clk) text_out[055:048] <= #1 sa12_ark;
|
||||
always @(posedge clk) text_out[023:016] <= #1 sa13_ark;
|
||||
always @(posedge clk) text_out[111:104] <= #1 sa20_ark;
|
||||
always @(posedge clk) text_out[079:072] <= #1 sa21_ark;
|
||||
always @(posedge clk) text_out[047:040] <= #1 sa22_ark;
|
||||
always @(posedge clk) text_out[015:008] <= #1 sa23_ark;
|
||||
always @(posedge clk) text_out[103:096] <= #1 sa30_ark;
|
||||
always @(posedge clk) text_out[071:064] <= #1 sa31_ark;
|
||||
always @(posedge clk) text_out[039:032] <= #1 sa32_ark;
|
||||
always @(posedge clk) text_out[007:000] <= #1 sa33_ark;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generic Functions
|
||||
//
|
||||
|
||||
function [31:0] inv_mix_col;
|
||||
input [7:0] s0,s1,s2,s3;
|
||||
begin
|
||||
inv_mix_col[31:24]=pmul_e(s0)^pmul_b(s1)^pmul_d(s2)^pmul_9(s3);
|
||||
inv_mix_col[23:16]=pmul_9(s0)^pmul_e(s1)^pmul_b(s2)^pmul_d(s3);
|
||||
inv_mix_col[15:08]=pmul_d(s0)^pmul_9(s1)^pmul_e(s2)^pmul_b(s3);
|
||||
inv_mix_col[07:00]=pmul_b(s0)^pmul_d(s1)^pmul_9(s2)^pmul_e(s3);
|
||||
end
|
||||
endfunction
|
||||
|
||||
// Some synthesis tools don't like xtime being called recursevly ...
|
||||
function [7:0] pmul_e;
|
||||
input [7:0] b;
|
||||
reg [7:0] two,four,eight;
|
||||
begin
|
||||
two=xtime(b);four=xtime(two);eight=xtime(four);pmul_e=eight^four^two;
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [7:0] pmul_9;
|
||||
input [7:0] b;
|
||||
reg [7:0] two,four,eight;
|
||||
begin
|
||||
two=xtime(b);four=xtime(two);eight=xtime(four);pmul_9=eight^b;
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [7:0] pmul_d;
|
||||
input [7:0] b;
|
||||
reg [7:0] two,four,eight;
|
||||
begin
|
||||
two=xtime(b);four=xtime(two);eight=xtime(four);pmul_d=eight^four^b;
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [7:0] pmul_b;
|
||||
input [7:0] b;
|
||||
reg [7:0] two,four,eight;
|
||||
begin
|
||||
two=xtime(b);four=xtime(two);eight=xtime(four);pmul_b=eight^two^b;
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [7:0] xtime;
|
||||
input [7:0] b;xtime={b[6:0],1'b0}^(8'h1b&{8{b[7]}});
|
||||
endfunction
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Key Buffer
|
||||
//
|
||||
|
||||
reg [127:0] kb[10:0];
|
||||
reg [3:0] kcnt;
|
||||
reg kdone;
|
||||
reg kb_ld;
|
||||
|
||||
always @(posedge clk)
|
||||
if(!rst) kcnt <= #1 4'ha;
|
||||
else
|
||||
if(kld) kcnt <= #1 4'ha;
|
||||
else
|
||||
if(kb_ld) kcnt <= #1 kcnt - 4'h1;
|
||||
|
||||
always @(posedge clk)
|
||||
if(!rst) kb_ld <= #1 1'b0;
|
||||
else
|
||||
if(kld) kb_ld <= #1 1'b1;
|
||||
else
|
||||
if(kcnt==4'h0) kb_ld <= #1 1'b0;
|
||||
|
||||
always @(posedge clk) kdone <= #1 (kcnt==4'h0) & !kld;
|
||||
always @(posedge clk) if(kb_ld) kb[kcnt] <= #1 {wk3, wk2, wk1, wk0};
|
||||
always @(posedge clk) {w3, w2, w1, w0} <= #1 kb[dcnt];
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Modules
|
||||
//
|
||||
|
||||
aes_key_expand_128 u0(
|
||||
.clk( clk ),
|
||||
.kld( kld ),
|
||||
.key( key ),
|
||||
.wo_0( wk0 ),
|
||||
.wo_1( wk1 ),
|
||||
.wo_2( wk2 ),
|
||||
.wo_3( wk3 ));
|
||||
|
||||
aes_inv_sbox us00( .a( sa00_sr ), .d( sa00_sub ));
|
||||
aes_inv_sbox us01( .a( sa01_sr ), .d( sa01_sub ));
|
||||
aes_inv_sbox us02( .a( sa02_sr ), .d( sa02_sub ));
|
||||
aes_inv_sbox us03( .a( sa03_sr ), .d( sa03_sub ));
|
||||
aes_inv_sbox us10( .a( sa10_sr ), .d( sa10_sub ));
|
||||
aes_inv_sbox us11( .a( sa11_sr ), .d( sa11_sub ));
|
||||
aes_inv_sbox us12( .a( sa12_sr ), .d( sa12_sub ));
|
||||
aes_inv_sbox us13( .a( sa13_sr ), .d( sa13_sub ));
|
||||
aes_inv_sbox us20( .a( sa20_sr ), .d( sa20_sub ));
|
||||
aes_inv_sbox us21( .a( sa21_sr ), .d( sa21_sub ));
|
||||
aes_inv_sbox us22( .a( sa22_sr ), .d( sa22_sub ));
|
||||
aes_inv_sbox us23( .a( sa23_sr ), .d( sa23_sub ));
|
||||
aes_inv_sbox us30( .a( sa30_sr ), .d( sa30_sub ));
|
||||
aes_inv_sbox us31( .a( sa31_sr ), .d( sa31_sub ));
|
||||
aes_inv_sbox us32( .a( sa32_sr ), .d( sa32_sub ));
|
||||
aes_inv_sbox us33( .a( sa33_sr ), .d( sa33_sub ));
|
||||
|
||||
endmodule
|
||||
|
|
@ -1,328 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// AES Inverse SBOX (ROM) ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/aes_core/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: aes_inv_sbox.v,v 1.1.1.1 2002/11/09 11:22:55 rudi Exp $
|
||||
//
|
||||
// $Date: 2002/11/09 11:22:55 $
|
||||
// $Revision: 1.1.1.1 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: aes_inv_sbox.v,v $
|
||||
// Revision 1.1.1.1 2002/11/09 11:22:55 rudi
|
||||
// Initial Checkin
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
`include "timescale.v"
|
||||
|
||||
module aes_inv_sbox(a,d);
|
||||
input [7:0] a;
|
||||
output [7:0] d;
|
||||
reg [7:0] d;
|
||||
|
||||
always @(a)
|
||||
case(a) // synopsys full_case parallel_case
|
||||
8'h00: d=8'h52;
|
||||
8'h01: d=8'h09;
|
||||
8'h02: d=8'h6a;
|
||||
8'h03: d=8'hd5;
|
||||
8'h04: d=8'h30;
|
||||
8'h05: d=8'h36;
|
||||
8'h06: d=8'ha5;
|
||||
8'h07: d=8'h38;
|
||||
8'h08: d=8'hbf;
|
||||
8'h09: d=8'h40;
|
||||
8'h0a: d=8'ha3;
|
||||
8'h0b: d=8'h9e;
|
||||
8'h0c: d=8'h81;
|
||||
8'h0d: d=8'hf3;
|
||||
8'h0e: d=8'hd7;
|
||||
8'h0f: d=8'hfb;
|
||||
8'h10: d=8'h7c;
|
||||
8'h11: d=8'he3;
|
||||
8'h12: d=8'h39;
|
||||
8'h13: d=8'h82;
|
||||
8'h14: d=8'h9b;
|
||||
8'h15: d=8'h2f;
|
||||
8'h16: d=8'hff;
|
||||
8'h17: d=8'h87;
|
||||
8'h18: d=8'h34;
|
||||
8'h19: d=8'h8e;
|
||||
8'h1a: d=8'h43;
|
||||
8'h1b: d=8'h44;
|
||||
8'h1c: d=8'hc4;
|
||||
8'h1d: d=8'hde;
|
||||
8'h1e: d=8'he9;
|
||||
8'h1f: d=8'hcb;
|
||||
8'h20: d=8'h54;
|
||||
8'h21: d=8'h7b;
|
||||
8'h22: d=8'h94;
|
||||
8'h23: d=8'h32;
|
||||
8'h24: d=8'ha6;
|
||||
8'h25: d=8'hc2;
|
||||
8'h26: d=8'h23;
|
||||
8'h27: d=8'h3d;
|
||||
8'h28: d=8'hee;
|
||||
8'h29: d=8'h4c;
|
||||
8'h2a: d=8'h95;
|
||||
8'h2b: d=8'h0b;
|
||||
8'h2c: d=8'h42;
|
||||
8'h2d: d=8'hfa;
|
||||
8'h2e: d=8'hc3;
|
||||
8'h2f: d=8'h4e;
|
||||
8'h30: d=8'h08;
|
||||
8'h31: d=8'h2e;
|
||||
8'h32: d=8'ha1;
|
||||
8'h33: d=8'h66;
|
||||
8'h34: d=8'h28;
|
||||
8'h35: d=8'hd9;
|
||||
8'h36: d=8'h24;
|
||||
8'h37: d=8'hb2;
|
||||
8'h38: d=8'h76;
|
||||
8'h39: d=8'h5b;
|
||||
8'h3a: d=8'ha2;
|
||||
8'h3b: d=8'h49;
|
||||
8'h3c: d=8'h6d;
|
||||
8'h3d: d=8'h8b;
|
||||
8'h3e: d=8'hd1;
|
||||
8'h3f: d=8'h25;
|
||||
8'h40: d=8'h72;
|
||||
8'h41: d=8'hf8;
|
||||
8'h42: d=8'hf6;
|
||||
8'h43: d=8'h64;
|
||||
8'h44: d=8'h86;
|
||||
8'h45: d=8'h68;
|
||||
8'h46: d=8'h98;
|
||||
8'h47: d=8'h16;
|
||||
8'h48: d=8'hd4;
|
||||
8'h49: d=8'ha4;
|
||||
8'h4a: d=8'h5c;
|
||||
8'h4b: d=8'hcc;
|
||||
8'h4c: d=8'h5d;
|
||||
8'h4d: d=8'h65;
|
||||
8'h4e: d=8'hb6;
|
||||
8'h4f: d=8'h92;
|
||||
8'h50: d=8'h6c;
|
||||
8'h51: d=8'h70;
|
||||
8'h52: d=8'h48;
|
||||
8'h53: d=8'h50;
|
||||
8'h54: d=8'hfd;
|
||||
8'h55: d=8'hed;
|
||||
8'h56: d=8'hb9;
|
||||
8'h57: d=8'hda;
|
||||
8'h58: d=8'h5e;
|
||||
8'h59: d=8'h15;
|
||||
8'h5a: d=8'h46;
|
||||
8'h5b: d=8'h57;
|
||||
8'h5c: d=8'ha7;
|
||||
8'h5d: d=8'h8d;
|
||||
8'h5e: d=8'h9d;
|
||||
8'h5f: d=8'h84;
|
||||
8'h60: d=8'h90;
|
||||
8'h61: d=8'hd8;
|
||||
8'h62: d=8'hab;
|
||||
8'h63: d=8'h00;
|
||||
8'h64: d=8'h8c;
|
||||
8'h65: d=8'hbc;
|
||||
8'h66: d=8'hd3;
|
||||
8'h67: d=8'h0a;
|
||||
8'h68: d=8'hf7;
|
||||
8'h69: d=8'he4;
|
||||
8'h6a: d=8'h58;
|
||||
8'h6b: d=8'h05;
|
||||
8'h6c: d=8'hb8;
|
||||
8'h6d: d=8'hb3;
|
||||
8'h6e: d=8'h45;
|
||||
8'h6f: d=8'h06;
|
||||
8'h70: d=8'hd0;
|
||||
8'h71: d=8'h2c;
|
||||
8'h72: d=8'h1e;
|
||||
8'h73: d=8'h8f;
|
||||
8'h74: d=8'hca;
|
||||
8'h75: d=8'h3f;
|
||||
8'h76: d=8'h0f;
|
||||
8'h77: d=8'h02;
|
||||
8'h78: d=8'hc1;
|
||||
8'h79: d=8'haf;
|
||||
8'h7a: d=8'hbd;
|
||||
8'h7b: d=8'h03;
|
||||
8'h7c: d=8'h01;
|
||||
8'h7d: d=8'h13;
|
||||
8'h7e: d=8'h8a;
|
||||
8'h7f: d=8'h6b;
|
||||
8'h80: d=8'h3a;
|
||||
8'h81: d=8'h91;
|
||||
8'h82: d=8'h11;
|
||||
8'h83: d=8'h41;
|
||||
8'h84: d=8'h4f;
|
||||
8'h85: d=8'h67;
|
||||
8'h86: d=8'hdc;
|
||||
8'h87: d=8'hea;
|
||||
8'h88: d=8'h97;
|
||||
8'h89: d=8'hf2;
|
||||
8'h8a: d=8'hcf;
|
||||
8'h8b: d=8'hce;
|
||||
8'h8c: d=8'hf0;
|
||||
8'h8d: d=8'hb4;
|
||||
8'h8e: d=8'he6;
|
||||
8'h8f: d=8'h73;
|
||||
8'h90: d=8'h96;
|
||||
8'h91: d=8'hac;
|
||||
8'h92: d=8'h74;
|
||||
8'h93: d=8'h22;
|
||||
8'h94: d=8'he7;
|
||||
8'h95: d=8'had;
|
||||
8'h96: d=8'h35;
|
||||
8'h97: d=8'h85;
|
||||
8'h98: d=8'he2;
|
||||
8'h99: d=8'hf9;
|
||||
8'h9a: d=8'h37;
|
||||
8'h9b: d=8'he8;
|
||||
8'h9c: d=8'h1c;
|
||||
8'h9d: d=8'h75;
|
||||
8'h9e: d=8'hdf;
|
||||
8'h9f: d=8'h6e;
|
||||
8'ha0: d=8'h47;
|
||||
8'ha1: d=8'hf1;
|
||||
8'ha2: d=8'h1a;
|
||||
8'ha3: d=8'h71;
|
||||
8'ha4: d=8'h1d;
|
||||
8'ha5: d=8'h29;
|
||||
8'ha6: d=8'hc5;
|
||||
8'ha7: d=8'h89;
|
||||
8'ha8: d=8'h6f;
|
||||
8'ha9: d=8'hb7;
|
||||
8'haa: d=8'h62;
|
||||
8'hab: d=8'h0e;
|
||||
8'hac: d=8'haa;
|
||||
8'had: d=8'h18;
|
||||
8'hae: d=8'hbe;
|
||||
8'haf: d=8'h1b;
|
||||
8'hb0: d=8'hfc;
|
||||
8'hb1: d=8'h56;
|
||||
8'hb2: d=8'h3e;
|
||||
8'hb3: d=8'h4b;
|
||||
8'hb4: d=8'hc6;
|
||||
8'hb5: d=8'hd2;
|
||||
8'hb6: d=8'h79;
|
||||
8'hb7: d=8'h20;
|
||||
8'hb8: d=8'h9a;
|
||||
8'hb9: d=8'hdb;
|
||||
8'hba: d=8'hc0;
|
||||
8'hbb: d=8'hfe;
|
||||
8'hbc: d=8'h78;
|
||||
8'hbd: d=8'hcd;
|
||||
8'hbe: d=8'h5a;
|
||||
8'hbf: d=8'hf4;
|
||||
8'hc0: d=8'h1f;
|
||||
8'hc1: d=8'hdd;
|
||||
8'hc2: d=8'ha8;
|
||||
8'hc3: d=8'h33;
|
||||
8'hc4: d=8'h88;
|
||||
8'hc5: d=8'h07;
|
||||
8'hc6: d=8'hc7;
|
||||
8'hc7: d=8'h31;
|
||||
8'hc8: d=8'hb1;
|
||||
8'hc9: d=8'h12;
|
||||
8'hca: d=8'h10;
|
||||
8'hcb: d=8'h59;
|
||||
8'hcc: d=8'h27;
|
||||
8'hcd: d=8'h80;
|
||||
8'hce: d=8'hec;
|
||||
8'hcf: d=8'h5f;
|
||||
8'hd0: d=8'h60;
|
||||
8'hd1: d=8'h51;
|
||||
8'hd2: d=8'h7f;
|
||||
8'hd3: d=8'ha9;
|
||||
8'hd4: d=8'h19;
|
||||
8'hd5: d=8'hb5;
|
||||
8'hd6: d=8'h4a;
|
||||
8'hd7: d=8'h0d;
|
||||
8'hd8: d=8'h2d;
|
||||
8'hd9: d=8'he5;
|
||||
8'hda: d=8'h7a;
|
||||
8'hdb: d=8'h9f;
|
||||
8'hdc: d=8'h93;
|
||||
8'hdd: d=8'hc9;
|
||||
8'hde: d=8'h9c;
|
||||
8'hdf: d=8'hef;
|
||||
8'he0: d=8'ha0;
|
||||
8'he1: d=8'he0;
|
||||
8'he2: d=8'h3b;
|
||||
8'he3: d=8'h4d;
|
||||
8'he4: d=8'hae;
|
||||
8'he5: d=8'h2a;
|
||||
8'he6: d=8'hf5;
|
||||
8'he7: d=8'hb0;
|
||||
8'he8: d=8'hc8;
|
||||
8'he9: d=8'heb;
|
||||
8'hea: d=8'hbb;
|
||||
8'heb: d=8'h3c;
|
||||
8'hec: d=8'h83;
|
||||
8'hed: d=8'h53;
|
||||
8'hee: d=8'h99;
|
||||
8'hef: d=8'h61;
|
||||
8'hf0: d=8'h17;
|
||||
8'hf1: d=8'h2b;
|
||||
8'hf2: d=8'h04;
|
||||
8'hf3: d=8'h7e;
|
||||
8'hf4: d=8'hba;
|
||||
8'hf5: d=8'h77;
|
||||
8'hf6: d=8'hd6;
|
||||
8'hf7: d=8'h26;
|
||||
8'hf8: d=8'he1;
|
||||
8'hf9: d=8'h69;
|
||||
8'hfa: d=8'h14;
|
||||
8'hfb: d=8'h63;
|
||||
8'hfc: d=8'h55;
|
||||
8'hfd: d=8'h21;
|
||||
8'hfe: d=8'h0c;
|
||||
8'hff: d=8'h7d;
|
||||
endcase
|
||||
endmodule
|
||||
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// AES Key Expand Block (for 128 bit keys) ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/aes_core/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: aes_key_expand_128.v,v 1.1.1.1 2002/11/09 11:22:38 rudi Exp $
|
||||
//
|
||||
// $Date: 2002/11/09 11:22:38 $
|
||||
// $Revision: 1.1.1.1 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: aes_key_expand_128.v,v $
|
||||
// Revision 1.1.1.1 2002/11/09 11:22:38 rudi
|
||||
// Initial Checkin
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
`include "timescale.v"
|
||||
|
||||
module aes_key_expand_128(clk, kld, key, wo_0, wo_1, wo_2, wo_3);
|
||||
input clk;
|
||||
input kld;
|
||||
input [127:0] key;
|
||||
output [31:0] wo_0, wo_1, wo_2, wo_3;
|
||||
reg [31:0] w[3:0];
|
||||
wire [31:0] tmp_w;
|
||||
wire [31:0] subword;
|
||||
wire [31:0] rcon;
|
||||
|
||||
assign wo_0 = w[0];
|
||||
assign wo_1 = w[1];
|
||||
assign wo_2 = w[2];
|
||||
assign wo_3 = w[3];
|
||||
always @(posedge clk) w[0] <= #1 kld ? key[127:096] : w[0]^subword^rcon;
|
||||
always @(posedge clk) w[1] <= #1 kld ? key[095:064] : w[0]^w[1]^subword^rcon;
|
||||
always @(posedge clk) w[2] <= #1 kld ? key[063:032] : w[0]^w[2]^w[1]^subword^rcon;
|
||||
always @(posedge clk) w[3] <= #1 kld ? key[031:000] : w[0]^w[3]^w[2]^w[1]^subword^rcon;
|
||||
assign tmp_w = w[3];
|
||||
aes_sbox u0( .a(tmp_w[23:16]), .d(subword[31:24]));
|
||||
aes_sbox u1( .a(tmp_w[15:08]), .d(subword[23:16]));
|
||||
aes_sbox u2( .a(tmp_w[07:00]), .d(subword[15:08]));
|
||||
aes_sbox u3( .a(tmp_w[31:24]), .d(subword[07:00]));
|
||||
aes_rcon r0( .clk(clk), .kld(kld), .out(rcon));
|
||||
endmodule
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// AES RCON Block ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/aes_core/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: aes_rcon.v,v 1.1.1.1 2002/11/09 11:22:38 rudi Exp $
|
||||
//
|
||||
// $Date: 2002/11/09 11:22:38 $
|
||||
// $Revision: 1.1.1.1 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: aes_rcon.v,v $
|
||||
// Revision 1.1.1.1 2002/11/09 11:22:38 rudi
|
||||
// Initial Checkin
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
`include "timescale.v"
|
||||
|
||||
module aes_rcon(clk, kld, out);
|
||||
input clk;
|
||||
input kld;
|
||||
output [31:0] out;
|
||||
reg [31:0] out;
|
||||
reg [3:0] rcnt;
|
||||
wire [3:0] rcnt_next;
|
||||
|
||||
always @(posedge clk)
|
||||
if(kld) out <= #1 32'h01_00_00_00;
|
||||
else out <= #1 frcon(rcnt_next);
|
||||
|
||||
assign rcnt_next = rcnt + 4'h1;
|
||||
always @(posedge clk)
|
||||
if(kld) rcnt <= #1 4'h0;
|
||||
else rcnt <= #1 rcnt_next;
|
||||
|
||||
function [31:0] frcon;
|
||||
input [3:0] i;
|
||||
case(i) // synopsys parallel_case
|
||||
4'h0: frcon=32'h01_00_00_00;
|
||||
4'h1: frcon=32'h02_00_00_00;
|
||||
4'h2: frcon=32'h04_00_00_00;
|
||||
4'h3: frcon=32'h08_00_00_00;
|
||||
4'h4: frcon=32'h10_00_00_00;
|
||||
4'h5: frcon=32'h20_00_00_00;
|
||||
4'h6: frcon=32'h40_00_00_00;
|
||||
4'h7: frcon=32'h80_00_00_00;
|
||||
4'h8: frcon=32'h1b_00_00_00;
|
||||
4'h9: frcon=32'h36_00_00_00;
|
||||
default: frcon=32'h00_00_00_00;
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
endmodule
|
|
@ -1,329 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// AES SBOX (ROM) ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/aes_core/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: aes_sbox.v,v 1.1.1.1 2002/11/09 11:22:38 rudi Exp $
|
||||
//
|
||||
// $Date: 2002/11/09 11:22:38 $
|
||||
// $Revision: 1.1.1.1 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: aes_sbox.v,v $
|
||||
// Revision 1.1.1.1 2002/11/09 11:22:38 rudi
|
||||
// Initial Checkin
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
`include "timescale.v"
|
||||
|
||||
module aes_sbox(a,d);
|
||||
input [7:0] a;
|
||||
output [7:0] d;
|
||||
reg [7:0] d;
|
||||
|
||||
always @(a)
|
||||
case(a) // synopsys full_case parallel_case
|
||||
8'h00: d=8'h63;
|
||||
8'h01: d=8'h7c;
|
||||
8'h02: d=8'h77;
|
||||
8'h03: d=8'h7b;
|
||||
8'h04: d=8'hf2;
|
||||
8'h05: d=8'h6b;
|
||||
8'h06: d=8'h6f;
|
||||
8'h07: d=8'hc5;
|
||||
8'h08: d=8'h30;
|
||||
8'h09: d=8'h01;
|
||||
8'h0a: d=8'h67;
|
||||
8'h0b: d=8'h2b;
|
||||
8'h0c: d=8'hfe;
|
||||
8'h0d: d=8'hd7;
|
||||
8'h0e: d=8'hab;
|
||||
8'h0f: d=8'h76;
|
||||
8'h10: d=8'hca;
|
||||
8'h11: d=8'h82;
|
||||
8'h12: d=8'hc9;
|
||||
8'h13: d=8'h7d;
|
||||
8'h14: d=8'hfa;
|
||||
8'h15: d=8'h59;
|
||||
8'h16: d=8'h47;
|
||||
8'h17: d=8'hf0;
|
||||
8'h18: d=8'had;
|
||||
8'h19: d=8'hd4;
|
||||
8'h1a: d=8'ha2;
|
||||
8'h1b: d=8'haf;
|
||||
8'h1c: d=8'h9c;
|
||||
8'h1d: d=8'ha4;
|
||||
8'h1e: d=8'h72;
|
||||
8'h1f: d=8'hc0;
|
||||
8'h20: d=8'hb7;
|
||||
8'h21: d=8'hfd;
|
||||
8'h22: d=8'h93;
|
||||
8'h23: d=8'h26;
|
||||
8'h24: d=8'h36;
|
||||
8'h25: d=8'h3f;
|
||||
8'h26: d=8'hf7;
|
||||
8'h27: d=8'hcc;
|
||||
8'h28: d=8'h34;
|
||||
8'h29: d=8'ha5;
|
||||
8'h2a: d=8'he5;
|
||||
8'h2b: d=8'hf1;
|
||||
8'h2c: d=8'h71;
|
||||
8'h2d: d=8'hd8;
|
||||
8'h2e: d=8'h31;
|
||||
8'h2f: d=8'h15;
|
||||
8'h30: d=8'h04;
|
||||
8'h31: d=8'hc7;
|
||||
8'h32: d=8'h23;
|
||||
8'h33: d=8'hc3;
|
||||
8'h34: d=8'h18;
|
||||
8'h35: d=8'h96;
|
||||
8'h36: d=8'h05;
|
||||
8'h37: d=8'h9a;
|
||||
8'h38: d=8'h07;
|
||||
8'h39: d=8'h12;
|
||||
8'h3a: d=8'h80;
|
||||
8'h3b: d=8'he2;
|
||||
8'h3c: d=8'heb;
|
||||
8'h3d: d=8'h27;
|
||||
8'h3e: d=8'hb2;
|
||||
8'h3f: d=8'h75;
|
||||
8'h40: d=8'h09;
|
||||
8'h41: d=8'h83;
|
||||
8'h42: d=8'h2c;
|
||||
8'h43: d=8'h1a;
|
||||
8'h44: d=8'h1b;
|
||||
8'h45: d=8'h6e;
|
||||
8'h46: d=8'h5a;
|
||||
8'h47: d=8'ha0;
|
||||
8'h48: d=8'h52;
|
||||
8'h49: d=8'h3b;
|
||||
8'h4a: d=8'hd6;
|
||||
8'h4b: d=8'hb3;
|
||||
8'h4c: d=8'h29;
|
||||
8'h4d: d=8'he3;
|
||||
8'h4e: d=8'h2f;
|
||||
8'h4f: d=8'h84;
|
||||
8'h50: d=8'h53;
|
||||
8'h51: d=8'hd1;
|
||||
8'h52: d=8'h00;
|
||||
8'h53: d=8'hed;
|
||||
8'h54: d=8'h20;
|
||||
8'h55: d=8'hfc;
|
||||
8'h56: d=8'hb1;
|
||||
8'h57: d=8'h5b;
|
||||
8'h58: d=8'h6a;
|
||||
8'h59: d=8'hcb;
|
||||
8'h5a: d=8'hbe;
|
||||
8'h5b: d=8'h39;
|
||||
8'h5c: d=8'h4a;
|
||||
8'h5d: d=8'h4c;
|
||||
8'h5e: d=8'h58;
|
||||
8'h5f: d=8'hcf;
|
||||
8'h60: d=8'hd0;
|
||||
8'h61: d=8'hef;
|
||||
8'h62: d=8'haa;
|
||||
8'h63: d=8'hfb;
|
||||
8'h64: d=8'h43;
|
||||
8'h65: d=8'h4d;
|
||||
8'h66: d=8'h33;
|
||||
8'h67: d=8'h85;
|
||||
8'h68: d=8'h45;
|
||||
8'h69: d=8'hf9;
|
||||
8'h6a: d=8'h02;
|
||||
8'h6b: d=8'h7f;
|
||||
8'h6c: d=8'h50;
|
||||
8'h6d: d=8'h3c;
|
||||
8'h6e: d=8'h9f;
|
||||
8'h6f: d=8'ha8;
|
||||
8'h70: d=8'h51;
|
||||
8'h71: d=8'ha3;
|
||||
8'h72: d=8'h40;
|
||||
8'h73: d=8'h8f;
|
||||
8'h74: d=8'h92;
|
||||
8'h75: d=8'h9d;
|
||||
8'h76: d=8'h38;
|
||||
8'h77: d=8'hf5;
|
||||
8'h78: d=8'hbc;
|
||||
8'h79: d=8'hb6;
|
||||
8'h7a: d=8'hda;
|
||||
8'h7b: d=8'h21;
|
||||
8'h7c: d=8'h10;
|
||||
8'h7d: d=8'hff;
|
||||
8'h7e: d=8'hf3;
|
||||
8'h7f: d=8'hd2;
|
||||
8'h80: d=8'hcd;
|
||||
8'h81: d=8'h0c;
|
||||
8'h82: d=8'h13;
|
||||
8'h83: d=8'hec;
|
||||
8'h84: d=8'h5f;
|
||||
8'h85: d=8'h97;
|
||||
8'h86: d=8'h44;
|
||||
8'h87: d=8'h17;
|
||||
8'h88: d=8'hc4;
|
||||
8'h89: d=8'ha7;
|
||||
8'h8a: d=8'h7e;
|
||||
8'h8b: d=8'h3d;
|
||||
8'h8c: d=8'h64;
|
||||
8'h8d: d=8'h5d;
|
||||
8'h8e: d=8'h19;
|
||||
8'h8f: d=8'h73;
|
||||
8'h90: d=8'h60;
|
||||
8'h91: d=8'h81;
|
||||
8'h92: d=8'h4f;
|
||||
8'h93: d=8'hdc;
|
||||
8'h94: d=8'h22;
|
||||
8'h95: d=8'h2a;
|
||||
8'h96: d=8'h90;
|
||||
8'h97: d=8'h88;
|
||||
8'h98: d=8'h46;
|
||||
8'h99: d=8'hee;
|
||||
8'h9a: d=8'hb8;
|
||||
8'h9b: d=8'h14;
|
||||
8'h9c: d=8'hde;
|
||||
8'h9d: d=8'h5e;
|
||||
8'h9e: d=8'h0b;
|
||||
8'h9f: d=8'hdb;
|
||||
8'ha0: d=8'he0;
|
||||
8'ha1: d=8'h32;
|
||||
8'ha2: d=8'h3a;
|
||||
8'ha3: d=8'h0a;
|
||||
8'ha4: d=8'h49;
|
||||
8'ha5: d=8'h06;
|
||||
8'ha6: d=8'h24;
|
||||
8'ha7: d=8'h5c;
|
||||
8'ha8: d=8'hc2;
|
||||
8'ha9: d=8'hd3;
|
||||
8'haa: d=8'hac;
|
||||
8'hab: d=8'h62;
|
||||
8'hac: d=8'h91;
|
||||
8'had: d=8'h95;
|
||||
8'hae: d=8'he4;
|
||||
8'haf: d=8'h79;
|
||||
8'hb0: d=8'he7;
|
||||
8'hb1: d=8'hc8;
|
||||
8'hb2: d=8'h37;
|
||||
8'hb3: d=8'h6d;
|
||||
8'hb4: d=8'h8d;
|
||||
8'hb5: d=8'hd5;
|
||||
8'hb6: d=8'h4e;
|
||||
8'hb7: d=8'ha9;
|
||||
8'hb8: d=8'h6c;
|
||||
8'hb9: d=8'h56;
|
||||
8'hba: d=8'hf4;
|
||||
8'hbb: d=8'hea;
|
||||
8'hbc: d=8'h65;
|
||||
8'hbd: d=8'h7a;
|
||||
8'hbe: d=8'hae;
|
||||
8'hbf: d=8'h08;
|
||||
8'hc0: d=8'hba;
|
||||
8'hc1: d=8'h78;
|
||||
8'hc2: d=8'h25;
|
||||
8'hc3: d=8'h2e;
|
||||
8'hc4: d=8'h1c;
|
||||
8'hc5: d=8'ha6;
|
||||
8'hc6: d=8'hb4;
|
||||
8'hc7: d=8'hc6;
|
||||
8'hc8: d=8'he8;
|
||||
8'hc9: d=8'hdd;
|
||||
8'hca: d=8'h74;
|
||||
8'hcb: d=8'h1f;
|
||||
8'hcc: d=8'h4b;
|
||||
8'hcd: d=8'hbd;
|
||||
8'hce: d=8'h8b;
|
||||
8'hcf: d=8'h8a;
|
||||
8'hd0: d=8'h70;
|
||||
8'hd1: d=8'h3e;
|
||||
8'hd2: d=8'hb5;
|
||||
8'hd3: d=8'h66;
|
||||
8'hd4: d=8'h48;
|
||||
8'hd5: d=8'h03;
|
||||
8'hd6: d=8'hf6;
|
||||
8'hd7: d=8'h0e;
|
||||
8'hd8: d=8'h61;
|
||||
8'hd9: d=8'h35;
|
||||
8'hda: d=8'h57;
|
||||
8'hdb: d=8'hb9;
|
||||
8'hdc: d=8'h86;
|
||||
8'hdd: d=8'hc1;
|
||||
8'hde: d=8'h1d;
|
||||
8'hdf: d=8'h9e;
|
||||
8'he0: d=8'he1;
|
||||
8'he1: d=8'hf8;
|
||||
8'he2: d=8'h98;
|
||||
8'he3: d=8'h11;
|
||||
8'he4: d=8'h69;
|
||||
8'he5: d=8'hd9;
|
||||
8'he6: d=8'h8e;
|
||||
8'he7: d=8'h94;
|
||||
8'he8: d=8'h9b;
|
||||
8'he9: d=8'h1e;
|
||||
8'hea: d=8'h87;
|
||||
8'heb: d=8'he9;
|
||||
8'hec: d=8'hce;
|
||||
8'hed: d=8'h55;
|
||||
8'hee: d=8'h28;
|
||||
8'hef: d=8'hdf;
|
||||
8'hf0: d=8'h8c;
|
||||
8'hf1: d=8'ha1;
|
||||
8'hf2: d=8'h89;
|
||||
8'hf3: d=8'h0d;
|
||||
8'hf4: d=8'hbf;
|
||||
8'hf5: d=8'he6;
|
||||
8'hf6: d=8'h42;
|
||||
8'hf7: d=8'h68;
|
||||
8'hf8: d=8'h41;
|
||||
8'hf9: d=8'h99;
|
||||
8'hfa: d=8'h2d;
|
||||
8'hfb: d=8'h0f;
|
||||
8'hfc: d=8'hb0;
|
||||
8'hfd: d=8'h54;
|
||||
8'hfe: d=8'hbb;
|
||||
8'hff: d=8'h16;
|
||||
endcase
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -1 +0,0 @@
|
|||
`timescale 1ns / 10ps
|
|
@ -1,153 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// EXCEPT ////
|
||||
//// Floating Point Exception/Special Numbers Unit ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000 Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
`timescale 1ns / 100ps
|
||||
|
||||
|
||||
module except( clk, opa, opb, inf, ind, qnan, snan, opa_nan, opb_nan,
|
||||
opa_00, opb_00, opa_inf, opb_inf, opa_dn, opb_dn);
|
||||
input clk;
|
||||
input [31:0] opa, opb;
|
||||
output inf, ind, qnan, snan, opa_nan, opb_nan;
|
||||
output opa_00, opb_00;
|
||||
output opa_inf, opb_inf;
|
||||
output opa_dn;
|
||||
output opb_dn;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and registers
|
||||
//
|
||||
|
||||
wire [7:0] expa, expb; // alias to opX exponent
|
||||
wire [22:0] fracta, fractb; // alias to opX fraction
|
||||
reg expa_ff, infa_f_r, qnan_r_a, snan_r_a;
|
||||
reg expb_ff, infb_f_r, qnan_r_b, snan_r_b;
|
||||
reg inf, ind, qnan, snan; // Output registers
|
||||
reg opa_nan, opb_nan;
|
||||
reg expa_00, expb_00, fracta_00, fractb_00;
|
||||
reg opa_00, opb_00;
|
||||
reg opa_inf, opb_inf;
|
||||
reg opa_dn, opb_dn;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Aliases
|
||||
//
|
||||
|
||||
assign expa = opa[30:23];
|
||||
assign expb = opb[30:23];
|
||||
assign fracta = opa[22:0];
|
||||
assign fractb = opb[22:0];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Determine if any of the input operators is a INF or NAN or any other special number
|
||||
//
|
||||
|
||||
always @(posedge clk)
|
||||
expa_ff <= #1 &expa;
|
||||
|
||||
always @(posedge clk)
|
||||
expb_ff <= #1 &expb;
|
||||
|
||||
always @(posedge clk)
|
||||
infa_f_r <= #1 !(|fracta);
|
||||
|
||||
always @(posedge clk)
|
||||
infb_f_r <= #1 !(|fractb);
|
||||
|
||||
always @(posedge clk)
|
||||
qnan_r_a <= #1 fracta[22];
|
||||
|
||||
always @(posedge clk)
|
||||
snan_r_a <= #1 !fracta[22] & |fracta[21:0];
|
||||
|
||||
always @(posedge clk)
|
||||
qnan_r_b <= #1 fractb[22];
|
||||
|
||||
always @(posedge clk)
|
||||
snan_r_b <= #1 !fractb[22] & |fractb[21:0];
|
||||
|
||||
always @(posedge clk)
|
||||
ind <= #1 (expa_ff & infa_f_r) & (expb_ff & infb_f_r);
|
||||
|
||||
always @(posedge clk)
|
||||
inf <= #1 (expa_ff & infa_f_r) | (expb_ff & infb_f_r);
|
||||
|
||||
always @(posedge clk)
|
||||
qnan <= #1 (expa_ff & qnan_r_a) | (expb_ff & qnan_r_b);
|
||||
|
||||
always @(posedge clk)
|
||||
snan <= #1 (expa_ff & snan_r_a) | (expb_ff & snan_r_b);
|
||||
|
||||
always @(posedge clk)
|
||||
opa_nan <= #1 &expa & (|fracta[22:0]);
|
||||
|
||||
always @(posedge clk)
|
||||
opb_nan <= #1 &expb & (|fractb[22:0]);
|
||||
|
||||
always @(posedge clk)
|
||||
opa_inf <= #1 (expa_ff & infa_f_r);
|
||||
|
||||
always @(posedge clk)
|
||||
opb_inf <= #1 (expb_ff & infb_f_r);
|
||||
|
||||
always @(posedge clk)
|
||||
expa_00 <= #1 !(|expa);
|
||||
|
||||
always @(posedge clk)
|
||||
expb_00 <= #1 !(|expb);
|
||||
|
||||
always @(posedge clk)
|
||||
fracta_00 <= #1 !(|fracta);
|
||||
|
||||
always @(posedge clk)
|
||||
fractb_00 <= #1 !(|fractb);
|
||||
|
||||
always @(posedge clk)
|
||||
opa_00 <= #1 expa_00 & fracta_00;
|
||||
|
||||
always @(posedge clk)
|
||||
opb_00 <= #1 expb_00 & fractb_00;
|
||||
|
||||
always @(posedge clk)
|
||||
opa_dn <= #1 expa_00;
|
||||
|
||||
always @(posedge clk)
|
||||
opb_dn <= #1 expb_00;
|
||||
|
||||
endmodule
|
||||
|
|
@ -1,560 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// FPU ////
|
||||
//// Floating Point Unit (Single precision) ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000 Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
`timescale 1ns / 100ps
|
||||
|
||||
/*
|
||||
|
||||
FPU Operations (fpu_op):
|
||||
========================
|
||||
|
||||
0 = add
|
||||
1 = sub
|
||||
2 = mul
|
||||
3 = div
|
||||
4 =
|
||||
5 =
|
||||
6 =
|
||||
7 =
|
||||
|
||||
Rounding Modes (rmode):
|
||||
=======================
|
||||
|
||||
0 = round_nearest_even
|
||||
1 = round_to_zero
|
||||
2 = round_up
|
||||
3 = round_down
|
||||
|
||||
*/
|
||||
|
||||
|
||||
module fpu( clk, rmode, fpu_op, opa, opb, out, inf, snan, qnan, ine, overflow, underflow, zero, div_by_zero);
|
||||
input clk;
|
||||
input [1:0] rmode;
|
||||
input [2:0] fpu_op;
|
||||
input [31:0] opa, opb;
|
||||
output [31:0] out;
|
||||
output inf, snan, qnan;
|
||||
output ine;
|
||||
output overflow, underflow;
|
||||
output zero;
|
||||
output div_by_zero;
|
||||
|
||||
parameter INF = 31'h7f800000,
|
||||
QNAN = 31'h7fc00001,
|
||||
SNAN = 31'h7f800001;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires
|
||||
//
|
||||
reg zero;
|
||||
reg [31:0] opa_r, opb_r; // Input operand registers
|
||||
reg [31:0] out; // Output register
|
||||
reg div_by_zero; // Divide by zero output register
|
||||
wire signa, signb; // alias to opX sign
|
||||
wire sign_fasu; // sign output
|
||||
wire [26:0] fracta, fractb; // Fraction Outputs from EQU block
|
||||
wire [7:0] exp_fasu; // Exponent output from EQU block
|
||||
reg [7:0] exp_r; // Exponent output (registerd)
|
||||
wire [26:0] fract_out_d; // fraction output
|
||||
wire co; // carry output
|
||||
reg [27:0] fract_out_q; // fraction output (registerd)
|
||||
wire [30:0] out_d; // Intermediate final result output
|
||||
wire overflow_d, underflow_d;// Overflow/Underflow Indicators
|
||||
reg overflow, underflow; // Output registers for Overflow & Underflow
|
||||
reg inf, snan, qnan; // Output Registers for INF, SNAN and QNAN
|
||||
reg ine; // Output Registers for INE
|
||||
reg [1:0] rmode_r1, rmode_r2, // Pipeline registers for rounding mode
|
||||
rmode_r3;
|
||||
reg [2:0] fpu_op_r1, fpu_op_r2, // Pipeline registers for fp opration
|
||||
fpu_op_r3;
|
||||
wire mul_inf, div_inf;
|
||||
wire mul_00, div_00;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Input Registers
|
||||
//
|
||||
|
||||
always @(posedge clk)
|
||||
opa_r <= #1 opa;
|
||||
|
||||
always @(posedge clk)
|
||||
opb_r <= #1 opb;
|
||||
|
||||
always @(posedge clk)
|
||||
rmode_r1 <= #1 rmode;
|
||||
|
||||
always @(posedge clk)
|
||||
rmode_r2 <= #1 rmode_r1;
|
||||
|
||||
always @(posedge clk)
|
||||
rmode_r3 <= #1 rmode_r2;
|
||||
|
||||
always @(posedge clk)
|
||||
fpu_op_r1 <= #1 fpu_op;
|
||||
|
||||
always @(posedge clk)
|
||||
fpu_op_r2 <= #1 fpu_op_r1;
|
||||
|
||||
always @(posedge clk)
|
||||
fpu_op_r3 <= #1 fpu_op_r2;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Exceptions block
|
||||
//
|
||||
wire inf_d, ind_d, qnan_d, snan_d, opa_nan, opb_nan;
|
||||
wire opa_00, opb_00;
|
||||
wire opa_inf, opb_inf;
|
||||
wire opa_dn, opb_dn;
|
||||
|
||||
except u0( .clk(clk),
|
||||
.opa(opa_r), .opb(opb_r),
|
||||
.inf(inf_d), .ind(ind_d),
|
||||
.qnan(qnan_d), .snan(snan_d),
|
||||
.opa_nan(opa_nan), .opb_nan(opb_nan),
|
||||
.opa_00(opa_00), .opb_00(opb_00),
|
||||
.opa_inf(opa_inf), .opb_inf(opb_inf),
|
||||
.opa_dn(opa_dn), .opb_dn(opb_dn)
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Pre-Normalize block
|
||||
// - Adjusts the numbers to equal exponents and sorts them
|
||||
// - determine result sign
|
||||
// - determine actual operation to perform (add or sub)
|
||||
//
|
||||
|
||||
wire nan_sign_d, result_zero_sign_d;
|
||||
reg sign_fasu_r;
|
||||
wire [7:0] exp_mul;
|
||||
wire sign_mul;
|
||||
reg sign_mul_r;
|
||||
wire [23:0] fracta_mul, fractb_mul;
|
||||
wire inf_mul;
|
||||
reg inf_mul_r;
|
||||
wire [1:0] exp_ovf;
|
||||
reg [1:0] exp_ovf_r;
|
||||
wire sign_exe;
|
||||
reg sign_exe_r;
|
||||
wire [2:0] underflow_fmul_d;
|
||||
|
||||
|
||||
pre_norm u1(.clk(clk), // System Clock
|
||||
.rmode(rmode_r2), // Roundin Mode
|
||||
.add(!fpu_op_r1[0]), // Add/Sub Input
|
||||
.opa(opa_r), .opb(opb_r), // Registered OP Inputs
|
||||
.opa_nan(opa_nan), // OpA is a NAN indicator
|
||||
.opb_nan(opb_nan), // OpB is a NAN indicator
|
||||
.fracta_out(fracta), // Equalized and sorted fraction
|
||||
.fractb_out(fractb), // outputs (Registered)
|
||||
.exp_dn_out(exp_fasu), // Selected exponent output (registered);
|
||||
.sign(sign_fasu), // Encoded output Sign (registered)
|
||||
.nan_sign(nan_sign_d), // Output Sign for NANs (registered)
|
||||
.result_zero_sign(result_zero_sign_d), // Output Sign for zero result (registered)
|
||||
.fasu_op(fasu_op) // Actual fasu operation output (registered)
|
||||
);
|
||||
|
||||
always @(posedge clk)
|
||||
sign_fasu_r <= #1 sign_fasu;
|
||||
|
||||
pre_norm_fmul u2(
|
||||
.clk(clk),
|
||||
.fpu_op(fpu_op_r1),
|
||||
.opa(opa_r), .opb(opb_r),
|
||||
.fracta(fracta_mul),
|
||||
.fractb(fractb_mul),
|
||||
.exp_out(exp_mul), // FMUL exponent output (registered)
|
||||
.sign(sign_mul), // FMUL sign output (registered)
|
||||
.sign_exe(sign_exe), // FMUL exception sign output (registered)
|
||||
.inf(inf_mul), // FMUL inf output (registered)
|
||||
.exp_ovf(exp_ovf), // FMUL exponnent overflow output (registered)
|
||||
.underflow(underflow_fmul_d)
|
||||
);
|
||||
|
||||
|
||||
always @(posedge clk)
|
||||
sign_mul_r <= #1 sign_mul;
|
||||
|
||||
always @(posedge clk)
|
||||
sign_exe_r <= #1 sign_exe;
|
||||
|
||||
always @(posedge clk)
|
||||
inf_mul_r <= #1 inf_mul;
|
||||
|
||||
always @(posedge clk)
|
||||
exp_ovf_r <= #1 exp_ovf;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Add/Sub
|
||||
//
|
||||
|
||||
add_sub27 u3(
|
||||
.add(fasu_op), // Add/Sub
|
||||
.opa(fracta), // Fraction A input
|
||||
.opb(fractb), // Fraction B Input
|
||||
.sum(fract_out_d), // SUM output
|
||||
.co(co_d) ); // Carry Output
|
||||
|
||||
always @(posedge clk)
|
||||
fract_out_q <= #1 {co_d, fract_out_d};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Mul
|
||||
//
|
||||
wire [47:0] prod;
|
||||
|
||||
mul_r2 u5(.clk(clk), .opa(fracta_mul), .opb(fractb_mul), .prod(prod));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Divide
|
||||
//
|
||||
wire [49:0] quo;
|
||||
wire [49:0] fdiv_opa;
|
||||
wire [49:0] remainder;
|
||||
wire remainder_00;
|
||||
reg [4:0] div_opa_ldz_d, div_opa_ldz_r1, div_opa_ldz_r2;
|
||||
|
||||
always @(fracta_mul)
|
||||
casex(fracta_mul[22:0])
|
||||
23'b1??????????????????????: div_opa_ldz_d = 1;
|
||||
23'b01?????????????????????: div_opa_ldz_d = 2;
|
||||
23'b001????????????????????: div_opa_ldz_d = 3;
|
||||
23'b0001???????????????????: div_opa_ldz_d = 4;
|
||||
23'b00001??????????????????: div_opa_ldz_d = 5;
|
||||
23'b000001?????????????????: div_opa_ldz_d = 6;
|
||||
23'b0000001????????????????: div_opa_ldz_d = 7;
|
||||
23'b00000001???????????????: div_opa_ldz_d = 8;
|
||||
23'b000000001??????????????: div_opa_ldz_d = 9;
|
||||
23'b0000000001?????????????: div_opa_ldz_d = 10;
|
||||
23'b00000000001????????????: div_opa_ldz_d = 11;
|
||||
23'b000000000001???????????: div_opa_ldz_d = 12;
|
||||
23'b0000000000001??????????: div_opa_ldz_d = 13;
|
||||
23'b00000000000001?????????: div_opa_ldz_d = 14;
|
||||
23'b000000000000001????????: div_opa_ldz_d = 15;
|
||||
23'b0000000000000001???????: div_opa_ldz_d = 16;
|
||||
23'b00000000000000001??????: div_opa_ldz_d = 17;
|
||||
23'b000000000000000001?????: div_opa_ldz_d = 18;
|
||||
23'b0000000000000000001????: div_opa_ldz_d = 19;
|
||||
23'b00000000000000000001???: div_opa_ldz_d = 20;
|
||||
23'b000000000000000000001??: div_opa_ldz_d = 21;
|
||||
23'b0000000000000000000001?: div_opa_ldz_d = 22;
|
||||
23'b0000000000000000000000?: div_opa_ldz_d = 23;
|
||||
endcase
|
||||
|
||||
assign fdiv_opa = !(|opa_r[30:23]) ? {(fracta_mul<<div_opa_ldz_d), 26'h0} : {fracta_mul, 26'h0};
|
||||
|
||||
|
||||
div_r2 u6(.clk(clk), .opa(fdiv_opa), .opb(fractb_mul), .quo(quo), .rem(remainder));
|
||||
|
||||
assign remainder_00 = !(|remainder);
|
||||
|
||||
always @(posedge clk)
|
||||
div_opa_ldz_r1 <= #1 div_opa_ldz_d;
|
||||
|
||||
always @(posedge clk)
|
||||
div_opa_ldz_r2 <= #1 div_opa_ldz_r1;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Normalize Result
|
||||
//
|
||||
wire ine_d;
|
||||
reg [47:0] fract_denorm;
|
||||
wire [47:0] fract_div;
|
||||
wire sign_d;
|
||||
reg sign;
|
||||
reg [30:0] opa_r1;
|
||||
reg [47:0] fract_i2f;
|
||||
reg opas_r1, opas_r2;
|
||||
wire f2i_out_sign;
|
||||
|
||||
always @(posedge clk) // Exponent must be once cycle delayed
|
||||
case(fpu_op_r2)
|
||||
0,1: exp_r <= #1 exp_fasu;
|
||||
2,3: exp_r <= #1 exp_mul;
|
||||
4: exp_r <= #1 0;
|
||||
5: exp_r <= #1 opa_r1[30:23];
|
||||
endcase
|
||||
|
||||
assign fract_div = (opb_dn ? quo[49:2] : {quo[26:0], 21'h0});
|
||||
|
||||
always @(posedge clk)
|
||||
opa_r1 <= #1 opa_r[30:0];
|
||||
|
||||
always @(posedge clk)
|
||||
fract_i2f <= #1 (fpu_op_r2==5) ?
|
||||
(sign_d ? 1-{24'h00, (|opa_r1[30:23]), opa_r1[22:0]}-1 : {24'h0, (|opa_r1[30:23]), opa_r1[22:0]}) :
|
||||
(sign_d ? 1 - {opa_r1, 17'h01} : {opa_r1, 17'h0});
|
||||
|
||||
always @(fpu_op_r3 or fract_out_q or prod or fract_div or fract_i2f)
|
||||
case(fpu_op_r3)
|
||||
0,1: fract_denorm = {fract_out_q, 20'h0};
|
||||
2: fract_denorm = prod;
|
||||
3: fract_denorm = fract_div;
|
||||
4,5: fract_denorm = fract_i2f;
|
||||
endcase
|
||||
|
||||
|
||||
always @(posedge clk)
|
||||
opas_r1 <= #1 opa_r[31];
|
||||
|
||||
always @(posedge clk)
|
||||
opas_r2 <= #1 opas_r1;
|
||||
|
||||
assign sign_d = fpu_op_r2[1] ? sign_mul : sign_fasu;
|
||||
|
||||
always @(posedge clk)
|
||||
sign <= #1 (rmode_r2==2'h3) ? !sign_d : sign_d;
|
||||
|
||||
post_norm u4(.clk(clk), // System Clock
|
||||
.fpu_op(fpu_op_r3), // Floating Point Operation
|
||||
.opas(opas_r2), // OPA Sign
|
||||
.sign(sign), // Sign of the result
|
||||
.rmode(rmode_r3), // Rounding mode
|
||||
.fract_in(fract_denorm), // Fraction Input
|
||||
.exp_ovf(exp_ovf_r), // Exponent Overflow
|
||||
.exp_in(exp_r), // Exponent Input
|
||||
.opa_dn(opa_dn), // Operand A Denormalized
|
||||
.opb_dn(opb_dn), // Operand A Denormalized
|
||||
.rem_00(remainder_00), // Diveide Remainder is zero
|
||||
.div_opa_ldz(div_opa_ldz_r2), // Divide opa leading zeros count
|
||||
.output_zero(mul_00 | div_00), // Force output to Zero
|
||||
.out(out_d), // Normalized output (un-registered)
|
||||
.ine(ine_d), // Result Inexact output (un-registered)
|
||||
.overflow(overflow_d), // Overflow output (un-registered)
|
||||
.underflow(underflow_d), // Underflow output (un-registered)
|
||||
.f2i_out_sign(f2i_out_sign) // F2I Output Sign
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FPU Outputs
|
||||
//
|
||||
reg fasu_op_r1, fasu_op_r2;
|
||||
wire [30:0] out_fixed;
|
||||
wire output_zero_fasu;
|
||||
wire output_zero_fdiv;
|
||||
wire output_zero_fmul;
|
||||
reg inf_mul2;
|
||||
wire overflow_fasu;
|
||||
wire overflow_fmul;
|
||||
wire overflow_fdiv;
|
||||
wire inf_fmul;
|
||||
wire sign_mul_final;
|
||||
wire out_d_00;
|
||||
wire sign_div_final;
|
||||
wire ine_mul, ine_mula, ine_div, ine_fasu;
|
||||
wire underflow_fasu, underflow_fmul, underflow_fdiv;
|
||||
wire underflow_fmul1;
|
||||
reg [2:0] underflow_fmul_r;
|
||||
reg opa_nan_r;
|
||||
|
||||
|
||||
always @(posedge clk)
|
||||
fasu_op_r1 <= #1 fasu_op;
|
||||
|
||||
always @(posedge clk)
|
||||
fasu_op_r2 <= #1 fasu_op_r1;
|
||||
|
||||
always @(posedge clk)
|
||||
inf_mul2 <= #1 exp_mul == 8'hff;
|
||||
|
||||
|
||||
// Force pre-set values for non numerical output
|
||||
assign mul_inf = (fpu_op_r3==3'b010) & (inf_mul_r | inf_mul2) & (rmode_r3==2'h0);
|
||||
assign div_inf = (fpu_op_r3==3'b011) & (opb_00 | opa_inf);
|
||||
|
||||
assign mul_00 = (fpu_op_r3==3'b010) & (opa_00 | opb_00);
|
||||
assign div_00 = (fpu_op_r3==3'b011) & (opa_00 | opb_inf);
|
||||
|
||||
assign out_fixed = ( (qnan_d | snan_d) |
|
||||
(ind_d & !fasu_op_r2) |
|
||||
((fpu_op_r3==3'b011) & opb_00 & opa_00) |
|
||||
(((opa_inf & opb_00) | (opb_inf & opa_00 )) & fpu_op_r3==3'b010)
|
||||
) ? QNAN : INF;
|
||||
|
||||
always @(posedge clk)
|
||||
out[30:0] <= #1 (mul_inf | div_inf | (inf_d & (fpu_op_r3!=3'b011) & (fpu_op_r3!=3'b101)) | snan_d | qnan_d) & fpu_op_r3!=3'b100 ? out_fixed :
|
||||
out_d;
|
||||
|
||||
assign out_d_00 = !(|out_d);
|
||||
|
||||
assign sign_mul_final = (sign_exe_r & ((opa_00 & opb_inf) | (opb_00 & opa_inf))) ? !sign_mul_r : sign_mul_r;
|
||||
assign sign_div_final = (sign_exe_r & (opa_inf & opb_inf)) ? !sign_mul_r : sign_mul_r | (opa_00 & opb_00);
|
||||
|
||||
always @(posedge clk)
|
||||
out[31] <= #1 ((fpu_op_r3==3'b101) & out_d_00) ? (f2i_out_sign & !(qnan_d | snan_d) ) :
|
||||
((fpu_op_r3==3'b010) & !(snan_d | qnan_d)) ? sign_mul_final :
|
||||
((fpu_op_r3==3'b011) & !(snan_d | qnan_d)) ? sign_div_final :
|
||||
(snan_d | qnan_d | ind_d) ? nan_sign_d :
|
||||
output_zero_fasu ? result_zero_sign_d :
|
||||
sign_fasu_r;
|
||||
|
||||
// Exception Outputs
|
||||
assign ine_mula = ((inf_mul_r | inf_mul2 | opa_inf | opb_inf) & (rmode_r3==2'h1) &
|
||||
!((opa_inf & opb_00) | (opb_inf & opa_00 )) & fpu_op_r3[1]);
|
||||
|
||||
assign ine_mul = (ine_mula | ine_d | inf_fmul | out_d_00 | overflow_d | underflow_d) &
|
||||
!opa_00 & !opb_00 & !(snan_d | qnan_d | inf_d);
|
||||
assign ine_div = (ine_d | overflow_d | underflow_d) & !(opb_00 | snan_d | qnan_d | inf_d);
|
||||
assign ine_fasu = (ine_d | overflow_d | underflow_d) & !(snan_d | qnan_d | inf_d);
|
||||
|
||||
always @(posedge clk)
|
||||
ine <= #1 fpu_op_r3[2] ? ine_d :
|
||||
!fpu_op_r3[1] ? ine_fasu :
|
||||
fpu_op_r3[0] ? ine_div : ine_mul;
|
||||
|
||||
|
||||
assign overflow_fasu = overflow_d & !(snan_d | qnan_d | inf_d);
|
||||
assign overflow_fmul = !inf_d & (inf_mul_r | inf_mul2 | overflow_d) & !(snan_d | qnan_d);
|
||||
assign overflow_fdiv = (overflow_d & !(opb_00 | inf_d | snan_d | qnan_d));
|
||||
|
||||
always @(posedge clk)
|
||||
overflow <= #1 fpu_op_r3[2] ? 0 :
|
||||
!fpu_op_r3[1] ? overflow_fasu :
|
||||
fpu_op_r3[0] ? overflow_fdiv : overflow_fmul;
|
||||
|
||||
always @(posedge clk)
|
||||
underflow_fmul_r <= #1 underflow_fmul_d;
|
||||
|
||||
|
||||
assign underflow_fmul1 = underflow_fmul_r[0] |
|
||||
(underflow_fmul_r[1] & underflow_d ) |
|
||||
((opa_dn | opb_dn) & out_d_00 & (prod!=0) & sign) |
|
||||
(underflow_fmul_r[2] & ((out_d[30:23]==0) | (out_d[22:0]==0)));
|
||||
|
||||
assign underflow_fasu = underflow_d & !(inf_d | snan_d | qnan_d);
|
||||
assign underflow_fmul = underflow_fmul1 & !(snan_d | qnan_d | inf_mul_r);
|
||||
assign underflow_fdiv = underflow_fasu & !opb_00;
|
||||
|
||||
always @(posedge clk)
|
||||
underflow <= #1 fpu_op_r3[2] ? 0 :
|
||||
!fpu_op_r3[1] ? underflow_fasu :
|
||||
fpu_op_r3[0] ? underflow_fdiv : underflow_fmul;
|
||||
|
||||
always @(posedge clk)
|
||||
snan <= #1 snan_d;
|
||||
|
||||
// synopsys translate_off
|
||||
wire mul_uf_del;
|
||||
wire uf2_del, ufb2_del, ufc2_del, underflow_d_del;
|
||||
wire co_del;
|
||||
wire [30:0] out_d_del;
|
||||
wire ov_fasu_del, ov_fmul_del;
|
||||
wire [2:0] fop;
|
||||
wire [4:0] ldza_del;
|
||||
wire [49:0] quo_del;
|
||||
|
||||
delay1 #0 ud000(clk, underflow_fmul1, mul_uf_del);
|
||||
delay1 #0 ud001(clk, underflow_fmul_r[0], uf2_del);
|
||||
delay1 #0 ud002(clk, underflow_fmul_r[1], ufb2_del);
|
||||
delay1 #0 ud003(clk, underflow_d, underflow_d_del);
|
||||
delay1 #0 ud004(clk, test.u0.u4.exp_out1_co, co_del);
|
||||
delay1 #0 ud005(clk, underflow_fmul_r[2], ufc2_del);
|
||||
delay1 #30 ud006(clk, out_d, out_d_del);
|
||||
|
||||
delay1 #0 ud007(clk, overflow_fasu, ov_fasu_del);
|
||||
delay1 #0 ud008(clk, overflow_fmul, ov_fmul_del);
|
||||
|
||||
delay1 #2 ud009(clk, fpu_op_r3, fop);
|
||||
|
||||
delay3 #4 ud010(clk, div_opa_ldz_d, ldza_del);
|
||||
|
||||
delay1 #49 ud012(clk, quo, quo_del);
|
||||
|
||||
always @(test.error_event)
|
||||
begin
|
||||
#0.2
|
||||
$display("muf: %b uf0: %b uf1: %b uf2: %b, tx0: %b, co: %b, out_d: %h (%h %h), ov_fasu: %b, ov_fmul: %b, fop: %h",
|
||||
mul_uf_del, uf2_del, ufb2_del, ufc2_del, underflow_d_del, co_del, out_d_del, out_d_del[30:23], out_d_del[22:0],
|
||||
ov_fasu_del, ov_fmul_del, fop );
|
||||
$display("ldza: %h, quo: %b",
|
||||
ldza_del, quo_del);
|
||||
end
|
||||
// synopsys translate_on
|
||||
|
||||
|
||||
|
||||
// Status Outputs
|
||||
always @(posedge clk)
|
||||
qnan <= #1 fpu_op_r3[2] ? 0 : (
|
||||
snan_d | qnan_d | (ind_d & !fasu_op_r2) |
|
||||
(opa_00 & opb_00 & fpu_op_r3==3'b011) |
|
||||
(((opa_inf & opb_00) | (opb_inf & opa_00 )) & fpu_op_r3==3'b010)
|
||||
);
|
||||
|
||||
assign inf_fmul = (((inf_mul_r | inf_mul2) & (rmode_r3==2'h0)) | opa_inf | opb_inf) &
|
||||
!((opa_inf & opb_00) | (opb_inf & opa_00 )) &
|
||||
fpu_op_r3==3'b010;
|
||||
|
||||
always @(posedge clk)
|
||||
inf <= #1 fpu_op_r3[2] ? 0 :
|
||||
(!(qnan_d | snan_d) & (
|
||||
((&out_d[30:23]) & !(|out_d[22:0]) & !(opb_00 & fpu_op_r3==3'b011)) |
|
||||
(inf_d & !(ind_d & !fasu_op_r2) & !fpu_op_r3[1]) |
|
||||
inf_fmul |
|
||||
(!opa_00 & opb_00 & fpu_op_r3==3'b011) |
|
||||
(fpu_op_r3==3'b011 & opa_inf & !opb_inf)
|
||||
)
|
||||
);
|
||||
|
||||
assign output_zero_fasu = out_d_00 & !(inf_d | snan_d | qnan_d);
|
||||
assign output_zero_fdiv = (div_00 | (out_d_00 & !opb_00)) & !(opa_inf & opb_inf) &
|
||||
!(opa_00 & opb_00) & !(qnan_d | snan_d);
|
||||
assign output_zero_fmul = (out_d_00 | opa_00 | opb_00) &
|
||||
!(inf_mul_r | inf_mul2 | opa_inf | opb_inf | snan_d | qnan_d) &
|
||||
!(opa_inf & opb_00) & !(opb_inf & opa_00);
|
||||
|
||||
always @(posedge clk)
|
||||
zero <= #1 fpu_op_r3==3'b101 ? out_d_00 & !(snan_d | qnan_d):
|
||||
fpu_op_r3==3'b011 ? output_zero_fdiv :
|
||||
fpu_op_r3==3'b010 ? output_zero_fmul :
|
||||
output_zero_fasu ;
|
||||
|
||||
always @(posedge clk)
|
||||
opa_nan_r <= #1 !opa_nan & fpu_op_r2==3'b011;
|
||||
|
||||
always @(posedge clk)
|
||||
div_by_zero <= #1 opa_nan_r & !opa_00 & !opa_inf & opb_00;
|
||||
|
||||
endmodule
|
|
@ -1,676 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Post Norm ////
|
||||
//// Floating Point Post Normalisation Unit ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000 Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
`timescale 1ns / 100ps
|
||||
|
||||
module post_norm( clk, fpu_op, opas, sign, rmode, fract_in, exp_in, exp_ovf,
|
||||
opa_dn, opb_dn, rem_00, div_opa_ldz, output_zero, out,
|
||||
ine, overflow, underflow, f2i_out_sign);
|
||||
input clk;
|
||||
input [2:0] fpu_op;
|
||||
input opas;
|
||||
input sign;
|
||||
input [1:0] rmode;
|
||||
input [47:0] fract_in;
|
||||
input [1:0] exp_ovf;
|
||||
input [7:0] exp_in;
|
||||
input opa_dn, opb_dn;
|
||||
input rem_00;
|
||||
input [4:0] div_opa_ldz;
|
||||
input output_zero;
|
||||
output [30:0] out;
|
||||
output ine;
|
||||
output overflow, underflow;
|
||||
output f2i_out_sign;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and registers
|
||||
//
|
||||
|
||||
wire [22:0] fract_out;
|
||||
wire [7:0] exp_out;
|
||||
wire [30:0] out;
|
||||
wire exp_out1_co, overflow, underflow;
|
||||
wire [22:0] fract_out_final;
|
||||
reg [22:0] fract_out_rnd;
|
||||
wire [8:0] exp_next_mi;
|
||||
wire dn;
|
||||
wire exp_rnd_adj;
|
||||
wire [7:0] exp_out_final;
|
||||
reg [7:0] exp_out_rnd;
|
||||
wire op_dn = opa_dn | opb_dn;
|
||||
wire op_mul = fpu_op[2:0]==3'b010;
|
||||
wire op_div = fpu_op[2:0]==3'b011;
|
||||
wire op_i2f = fpu_op[2:0]==3'b100;
|
||||
wire op_f2i = fpu_op[2:0]==3'b101;
|
||||
reg [5:0] fi_ldz;
|
||||
|
||||
wire g, r, s;
|
||||
wire round, round2, round2a, round2_fasu, round2_fmul;
|
||||
wire [7:0] exp_out_rnd0, exp_out_rnd1, exp_out_rnd2, exp_out_rnd2a;
|
||||
wire [22:0] fract_out_rnd0, fract_out_rnd1, fract_out_rnd2, fract_out_rnd2a;
|
||||
wire exp_rnd_adj0, exp_rnd_adj2a;
|
||||
wire r_sign;
|
||||
wire ovf0, ovf1;
|
||||
wire [23:0] fract_out_pl1;
|
||||
wire [7:0] exp_out_pl1, exp_out_mi1;
|
||||
wire exp_out_00, exp_out_fe, exp_out_ff, exp_in_00, exp_in_ff;
|
||||
wire exp_out_final_ff, fract_out_7fffff;
|
||||
wire [24:0] fract_trunc;
|
||||
wire [7:0] exp_out1;
|
||||
wire grs_sel;
|
||||
wire fract_out_00, fract_in_00;
|
||||
wire shft_co;
|
||||
wire [8:0] exp_in_pl1, exp_in_mi1;
|
||||
wire [47:0] fract_in_shftr;
|
||||
wire [47:0] fract_in_shftl;
|
||||
|
||||
wire [7:0] exp_div;
|
||||
wire [7:0] shft2;
|
||||
wire [7:0] exp_out1_mi1;
|
||||
wire div_dn;
|
||||
wire div_nr;
|
||||
wire grs_sel_div;
|
||||
|
||||
wire div_inf;
|
||||
wire [6:0] fi_ldz_2a;
|
||||
wire [7:0] fi_ldz_2;
|
||||
wire [7:0] div_shft1, div_shft2, div_shft3, div_shft4;
|
||||
wire div_shft1_co;
|
||||
wire [8:0] div_exp1;
|
||||
wire [7:0] div_exp2, div_exp3;
|
||||
wire left_right, lr_mul, lr_div;
|
||||
wire [7:0] shift_right, shftr_mul, shftr_div;
|
||||
wire [7:0] shift_left, shftl_mul, shftl_div;
|
||||
wire [7:0] fasu_shift;
|
||||
wire [7:0] exp_fix_div;
|
||||
|
||||
wire [7:0] exp_fix_diva, exp_fix_divb;
|
||||
wire [5:0] fi_ldz_mi1;
|
||||
wire [5:0] fi_ldz_mi22;
|
||||
wire exp_zero;
|
||||
wire [6:0] ldz_all;
|
||||
wire [7:0] ldz_dif;
|
||||
|
||||
wire [8:0] div_scht1a;
|
||||
wire [7:0] f2i_shft;
|
||||
wire [55:0] exp_f2i_1;
|
||||
wire f2i_zero, f2i_max;
|
||||
wire [7:0] f2i_emin;
|
||||
wire [7:0] conv_shft;
|
||||
wire [7:0] exp_i2f, exp_f2i, conv_exp;
|
||||
wire round2_f2i;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Normalize and Round Logic
|
||||
//
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Count Leading zeros in fraction
|
||||
|
||||
always @(fract_in)
|
||||
casex(fract_in) // synopsys full_case parallel_case
|
||||
48'b1???????????????????????????????????????????????: fi_ldz = 1;
|
||||
48'b01??????????????????????????????????????????????: fi_ldz = 2;
|
||||
48'b001?????????????????????????????????????????????: fi_ldz = 3;
|
||||
48'b0001????????????????????????????????????????????: fi_ldz = 4;
|
||||
48'b00001???????????????????????????????????????????: fi_ldz = 5;
|
||||
48'b000001??????????????????????????????????????????: fi_ldz = 6;
|
||||
48'b0000001?????????????????????????????????????????: fi_ldz = 7;
|
||||
48'b00000001????????????????????????????????????????: fi_ldz = 8;
|
||||
48'b000000001???????????????????????????????????????: fi_ldz = 9;
|
||||
48'b0000000001??????????????????????????????????????: fi_ldz = 10;
|
||||
48'b00000000001?????????????????????????????????????: fi_ldz = 11;
|
||||
48'b000000000001????????????????????????????????????: fi_ldz = 12;
|
||||
48'b0000000000001???????????????????????????????????: fi_ldz = 13;
|
||||
48'b00000000000001??????????????????????????????????: fi_ldz = 14;
|
||||
48'b000000000000001?????????????????????????????????: fi_ldz = 15;
|
||||
48'b0000000000000001????????????????????????????????: fi_ldz = 16;
|
||||
48'b00000000000000001???????????????????????????????: fi_ldz = 17;
|
||||
48'b000000000000000001??????????????????????????????: fi_ldz = 18;
|
||||
48'b0000000000000000001?????????????????????????????: fi_ldz = 19;
|
||||
48'b00000000000000000001????????????????????????????: fi_ldz = 20;
|
||||
48'b000000000000000000001???????????????????????????: fi_ldz = 21;
|
||||
48'b0000000000000000000001??????????????????????????: fi_ldz = 22;
|
||||
48'b00000000000000000000001?????????????????????????: fi_ldz = 23;
|
||||
48'b000000000000000000000001????????????????????????: fi_ldz = 24;
|
||||
48'b0000000000000000000000001???????????????????????: fi_ldz = 25;
|
||||
48'b00000000000000000000000001??????????????????????: fi_ldz = 26;
|
||||
48'b000000000000000000000000001?????????????????????: fi_ldz = 27;
|
||||
48'b0000000000000000000000000001????????????????????: fi_ldz = 28;
|
||||
48'b00000000000000000000000000001???????????????????: fi_ldz = 29;
|
||||
48'b000000000000000000000000000001??????????????????: fi_ldz = 30;
|
||||
48'b0000000000000000000000000000001?????????????????: fi_ldz = 31;
|
||||
48'b00000000000000000000000000000001????????????????: fi_ldz = 32;
|
||||
48'b000000000000000000000000000000001???????????????: fi_ldz = 33;
|
||||
48'b0000000000000000000000000000000001??????????????: fi_ldz = 34;
|
||||
48'b00000000000000000000000000000000001?????????????: fi_ldz = 35;
|
||||
48'b000000000000000000000000000000000001????????????: fi_ldz = 36;
|
||||
48'b0000000000000000000000000000000000001???????????: fi_ldz = 37;
|
||||
48'b00000000000000000000000000000000000001??????????: fi_ldz = 38;
|
||||
48'b000000000000000000000000000000000000001?????????: fi_ldz = 39;
|
||||
48'b0000000000000000000000000000000000000001????????: fi_ldz = 40;
|
||||
48'b00000000000000000000000000000000000000001???????: fi_ldz = 41;
|
||||
48'b000000000000000000000000000000000000000001??????: fi_ldz = 42;
|
||||
48'b0000000000000000000000000000000000000000001?????: fi_ldz = 43;
|
||||
48'b00000000000000000000000000000000000000000001????: fi_ldz = 44;
|
||||
48'b000000000000000000000000000000000000000000001???: fi_ldz = 45;
|
||||
48'b0000000000000000000000000000000000000000000001??: fi_ldz = 46;
|
||||
48'b00000000000000000000000000000000000000000000001?: fi_ldz = 47;
|
||||
48'b00000000000000000000000000000000000000000000000?: fi_ldz = 48;
|
||||
endcase
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Normalize
|
||||
|
||||
wire exp_in_80;
|
||||
wire rmode_00, rmode_01, rmode_10, rmode_11;
|
||||
|
||||
// Misc common signals
|
||||
assign exp_in_ff = &exp_in;
|
||||
assign exp_in_00 = !(|exp_in);
|
||||
assign exp_in_80 = exp_in[7] & !(|exp_in[6:0]);
|
||||
assign exp_out_ff = &exp_out;
|
||||
assign exp_out_00 = !(|exp_out);
|
||||
assign exp_out_fe = &exp_out[7:1] & !exp_out[0];
|
||||
assign exp_out_final_ff = &exp_out_final;
|
||||
|
||||
assign fract_out_7fffff = &fract_out;
|
||||
assign fract_out_00 = !(|fract_out);
|
||||
assign fract_in_00 = !(|fract_in);
|
||||
|
||||
assign rmode_00 = (rmode==2'b00);
|
||||
assign rmode_01 = (rmode==2'b01);
|
||||
assign rmode_10 = (rmode==2'b10);
|
||||
assign rmode_11 = (rmode==2'b11);
|
||||
|
||||
// Fasu Output will be denormalized ...
|
||||
assign dn = !op_mul & !op_div & (exp_in_00 | (exp_next_mi[8] & !fract_in[47]) );
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Fraction Normalization
|
||||
parameter f2i_emax = 8'h9d;
|
||||
|
||||
// Incremented fraction for rounding
|
||||
assign fract_out_pl1 = fract_out + 1;
|
||||
|
||||
// Special Signals for f2i
|
||||
assign f2i_emin = rmode_00 ? 8'h7e : 8'h7f;
|
||||
assign f2i_zero = (!opas & (exp_in<f2i_emin)) | (opas & (exp_in>f2i_emax)) | (opas & (exp_in<f2i_emin) & (fract_in_00 | !rmode_11));
|
||||
assign f2i_max = (!opas & (exp_in>f2i_emax)) | (opas & (exp_in<f2i_emin) & !fract_in_00 & rmode_11);
|
||||
|
||||
// Claculate various shifting options
|
||||
|
||||
assign {shft_co,shftr_mul} = (!exp_ovf[1] & exp_in_00) ? {1'b0, exp_out} : exp_in_mi1 ;
|
||||
assign {div_shft1_co, div_shft1} = exp_in_00 ? {1'b0, div_opa_ldz} : div_scht1a;
|
||||
|
||||
assign div_scht1a = exp_in-div_opa_ldz; // 9 bits - includes carry out
|
||||
assign div_shft2 = exp_in+2;
|
||||
assign div_shft3 = div_opa_ldz+exp_in;
|
||||
assign div_shft4 = div_opa_ldz-exp_in;
|
||||
|
||||
assign div_dn = op_dn & div_shft1_co;
|
||||
assign div_nr = op_dn & exp_ovf[1] & !(|fract_in[46:23]) & (div_shft3>8'h16);
|
||||
|
||||
assign f2i_shft = exp_in-8'h7d;
|
||||
|
||||
// Select shifting direction
|
||||
assign left_right = op_div ? lr_div : op_mul ? lr_mul : 1;
|
||||
|
||||
assign lr_div = (op_dn & !exp_ovf[1] & exp_ovf[0]) ? 1 :
|
||||
(op_dn & exp_ovf[1]) ? 0 :
|
||||
(op_dn & div_shft1_co) ? 0 :
|
||||
(op_dn & exp_out_00) ? 1 :
|
||||
(!op_dn & exp_out_00 & !exp_ovf[1]) ? 1 :
|
||||
exp_ovf[1] ? 0 :
|
||||
1;
|
||||
assign lr_mul = (shft_co | (!exp_ovf[1] & exp_in_00) |
|
||||
(!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00) )) ? 1 :
|
||||
( exp_ovf[1] | exp_in_00 ) ? 0 :
|
||||
1;
|
||||
|
||||
// Select Left and Right shift value
|
||||
assign fasu_shift = (dn | exp_out_00) ? (exp_in_00 ? 8'h2 : exp_in_pl1[7:0]) : {2'h0, fi_ldz};
|
||||
assign shift_right = op_div ? shftr_div : shftr_mul;
|
||||
|
||||
assign conv_shft = op_f2i ? f2i_shft : {2'h0, fi_ldz};
|
||||
|
||||
assign shift_left = op_div ? shftl_div : op_mul ? shftl_mul : (op_f2i | op_i2f) ? conv_shft : fasu_shift;
|
||||
|
||||
assign shftl_mul = (shft_co |
|
||||
(!exp_ovf[1] & exp_in_00) |
|
||||
(!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00))) ? exp_in_pl1[7:0] : {2'h0, fi_ldz};
|
||||
|
||||
assign shftl_div = ( op_dn & exp_out_00 & !(!exp_ovf[1] & exp_ovf[0])) ? div_shft1[7:0] :
|
||||
(!op_dn & exp_out_00 & !exp_ovf[1]) ? exp_in[7:0] :
|
||||
{2'h0, fi_ldz};
|
||||
assign shftr_div = (op_dn & exp_ovf[1]) ? div_shft3 :
|
||||
(op_dn & div_shft1_co) ? div_shft4 :
|
||||
div_shft2;
|
||||
// Do the actual shifting
|
||||
assign fract_in_shftr = (|shift_right[7:6]) ? 0 : fract_in>>shift_right[5:0];
|
||||
assign fract_in_shftl = (|shift_left[7:6] | (f2i_zero & op_f2i)) ? 0 : fract_in<<shift_left[5:0];
|
||||
|
||||
// Chose final fraction output
|
||||
assign {fract_out,fract_trunc} = left_right ? fract_in_shftl : fract_in_shftr;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Exponent Normalization
|
||||
|
||||
assign fi_ldz_mi1 = fi_ldz - 1;
|
||||
assign fi_ldz_mi22 = fi_ldz - 22;
|
||||
assign exp_out_pl1 = exp_out + 1;
|
||||
assign exp_out_mi1 = exp_out - 1;
|
||||
assign exp_in_pl1 = exp_in + 1; // 9 bits - includes carry out
|
||||
assign exp_in_mi1 = exp_in - 1; // 9 bits - includes carry out
|
||||
assign exp_out1_mi1 = exp_out1 - 1;
|
||||
|
||||
assign exp_next_mi = exp_in_pl1 - fi_ldz_mi1; // 9 bits - includes carry out
|
||||
|
||||
assign exp_fix_diva = exp_in - fi_ldz_mi22;
|
||||
assign exp_fix_divb = exp_in - fi_ldz_mi1;
|
||||
|
||||
assign exp_zero = (exp_ovf[1] & !exp_ovf[0] & op_mul & (!exp_rnd_adj2a | !rmode[1])) | (op_mul & exp_out1_co);
|
||||
assign {exp_out1_co, exp_out1} = fract_in[47] ? exp_in_pl1 : exp_next_mi;
|
||||
|
||||
assign f2i_out_sign = !opas ? ((exp_in<f2i_emin) ? 0 : (exp_in>f2i_emax) ? 0 : opas) :
|
||||
((exp_in<f2i_emin) ? 0 : (exp_in>f2i_emax) ? 1 : opas);
|
||||
|
||||
assign exp_i2f = fract_in_00 ? (opas ? 8'h9e : 0) : (8'h9e-fi_ldz);
|
||||
assign exp_f2i_1 = {{8{fract_in[47]}}, fract_in }<<f2i_shft;
|
||||
assign exp_f2i = f2i_zero ? 0 : f2i_max ? 8'hff : exp_f2i_1[55:48];
|
||||
assign conv_exp = op_f2i ? exp_f2i : exp_i2f;
|
||||
|
||||
assign exp_out = op_div ? exp_div : (op_f2i | op_i2f) ? conv_exp : exp_zero ? 8'h0 : dn ? {6'h0, fract_in[47:46]} : exp_out1;
|
||||
|
||||
assign ldz_all = div_opa_ldz + fi_ldz;
|
||||
assign ldz_dif = fi_ldz_2 - div_opa_ldz;
|
||||
assign fi_ldz_2a = 6'd23 - fi_ldz;
|
||||
assign fi_ldz_2 = {fi_ldz_2a[6], fi_ldz_2a[6:0]};
|
||||
|
||||
assign div_exp1 = exp_in_mi1 + fi_ldz_2; // 9 bits - includes carry out
|
||||
|
||||
assign div_exp2 = exp_in_pl1 - ldz_all;
|
||||
assign div_exp3 = exp_in + ldz_dif;
|
||||
|
||||
assign exp_div =(opa_dn & opb_dn) ? div_exp3 :
|
||||
opb_dn ? div_exp1[7:0] :
|
||||
(opa_dn & !( (exp_in<div_opa_ldz) | (div_exp2>9'hfe) )) ? div_exp2 :
|
||||
(opa_dn | (exp_in_00 & !exp_ovf[1]) ) ? 0 :
|
||||
exp_out1_mi1;
|
||||
|
||||
assign div_inf = opb_dn & !opa_dn & (div_exp1[7:0] < 8'h7f);
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Round
|
||||
|
||||
// Extract rounding (GRS) bits
|
||||
assign grs_sel_div = op_div & (exp_ovf[1] | div_dn | exp_out1_co | exp_out_00);
|
||||
|
||||
assign g = grs_sel_div ? fract_out[0] : fract_out[0];
|
||||
assign r = grs_sel_div ? (fract_trunc[24] & !div_nr) : fract_trunc[24];
|
||||
assign s = grs_sel_div ? |fract_trunc[24:0] : (|fract_trunc[23:0] | (fract_trunc[24] & op_div));
|
||||
|
||||
// Round to nearest even
|
||||
assign round = (g & r) | (r & s) ;
|
||||
assign {exp_rnd_adj0, fract_out_rnd0} = round ? fract_out_pl1 : {1'b0, fract_out};
|
||||
assign exp_out_rnd0 = exp_rnd_adj0 ? exp_out_pl1 : exp_out;
|
||||
assign ovf0 = exp_out_final_ff & !rmode_01 & !op_f2i;
|
||||
|
||||
// round to zero
|
||||
assign fract_out_rnd1 = (exp_out_ff & !op_div & !dn & !op_f2i) ? 23'h7fffff : fract_out;
|
||||
assign exp_fix_div = (fi_ldz>22) ? exp_fix_diva : exp_fix_divb;
|
||||
assign exp_out_rnd1 = (g & r & s & exp_in_ff) ? (op_div ? exp_fix_div : exp_next_mi[7:0]) :
|
||||
(exp_out_ff & !op_f2i) ? exp_in : exp_out;
|
||||
assign ovf1 = exp_out_ff & !dn;
|
||||
|
||||
// round to +inf (UP) and -inf (DOWN)
|
||||
assign r_sign = sign;
|
||||
|
||||
assign round2a = !exp_out_fe | !fract_out_7fffff | (exp_out_fe & fract_out_7fffff);
|
||||
assign round2_fasu = ((r | s) & !r_sign) & (!exp_out[7] | (exp_out[7] & round2a));
|
||||
|
||||
assign round2_fmul = !r_sign &
|
||||
(
|
||||
(exp_ovf[1] & !fract_in_00 &
|
||||
( ((!exp_out1_co | op_dn) & (r | s | (!rem_00 & op_div) )) | fract_out_00 | (!op_dn & !op_div))
|
||||
) |
|
||||
(
|
||||
(r | s | (!rem_00 & op_div)) & (
|
||||
(!exp_ovf[1] & (exp_in_80 | !exp_ovf[0])) | op_div |
|
||||
( exp_ovf[1] & !exp_ovf[0] & exp_out1_co)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
assign round2_f2i = rmode_10 & (( |fract_in[23:0] & !opas & (exp_in<8'h80 )) | (|fract_trunc));
|
||||
assign round2 = (op_mul | op_div) ? round2_fmul : op_f2i ? round2_f2i : round2_fasu;
|
||||
|
||||
assign {exp_rnd_adj2a, fract_out_rnd2a} = round2 ? fract_out_pl1 : {1'b0, fract_out};
|
||||
assign exp_out_rnd2a = exp_rnd_adj2a ? ((exp_ovf[1] & op_mul) ? exp_out_mi1 : exp_out_pl1) : exp_out;
|
||||
|
||||
assign fract_out_rnd2 = (r_sign & exp_out_ff & !op_div & !dn & !op_f2i) ? 23'h7fffff : fract_out_rnd2a;
|
||||
assign exp_out_rnd2 = (r_sign & exp_out_ff & !op_f2i) ? 8'hfe : exp_out_rnd2a;
|
||||
|
||||
|
||||
// Choose rounding mode
|
||||
always @(rmode or exp_out_rnd0 or exp_out_rnd1 or exp_out_rnd2)
|
||||
case(rmode) // synopsys full_case parallel_case
|
||||
0: exp_out_rnd = exp_out_rnd0;
|
||||
1: exp_out_rnd = exp_out_rnd1;
|
||||
2,3: exp_out_rnd = exp_out_rnd2;
|
||||
endcase
|
||||
|
||||
always @(rmode or fract_out_rnd0 or fract_out_rnd1 or fract_out_rnd2)
|
||||
case(rmode) // synopsys full_case parallel_case
|
||||
0: fract_out_rnd = fract_out_rnd0;
|
||||
1: fract_out_rnd = fract_out_rnd1;
|
||||
2,3: fract_out_rnd = fract_out_rnd2;
|
||||
endcase
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Final Output Mux
|
||||
// Fix Output for denormalized and special numbers
|
||||
wire max_num, inf_out;
|
||||
|
||||
assign max_num = ( !rmode_00 & (op_mul | op_div ) & (
|
||||
( exp_ovf[1] & exp_ovf[0]) |
|
||||
(!exp_ovf[1] & !exp_ovf[0] & exp_in_ff & (fi_ldz_2<24) & (exp_out!=8'hfe) )
|
||||
)
|
||||
) |
|
||||
|
||||
( op_div & (
|
||||
( rmode_01 & ( div_inf |
|
||||
(exp_out_ff & !exp_ovf[1] ) |
|
||||
(exp_ovf[1] & exp_ovf[0] )
|
||||
)
|
||||
) |
|
||||
|
||||
( rmode[1] & !exp_ovf[1] & (
|
||||
( exp_ovf[0] & exp_in_ff & r_sign & fract_in[47]
|
||||
) |
|
||||
|
||||
( r_sign & (
|
||||
(fract_in[47] & div_inf) |
|
||||
(exp_in[7] & !exp_out_rnd[7] & !exp_in_80 & exp_out!=8'h7f ) |
|
||||
(exp_in[7] & exp_out_rnd[7] & r_sign & exp_out_ff & op_dn &
|
||||
div_exp1>9'h0fe )
|
||||
)
|
||||
) |
|
||||
|
||||
( exp_in_00 & r_sign & (
|
||||
div_inf |
|
||||
(r_sign & exp_out_ff & fi_ldz_2<24)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
assign inf_out = (rmode[1] & (op_mul | op_div) & !r_sign & ( (exp_in_ff & !op_div) |
|
||||
(exp_ovf[1] & exp_ovf[0] & (exp_in_00 | exp_in[7]) )
|
||||
)
|
||||
) | (div_inf & op_div & (
|
||||
rmode_00 |
|
||||
(rmode[1] & !exp_in_ff & !exp_ovf[1] & !exp_ovf[0] & !r_sign ) |
|
||||
(rmode[1] & !exp_ovf[1] & exp_ovf[0] & exp_in_00 & !r_sign)
|
||||
)
|
||||
) | (op_div & rmode[1] & exp_in_ff & op_dn & !r_sign & (fi_ldz_2 < 24) & (exp_out_rnd!=8'hfe) );
|
||||
|
||||
assign fract_out_final = (inf_out | ovf0 | output_zero ) ? 23'h0 :
|
||||
(max_num | (f2i_max & op_f2i) ) ? 23'h7fffff :
|
||||
fract_out_rnd;
|
||||
|
||||
assign exp_out_final = ((op_div & exp_ovf[1] & !exp_ovf[0]) | output_zero ) ? 8'h00 :
|
||||
((op_div & exp_ovf[1] & exp_ovf[0] & rmode_00) | inf_out | (f2i_max & op_f2i) ) ? 8'hff :
|
||||
max_num ? 8'hfe :
|
||||
exp_out_rnd;
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Pack Result
|
||||
|
||||
assign out = {exp_out_final, fract_out_final};
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Exceptions
|
||||
wire underflow_fmul;
|
||||
wire overflow_fdiv;
|
||||
wire undeflow_div;
|
||||
|
||||
wire z = shft_co | ( exp_ovf[1] | exp_in_00) |
|
||||
(!exp_ovf[1] & !exp_in_00 & (exp_out1_co | exp_out_00));
|
||||
|
||||
assign underflow_fmul = ( (|fract_trunc) & z & !exp_in_ff ) |
|
||||
(fract_out_00 & !fract_in_00 & exp_ovf[1]);
|
||||
|
||||
assign undeflow_div = !(exp_ovf[1] & exp_ovf[0] & rmode_00) & !inf_out & !max_num & exp_out_final!=8'hff & (
|
||||
|
||||
((|fract_trunc) & !opb_dn & (
|
||||
( op_dn & !exp_ovf[1] & exp_ovf[0]) |
|
||||
( op_dn & exp_ovf[1]) |
|
||||
( op_dn & div_shft1_co) |
|
||||
exp_out_00 |
|
||||
exp_ovf[1]
|
||||
)
|
||||
|
||||
) |
|
||||
|
||||
( exp_ovf[1] & !exp_ovf[0] & (
|
||||
( op_dn & exp_in>8'h16 & fi_ldz<23) |
|
||||
( op_dn & exp_in<23 & fi_ldz<23 & !rem_00) |
|
||||
( !op_dn & (exp_in[7]==exp_div[7]) & !rem_00) |
|
||||
( !op_dn & exp_in_00 & (exp_div[7:1]==7'h7f) ) |
|
||||
( !op_dn & exp_in<8'h7f & exp_in>8'h20 )
|
||||
)
|
||||
) |
|
||||
|
||||
(!exp_ovf[1] & !exp_ovf[0] & (
|
||||
( op_dn & fi_ldz<23 & exp_out_00) |
|
||||
( exp_in_00 & !rem_00) |
|
||||
( !op_dn & ldz_all<23 & exp_in==1 & exp_out_00 & !rem_00)
|
||||
)
|
||||
)
|
||||
|
||||
);
|
||||
|
||||
assign underflow = op_div ? undeflow_div : op_mul ? underflow_fmul : (!fract_in[47] & exp_out1_co) & !dn;
|
||||
|
||||
assign overflow_fdiv = inf_out |
|
||||
(!rmode_00 & max_num) |
|
||||
(exp_in[7] & op_dn & exp_out_ff) |
|
||||
(exp_ovf[0] & (exp_ovf[1] | exp_out_ff) );
|
||||
|
||||
assign overflow = op_div ? overflow_fdiv : (ovf0 | ovf1);
|
||||
|
||||
wire f2i_ine;
|
||||
|
||||
assign f2i_ine = (f2i_zero & !fract_in_00 & !opas) |
|
||||
(|fract_trunc) |
|
||||
(f2i_zero & (exp_in<8'h80) & opas & !fract_in_00) |
|
||||
(f2i_max & rmode_11 & (exp_in<8'h80));
|
||||
|
||||
|
||||
|
||||
assign ine = op_f2i ? f2i_ine :
|
||||
op_i2f ? (|fract_trunc) :
|
||||
((r & !dn) | (s & !dn) | max_num | (op_div & !rem_00));
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Debugging Stuff
|
||||
|
||||
// synopsys translate_off
|
||||
|
||||
wire [26:0] fracta_del, fractb_del;
|
||||
wire [2:0] grs_del;
|
||||
wire dn_del;
|
||||
wire [7:0] exp_in_del;
|
||||
wire [7:0] exp_out_del;
|
||||
wire [22:0] fract_out_del;
|
||||
wire [47:0] fract_in_del;
|
||||
wire overflow_del;
|
||||
wire [1:0] exp_ovf_del;
|
||||
wire [22:0] fract_out_x_del, fract_out_rnd2a_del;
|
||||
wire [24:0] trunc_xx_del;
|
||||
wire exp_rnd_adj2a_del;
|
||||
wire [22:0] fract_dn_del;
|
||||
wire [4:0] div_opa_ldz_del;
|
||||
wire [23:0] fracta_div_del;
|
||||
wire [23:0] fractb_div_del;
|
||||
wire div_inf_del;
|
||||
wire [7:0] fi_ldz_2_del;
|
||||
wire inf_out_del, max_out_del;
|
||||
wire [5:0] fi_ldz_del;
|
||||
wire rx_del;
|
||||
wire ez_del;
|
||||
wire lr;
|
||||
wire [7:0] shr, shl, exp_div_del;
|
||||
|
||||
delay2 #26 ud000(clk, test.u0.fracta, fracta_del);
|
||||
delay2 #26 ud001(clk, test.u0.fractb, fractb_del);
|
||||
delay1 #2 ud002(clk, {g,r,s}, grs_del);
|
||||
delay1 #0 ud004(clk, dn, dn_del);
|
||||
delay1 #7 ud005(clk, exp_in, exp_in_del);
|
||||
delay1 #7 ud007(clk, exp_out_rnd, exp_out_del);
|
||||
delay1 #47 ud009(clk, fract_in, fract_in_del);
|
||||
delay1 #0 ud010(clk, overflow, overflow_del);
|
||||
delay1 #1 ud011(clk, exp_ovf, exp_ovf_del);
|
||||
delay1 #22 ud014(clk, fract_out, fract_out_x_del);
|
||||
delay1 #24 ud015(clk, fract_trunc, trunc_xx_del);
|
||||
delay1 #0 ud017(clk, exp_rnd_adj2a, exp_rnd_adj2a_del);
|
||||
delay1 #4 ud019(clk, div_opa_ldz, div_opa_ldz_del);
|
||||
delay3 #23 ud020(clk, test.u0.fdiv_opa[49:26], fracta_div_del);
|
||||
delay3 #23 ud021(clk, test.u0.fractb_mul, fractb_div_del);
|
||||
delay1 #0 ud023(clk, div_inf, div_inf_del);
|
||||
delay1 #7 ud024(clk, fi_ldz_2, fi_ldz_2_del);
|
||||
delay1 #0 ud025(clk, inf_out, inf_out_del);
|
||||
delay1 #0 ud026(clk, max_num, max_num_del);
|
||||
delay1 #5 ud027(clk, fi_ldz, fi_ldz_del);
|
||||
delay1 #0 ud028(clk, rem_00, rx_del);
|
||||
|
||||
delay1 #0 ud029(clk, left_right, lr);
|
||||
delay1 #7 ud030(clk, shift_right, shr);
|
||||
delay1 #7 ud031(clk, shift_left, shl);
|
||||
delay1 #22 ud032(clk, fract_out_rnd2a, fract_out_rnd2a_del);
|
||||
|
||||
delay1 #7 ud033(clk, exp_div, exp_div_del);
|
||||
|
||||
always @(test.error_event)
|
||||
begin
|
||||
|
||||
$display("\n----------------------------------------------");
|
||||
|
||||
$display("ERROR: GRS: %b exp_ovf: %b dn: %h exp_in: %h exp_out: %h, exp_rnd_adj2a: %b",
|
||||
grs_del, exp_ovf_del, dn_del, exp_in_del, exp_out_del, exp_rnd_adj2a_del);
|
||||
|
||||
$display(" div_opa: %b, div_opb: %b, rem_00: %b, exp_div: %h",
|
||||
fracta_div_del, fractb_div_del, rx_del, exp_div_del);
|
||||
|
||||
$display(" lr: %b, shl: %h, shr: %h",
|
||||
lr, shl, shr);
|
||||
|
||||
|
||||
$display(" overflow: %b, fract_in=%b fa:%h fb:%h",
|
||||
overflow_del, fract_in_del, fracta_del, fractb_del);
|
||||
|
||||
$display(" div_opa_ldz: %h, div_inf: %b, inf_out: %b, max_num: %b, fi_ldz: %h, fi_ldz_2: %h",
|
||||
div_opa_ldz_del, div_inf_del, inf_out_del, max_num_del, fi_ldz_del, fi_ldz_2_del);
|
||||
|
||||
$display(" fract_out_x: %b, fract_out_rnd2a_del: %h, fract_trunc: %b\n",
|
||||
fract_out_x_del, fract_out_rnd2a_del, trunc_xx_del);
|
||||
end
|
||||
|
||||
|
||||
// synopsys translate_on
|
||||
|
||||
endmodule
|
||||
|
||||
// synopsys translate_off
|
||||
|
||||
module delay1(clk, in, out);
|
||||
parameter N = 1;
|
||||
input [N:0] in;
|
||||
output [N:0] out;
|
||||
input clk;
|
||||
|
||||
reg [N:0] out;
|
||||
|
||||
always @(posedge clk)
|
||||
out <= #1 in;
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module delay2(clk, in, out);
|
||||
parameter N = 1;
|
||||
input [N:0] in;
|
||||
output [N:0] out;
|
||||
input clk;
|
||||
|
||||
reg [N:0] out, r1;
|
||||
|
||||
always @(posedge clk)
|
||||
r1 <= #1 in;
|
||||
|
||||
always @(posedge clk)
|
||||
out <= #1 r1;
|
||||
|
||||
endmodule
|
||||
|
||||
module delay3(clk, in, out);
|
||||
parameter N = 1;
|
||||
input [N:0] in;
|
||||
output [N:0] out;
|
||||
input clk;
|
||||
|
||||
reg [N:0] out, r1, r2;
|
||||
|
||||
always @(posedge clk)
|
||||
r1 <= #1 in;
|
||||
|
||||
always @(posedge clk)
|
||||
r2 <= #1 r1;
|
||||
|
||||
always @(posedge clk)
|
||||
out <= #1 r2;
|
||||
|
||||
endmodule
|
||||
|
||||
// synopsys translate_on
|
|
@ -1,270 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Pre Normalize ////
|
||||
//// Pre Normalization Unit for Add/Sub Operations ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000 Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
`timescale 1ns / 100ps
|
||||
|
||||
|
||||
module pre_norm(clk, rmode, add, opa, opb, opa_nan, opb_nan, fracta_out,
|
||||
fractb_out, exp_dn_out, sign, nan_sign, result_zero_sign,
|
||||
fasu_op);
|
||||
input clk;
|
||||
input [1:0] rmode;
|
||||
input add;
|
||||
input [31:0] opa, opb;
|
||||
input opa_nan, opb_nan;
|
||||
output [26:0] fracta_out, fractb_out;
|
||||
output [7:0] exp_dn_out;
|
||||
output sign;
|
||||
output nan_sign, result_zero_sign;
|
||||
output fasu_op; // Operation Output
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and registers
|
||||
//
|
||||
|
||||
wire signa, signb; // alias to opX sign
|
||||
wire [7:0] expa, expb; // alias to opX exponent
|
||||
wire [22:0] fracta, fractb; // alias to opX fraction
|
||||
wire expa_lt_expb; // expa is larger than expb indicator
|
||||
wire fractb_lt_fracta; // fractb is larger than fracta indicator
|
||||
reg [7:0] exp_dn_out; // de normalized exponent output
|
||||
wire [7:0] exp_small, exp_large;
|
||||
wire [7:0] exp_diff; // Numeric difference of the two exponents
|
||||
wire [22:0] adj_op; // Fraction adjustment: input
|
||||
wire [26:0] adj_op_tmp;
|
||||
wire [26:0] adj_op_out; // Fraction adjustment: output
|
||||
wire [26:0] fracta_n, fractb_n; // Fraction selection after normalizing
|
||||
wire [26:0] fracta_s, fractb_s; // Fraction Sorting out
|
||||
reg [26:0] fracta_out, fractb_out; // Fraction Output
|
||||
reg sign, sign_d; // Sign Output
|
||||
reg add_d; // operation (add/sub)
|
||||
reg fasu_op; // operation (add/sub) register
|
||||
wire expa_dn, expb_dn;
|
||||
reg sticky;
|
||||
reg result_zero_sign;
|
||||
reg add_r, signa_r, signb_r;
|
||||
wire [4:0] exp_diff_sft;
|
||||
wire exp_lt_27;
|
||||
wire op_dn;
|
||||
wire [26:0] adj_op_out_sft;
|
||||
reg fracta_lt_fractb, fracta_eq_fractb;
|
||||
wire nan_sign1;
|
||||
reg nan_sign;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Aliases
|
||||
//
|
||||
|
||||
assign signa = opa[31];
|
||||
assign signb = opb[31];
|
||||
assign expa = opa[30:23];
|
||||
assign expb = opb[30:23];
|
||||
assign fracta = opa[22:0];
|
||||
assign fractb = opb[22:0];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Pre-Normalize exponents (and fractions)
|
||||
//
|
||||
|
||||
assign expa_lt_expb = expa > expb; // expa is larger than expb
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Normalize
|
||||
|
||||
assign expa_dn = !(|expa); // opa denormalized
|
||||
assign expb_dn = !(|expb); // opb denormalized
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Calculate the difference between the smaller and larger exponent
|
||||
|
||||
wire [7:0] exp_diff1, exp_diff1a, exp_diff2;
|
||||
|
||||
assign exp_small = expa_lt_expb ? expb : expa;
|
||||
assign exp_large = expa_lt_expb ? expa : expb;
|
||||
assign exp_diff1 = exp_large - exp_small;
|
||||
assign exp_diff1a = exp_diff1-1;
|
||||
assign exp_diff2 = (expa_dn | expb_dn) ? exp_diff1a : exp_diff1;
|
||||
assign exp_diff = (expa_dn & expb_dn) ? 8'h0 : exp_diff2;
|
||||
|
||||
always @(posedge clk) // If numbers are equal we should return zero
|
||||
exp_dn_out <= #1 (!add_d & expa==expb & fracta==fractb) ? 8'h0 : exp_large;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Adjust the smaller fraction
|
||||
|
||||
|
||||
assign op_dn = expa_lt_expb ? expb_dn : expa_dn;
|
||||
assign adj_op = expa_lt_expb ? fractb : fracta;
|
||||
assign adj_op_tmp = { ~op_dn, adj_op, 3'b0 }; // recover hidden bit (op_dn)
|
||||
|
||||
// adj_op_out is 27 bits wide, so can only be shifted 27 bits to the right
|
||||
assign exp_lt_27 = exp_diff > 8'd27;
|
||||
assign exp_diff_sft = exp_lt_27 ? 5'd27 : exp_diff[4:0];
|
||||
assign adj_op_out_sft = adj_op_tmp >> exp_diff_sft;
|
||||
assign adj_op_out = {adj_op_out_sft[26:1], adj_op_out_sft[0] | sticky };
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Get truncated portion (sticky bit)
|
||||
|
||||
always @(exp_diff_sft or adj_op_tmp)
|
||||
case(exp_diff_sft) // synopsys full_case parallel_case
|
||||
00: sticky = 1'h0;
|
||||
01: sticky = adj_op_tmp[0];
|
||||
02: sticky = |adj_op_tmp[01:0];
|
||||
03: sticky = |adj_op_tmp[02:0];
|
||||
04: sticky = |adj_op_tmp[03:0];
|
||||
05: sticky = |adj_op_tmp[04:0];
|
||||
06: sticky = |adj_op_tmp[05:0];
|
||||
07: sticky = |adj_op_tmp[06:0];
|
||||
08: sticky = |adj_op_tmp[07:0];
|
||||
09: sticky = |adj_op_tmp[08:0];
|
||||
10: sticky = |adj_op_tmp[09:0];
|
||||
11: sticky = |adj_op_tmp[10:0];
|
||||
12: sticky = |adj_op_tmp[11:0];
|
||||
13: sticky = |adj_op_tmp[12:0];
|
||||
14: sticky = |adj_op_tmp[13:0];
|
||||
15: sticky = |adj_op_tmp[14:0];
|
||||
16: sticky = |adj_op_tmp[15:0];
|
||||
17: sticky = |adj_op_tmp[16:0];
|
||||
18: sticky = |adj_op_tmp[17:0];
|
||||
19: sticky = |adj_op_tmp[18:0];
|
||||
20: sticky = |adj_op_tmp[19:0];
|
||||
21: sticky = |adj_op_tmp[20:0];
|
||||
22: sticky = |adj_op_tmp[21:0];
|
||||
23: sticky = |adj_op_tmp[22:0];
|
||||
24: sticky = |adj_op_tmp[23:0];
|
||||
25: sticky = |adj_op_tmp[24:0];
|
||||
26: sticky = |adj_op_tmp[25:0];
|
||||
27: sticky = |adj_op_tmp[26:0];
|
||||
endcase
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Select operands for add/sub (recover hidden bit)
|
||||
|
||||
assign fracta_n = expa_lt_expb ? {~expa_dn, fracta, 3'b0} : adj_op_out;
|
||||
assign fractb_n = expa_lt_expb ? adj_op_out : {~expb_dn, fractb, 3'b0};
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Sort operands (for sub only)
|
||||
|
||||
assign fractb_lt_fracta = fractb_n > fracta_n; // fractb is larger than fracta
|
||||
assign fracta_s = fractb_lt_fracta ? fractb_n : fracta_n;
|
||||
assign fractb_s = fractb_lt_fracta ? fracta_n : fractb_n;
|
||||
|
||||
always @(posedge clk)
|
||||
fracta_out <= #1 fracta_s;
|
||||
|
||||
always @(posedge clk)
|
||||
fractb_out <= #1 fractb_s;
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Determine sign for the output
|
||||
|
||||
// sign: 0=Positive Number; 1=Negative Number
|
||||
always @(signa or signb or add or fractb_lt_fracta)
|
||||
case({signa, signb, add}) // synopsys full_case parallel_case
|
||||
|
||||
// Add
|
||||
3'b0_0_1: sign_d = 0;
|
||||
3'b0_1_1: sign_d = fractb_lt_fracta;
|
||||
3'b1_0_1: sign_d = !fractb_lt_fracta;
|
||||
3'b1_1_1: sign_d = 1;
|
||||
|
||||
// Sub
|
||||
3'b0_0_0: sign_d = fractb_lt_fracta;
|
||||
3'b0_1_0: sign_d = 0;
|
||||
3'b1_0_0: sign_d = 1;
|
||||
3'b1_1_0: sign_d = !fractb_lt_fracta;
|
||||
endcase
|
||||
|
||||
always @(posedge clk)
|
||||
sign <= #1 sign_d;
|
||||
|
||||
// Fix sign for ZERO result
|
||||
always @(posedge clk)
|
||||
signa_r <= #1 signa;
|
||||
|
||||
always @(posedge clk)
|
||||
signb_r <= #1 signb;
|
||||
|
||||
always @(posedge clk)
|
||||
add_r <= #1 add;
|
||||
|
||||
always @(posedge clk)
|
||||
result_zero_sign <= #1 ( add_r & signa_r & signb_r) |
|
||||
(!add_r & signa_r & !signb_r) |
|
||||
( add_r & (signa_r | signb_r) & (rmode==3)) |
|
||||
(!add_r & (signa_r == signb_r) & (rmode==3));
|
||||
|
||||
// Fix sign for NAN result
|
||||
always @(posedge clk)
|
||||
fracta_lt_fractb <= #1 fracta < fractb;
|
||||
|
||||
always @(posedge clk)
|
||||
fracta_eq_fractb <= #1 fracta == fractb;
|
||||
|
||||
assign nan_sign1 = fracta_eq_fractb ? (signa_r & signb_r) : fracta_lt_fractb ? signb_r : signa_r;
|
||||
|
||||
always @(posedge clk)
|
||||
nan_sign <= #1 (opa_nan & opb_nan) ? nan_sign1 : opb_nan ? signb_r : signa_r;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Decode Add/Sub operation
|
||||
//
|
||||
|
||||
// add: 1=Add; 0=Subtract
|
||||
always @(signa or signb or add)
|
||||
case({signa, signb, add}) // synopsys full_case parallel_case
|
||||
|
||||
// Add
|
||||
3'b0_0_1: add_d = 1;
|
||||
3'b0_1_1: add_d = 0;
|
||||
3'b1_0_1: add_d = 0;
|
||||
3'b1_1_1: add_d = 1;
|
||||
|
||||
// Sub
|
||||
3'b0_0_0: add_d = 0;
|
||||
3'b0_1_0: add_d = 1;
|
||||
3'b1_0_0: add_d = 1;
|
||||
3'b1_1_0: add_d = 0;
|
||||
endcase
|
||||
|
||||
always @(posedge clk)
|
||||
fasu_op <= #1 add_d;
|
||||
|
||||
endmodule
|
|
@ -1,150 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Pre Normalize ////
|
||||
//// Floating Point Pre Normalization Unit for FMUL ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000 Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
`timescale 1ns / 100ps
|
||||
|
||||
module pre_norm_fmul(clk, fpu_op, opa, opb, fracta, fractb, exp_out, sign,
|
||||
sign_exe, inf, exp_ovf, underflow);
|
||||
input clk;
|
||||
input [2:0] fpu_op;
|
||||
input [31:0] opa, opb;
|
||||
output [23:0] fracta, fractb;
|
||||
output [7:0] exp_out;
|
||||
output sign, sign_exe;
|
||||
output inf;
|
||||
output [1:0] exp_ovf;
|
||||
output [2:0] underflow;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and registers
|
||||
//
|
||||
|
||||
reg [7:0] exp_out;
|
||||
wire signa, signb;
|
||||
reg sign, sign_d;
|
||||
reg sign_exe;
|
||||
reg inf;
|
||||
wire [1:0] exp_ovf_d;
|
||||
reg [1:0] exp_ovf;
|
||||
wire [7:0] expa, expb;
|
||||
wire [7:0] exp_tmp1, exp_tmp2;
|
||||
wire co1, co2;
|
||||
wire expa_dn, expb_dn;
|
||||
wire [7:0] exp_out_a;
|
||||
wire opa_00, opb_00, fracta_00, fractb_00;
|
||||
wire [7:0] exp_tmp3, exp_tmp4, exp_tmp5;
|
||||
wire [2:0] underflow_d;
|
||||
reg [2:0] underflow;
|
||||
wire op_div = (fpu_op == 3'b011);
|
||||
wire [7:0] exp_out_mul, exp_out_div;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Aliases
|
||||
//
|
||||
|
||||
assign signa = opa[31];
|
||||
assign signb = opb[31];
|
||||
assign expa = opa[30:23];
|
||||
assign expb = opb[30:23];
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Calculate Exponenet
|
||||
//
|
||||
|
||||
assign expa_dn = !(|expa);
|
||||
assign expb_dn = !(|expb);
|
||||
assign opa_00 = !(|opa[30:0]);
|
||||
assign opb_00 = !(|opb[30:0]);
|
||||
assign fracta_00 = !(|opa[22:0]);
|
||||
assign fractb_00 = !(|opb[22:0]);
|
||||
|
||||
assign fracta = {!expa_dn,opa[22:0]}; // Recover hidden bit
|
||||
assign fractb = {!expb_dn,opb[22:0]}; // Recover hidden bit
|
||||
|
||||
assign {co1,exp_tmp1} = op_div ? (expa - expb) : (expa + expb);
|
||||
assign {co2,exp_tmp2} = op_div ? ({co1,exp_tmp1} + 8'h7f) : ({co1,exp_tmp1} - 8'h7f);
|
||||
|
||||
assign exp_tmp3 = exp_tmp2 + 1;
|
||||
assign exp_tmp4 = 8'h7f - exp_tmp1;
|
||||
assign exp_tmp5 = op_div ? (exp_tmp4+1) : (exp_tmp4-1);
|
||||
|
||||
|
||||
always@(posedge clk)
|
||||
exp_out <= #1 op_div ? exp_out_div : exp_out_mul;
|
||||
|
||||
assign exp_out_div = (expa_dn | expb_dn) ? (co2 ? exp_tmp5 : exp_tmp3 ) : co2 ? exp_tmp4 : exp_tmp2;
|
||||
assign exp_out_mul = exp_ovf_d[1] ? exp_out_a : (expa_dn | expb_dn) ? exp_tmp3 : exp_tmp2;
|
||||
assign exp_out_a = (expa_dn | expb_dn) ? exp_tmp5 : exp_tmp4;
|
||||
assign exp_ovf_d[0] = op_div ? (expa[7] & !expb[7]) : (co2 & expa[7] & expb[7]);
|
||||
assign exp_ovf_d[1] = op_div ? co2 : ((!expa[7] & !expb[7] & exp_tmp2[7]) | co2);
|
||||
|
||||
always @(posedge clk)
|
||||
exp_ovf <= #1 exp_ovf_d;
|
||||
|
||||
assign underflow_d[0] = (exp_tmp1 < 8'h7f) & !co1 & !(opa_00 | opb_00 | expa_dn | expb_dn);
|
||||
assign underflow_d[1] = ((expa[7] | expb[7]) & !opa_00 & !opb_00) |
|
||||
(expa_dn & !fracta_00) | (expb_dn & !fractb_00);
|
||||
assign underflow_d[2] = !opa_00 & !opb_00 & (exp_tmp1 == 8'h7f);
|
||||
|
||||
always @(posedge clk)
|
||||
underflow <= #1 underflow_d;
|
||||
|
||||
always @(posedge clk)
|
||||
inf <= #1 op_div ? (expb_dn & !expa[7]) : ({co1,exp_tmp1} > 9'h17e) ;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Determine sign for the output
|
||||
//
|
||||
|
||||
// sign: 0=Posetive Number; 1=Negative Number
|
||||
always @(signa or signb)
|
||||
case({signa, signb}) // synopsys full_case parallel_case
|
||||
2'b0_0: sign_d = 0;
|
||||
2'b0_1: sign_d = 1;
|
||||
2'b1_0: sign_d = 1;
|
||||
2'b1_1: sign_d = 0;
|
||||
endcase
|
||||
|
||||
always @(posedge clk)
|
||||
sign <= #1 sign_d;
|
||||
|
||||
always @(posedge clk)
|
||||
sign_exe <= #1 signa & signb;
|
||||
|
||||
endmodule
|
|
@ -1,103 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Primitives ////
|
||||
//// FPU Primitives ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000 Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
`timescale 1ns / 100ps
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Add/Sub
|
||||
//
|
||||
|
||||
module add_sub27(add, opa, opb, sum, co);
|
||||
input add;
|
||||
input [26:0] opa, opb;
|
||||
output [26:0] sum;
|
||||
output co;
|
||||
|
||||
|
||||
|
||||
assign {co, sum} = add ? (opa + opb) : (opa - opb);
|
||||
|
||||
endmodule
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Multiply
|
||||
//
|
||||
|
||||
module mul_r2(clk, opa, opb, prod);
|
||||
input clk;
|
||||
input [23:0] opa, opb;
|
||||
output [47:0] prod;
|
||||
|
||||
reg [47:0] prod1, prod;
|
||||
|
||||
always @(posedge clk)
|
||||
prod1 <= #1 opa * opb;
|
||||
|
||||
always @(posedge clk)
|
||||
prod <= #1 prod1;
|
||||
|
||||
endmodule
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Divide
|
||||
//
|
||||
|
||||
module div_r2(clk, opa, opb, quo, rem);
|
||||
input clk;
|
||||
input [49:0] opa;
|
||||
input [23:0] opb;
|
||||
output [49:0] quo, rem;
|
||||
|
||||
reg [49:0] quo, rem, quo1, remainder;
|
||||
|
||||
always @(posedge clk)
|
||||
quo1 <= #1 opa / opb;
|
||||
|
||||
always @(posedge clk)
|
||||
quo <= #1 quo1;
|
||||
|
||||
always @(posedge clk)
|
||||
remainder <= #1 opa % opb;
|
||||
|
||||
always @(posedge clk)
|
||||
rem <= #1 remainder;
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -1,535 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE rev.B2 compliant I2C Master bit-controller ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// www.asics.ws ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2001 Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: i2c_master_bit_ctrl.v,v 1.11 2004/05/07 11:02:26 rherveille Exp $
|
||||
//
|
||||
// $Date: 2004/05/07 11:02:26 $
|
||||
// $Revision: 1.11 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: i2c_master_bit_ctrl.v,v $
|
||||
// Revision 1.11 2004/05/07 11:02:26 rherveille
|
||||
// Fixed a bug where the core would signal an arbitration lost (AL bit set), when another master controls the bus and the other master generates a STOP bit.
|
||||
//
|
||||
// Revision 1.10 2003/08/09 07:01:33 rherveille
|
||||
// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
|
||||
// Fixed a potential bug in the byte controller's host-acknowledge generation.
|
||||
//
|
||||
// Revision 1.9 2003/03/10 14:26:37 rherveille
|
||||
// Fixed cmd_ack generation item (no bug).
|
||||
//
|
||||
// Revision 1.8 2003/02/05 00:06:10 rherveille
|
||||
// Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles.
|
||||
//
|
||||
// Revision 1.7 2002/12/26 16:05:12 rherveille
|
||||
// Small code simplifications
|
||||
//
|
||||
// Revision 1.6 2002/12/26 15:02:32 rherveille
|
||||
// Core is now a Multimaster I2C controller
|
||||
//
|
||||
// Revision 1.5 2002/11/30 22:24:40 rherveille
|
||||
// Cleaned up code
|
||||
//
|
||||
// Revision 1.4 2002/10/30 18:10:07 rherveille
|
||||
// Fixed some reported minor start/stop generation timing issuess.
|
||||
//
|
||||
// Revision 1.3 2002/06/15 07:37:03 rherveille
|
||||
// Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment.
|
||||
//
|
||||
// Revision 1.2 2001/11/05 11:59:25 rherveille
|
||||
// Fixed wb_ack_o generation bug.
|
||||
// Fixed bug in the byte_controller statemachine.
|
||||
// Added headers.
|
||||
//
|
||||
|
||||
//
|
||||
/////////////////////////////////////
|
||||
// Bit controller section
|
||||
/////////////////////////////////////
|
||||
//
|
||||
// Translate simple commands into SCL/SDA transitions
|
||||
// Each command has 5 states, A/B/C/D/idle
|
||||
//
|
||||
// start: SCL ~~~~~~~~~~\____
|
||||
// SDA ~~~~~~~~\______
|
||||
// x | A | B | C | D | i
|
||||
//
|
||||
// repstart SCL ____/~~~~\___
|
||||
// SDA __/~~~\______
|
||||
// x | A | B | C | D | i
|
||||
//
|
||||
// stop SCL ____/~~~~~~~~
|
||||
// SDA ==\____/~~~~~
|
||||
// x | A | B | C | D | i
|
||||
//
|
||||
//- write SCL ____/~~~~\____
|
||||
// SDA ==X=========X=
|
||||
// x | A | B | C | D | i
|
||||
//
|
||||
//- read SCL ____/~~~~\____
|
||||
// SDA XXXX=====XXXX
|
||||
// x | A | B | C | D | i
|
||||
//
|
||||
|
||||
// Timing: Normal mode Fast mode
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Fscl 100KHz 400KHz
|
||||
// Th_scl 4.0us 0.6us High period of SCL
|
||||
// Tl_scl 4.7us 1.3us Low period of SCL
|
||||
// Tsu:sta 4.7us 0.6us setup time for a repeated start condition
|
||||
// Tsu:sto 4.0us 0.6us setup time for a stop conditon
|
||||
// Tbuf 4.7us 1.3us Bus free time between a stop and start condition
|
||||
//
|
||||
|
||||
// synopsys translate_off
|
||||
`include "timescale.v"
|
||||
// synopsys translate_on
|
||||
|
||||
`include "i2c_master_defines.v"
|
||||
|
||||
module i2c_master_bit_ctrl(
|
||||
clk, rst, nReset,
|
||||
clk_cnt, ena, cmd, cmd_ack, busy, al, din, dout,
|
||||
scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen
|
||||
);
|
||||
|
||||
//
|
||||
// inputs & outputs
|
||||
//
|
||||
input clk;
|
||||
input rst;
|
||||
input nReset;
|
||||
input ena; // core enable signal
|
||||
|
||||
input [15:0] clk_cnt; // clock prescale value
|
||||
|
||||
input [3:0] cmd;
|
||||
output cmd_ack; // command complete acknowledge
|
||||
reg cmd_ack;
|
||||
output busy; // i2c bus busy
|
||||
reg busy;
|
||||
output al; // i2c bus arbitration lost
|
||||
reg al;
|
||||
|
||||
input din;
|
||||
output dout;
|
||||
reg dout;
|
||||
|
||||
// I2C lines
|
||||
input scl_i; // i2c clock line input
|
||||
output scl_o; // i2c clock line output
|
||||
output scl_oen; // i2c clock line output enable (active low)
|
||||
reg scl_oen;
|
||||
input sda_i; // i2c data line input
|
||||
output sda_o; // i2c data line output
|
||||
output sda_oen; // i2c data line output enable (active low)
|
||||
reg sda_oen;
|
||||
|
||||
|
||||
//
|
||||
// variable declarations
|
||||
//
|
||||
|
||||
reg sSCL, sSDA; // synchronized SCL and SDA inputs
|
||||
reg dscl_oen; // delayed scl_oen
|
||||
reg sda_chk; // check SDA output (Multi-master arbitration)
|
||||
reg clk_en; // clock generation signals
|
||||
wire slave_wait;
|
||||
// reg [15:0] cnt = clk_cnt; // clock divider counter (simulation)
|
||||
reg [15:0] cnt; // clock divider counter (synthesis)
|
||||
|
||||
// state machine variable
|
||||
reg [16:0] c_state; // synopsys enum_state
|
||||
|
||||
//
|
||||
// module body
|
||||
//
|
||||
|
||||
// whenever the slave is not ready it can delay the cycle by pulling SCL low
|
||||
// delay scl_oen
|
||||
always @(posedge clk)
|
||||
dscl_oen <= #1 scl_oen;
|
||||
|
||||
assign slave_wait = dscl_oen && !sSCL;
|
||||
|
||||
|
||||
// generate clk enable signal
|
||||
always @(posedge clk or negedge nReset)
|
||||
if(~nReset)
|
||||
begin
|
||||
cnt <= #1 16'h0;
|
||||
clk_en <= #1 1'b1;
|
||||
end
|
||||
else if (rst)
|
||||
begin
|
||||
cnt <= #1 16'h0;
|
||||
clk_en <= #1 1'b1;
|
||||
end
|
||||
else if ( ~|cnt || ~ena)
|
||||
if (~slave_wait)
|
||||
begin
|
||||
cnt <= #1 clk_cnt;
|
||||
clk_en <= #1 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
cnt <= #1 cnt;
|
||||
clk_en <= #1 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
cnt <= #1 cnt - 16'h1;
|
||||
clk_en <= #1 1'b0;
|
||||
end
|
||||
|
||||
|
||||
// generate bus status controller
|
||||
reg dSCL, dSDA;
|
||||
reg sta_condition;
|
||||
reg sto_condition;
|
||||
|
||||
// synchronize SCL and SDA inputs
|
||||
// reduce metastability risc
|
||||
always @(posedge clk or negedge nReset)
|
||||
if (~nReset)
|
||||
begin
|
||||
sSCL <= #1 1'b1;
|
||||
sSDA <= #1 1'b1;
|
||||
|
||||
dSCL <= #1 1'b1;
|
||||
dSDA <= #1 1'b1;
|
||||
end
|
||||
else if (rst)
|
||||
begin
|
||||
sSCL <= #1 1'b1;
|
||||
sSDA <= #1 1'b1;
|
||||
|
||||
dSCL <= #1 1'b1;
|
||||
dSDA <= #1 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
sSCL <= #1 scl_i;
|
||||
sSDA <= #1 sda_i;
|
||||
|
||||
dSCL <= #1 sSCL;
|
||||
dSDA <= #1 sSDA;
|
||||
end
|
||||
|
||||
// detect start condition => detect falling edge on SDA while SCL is high
|
||||
// detect stop condition => detect rising edge on SDA while SCL is high
|
||||
always @(posedge clk or negedge nReset)
|
||||
if (~nReset)
|
||||
begin
|
||||
sta_condition <= #1 1'b0;
|
||||
sto_condition <= #1 1'b0;
|
||||
end
|
||||
else if (rst)
|
||||
begin
|
||||
sta_condition <= #1 1'b0;
|
||||
sto_condition <= #1 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
sta_condition <= #1 ~sSDA & dSDA & sSCL;
|
||||
sto_condition <= #1 sSDA & ~dSDA & sSCL;
|
||||
end
|
||||
|
||||
// generate i2c bus busy signal
|
||||
always @(posedge clk or negedge nReset)
|
||||
if(!nReset)
|
||||
busy <= #1 1'b0;
|
||||
else if (rst)
|
||||
busy <= #1 1'b0;
|
||||
else
|
||||
busy <= #1 (sta_condition | busy) & ~sto_condition;
|
||||
|
||||
// generate arbitration lost signal
|
||||
// aribitration lost when:
|
||||
// 1) master drives SDA high, but the i2c bus is low
|
||||
// 2) stop detected while not requested
|
||||
reg cmd_stop;
|
||||
always @(posedge clk or negedge nReset)
|
||||
if (~nReset)
|
||||
cmd_stop <= #1 1'b0;
|
||||
else if (rst)
|
||||
cmd_stop <= #1 1'b0;
|
||||
else if (clk_en)
|
||||
cmd_stop <= #1 cmd == `I2C_CMD_STOP;
|
||||
|
||||
always @(posedge clk or negedge nReset)
|
||||
if (~nReset)
|
||||
al <= #1 1'b0;
|
||||
else if (rst)
|
||||
al <= #1 1'b0;
|
||||
else
|
||||
al <= #1 (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop);
|
||||
|
||||
|
||||
// generate dout signal (store SDA on rising edge of SCL)
|
||||
always @(posedge clk)
|
||||
if(sSCL & ~dSCL)
|
||||
dout <= #1 sSDA;
|
||||
|
||||
// generate statemachine
|
||||
|
||||
// nxt_state decoder
|
||||
parameter [16:0] idle = 17'b0_0000_0000_0000_0000;
|
||||
parameter [16:0] start_a = 17'b0_0000_0000_0000_0001;
|
||||
parameter [16:0] start_b = 17'b0_0000_0000_0000_0010;
|
||||
parameter [16:0] start_c = 17'b0_0000_0000_0000_0100;
|
||||
parameter [16:0] start_d = 17'b0_0000_0000_0000_1000;
|
||||
parameter [16:0] start_e = 17'b0_0000_0000_0001_0000;
|
||||
parameter [16:0] stop_a = 17'b0_0000_0000_0010_0000;
|
||||
parameter [16:0] stop_b = 17'b0_0000_0000_0100_0000;
|
||||
parameter [16:0] stop_c = 17'b0_0000_0000_1000_0000;
|
||||
parameter [16:0] stop_d = 17'b0_0000_0001_0000_0000;
|
||||
parameter [16:0] rd_a = 17'b0_0000_0010_0000_0000;
|
||||
parameter [16:0] rd_b = 17'b0_0000_0100_0000_0000;
|
||||
parameter [16:0] rd_c = 17'b0_0000_1000_0000_0000;
|
||||
parameter [16:0] rd_d = 17'b0_0001_0000_0000_0000;
|
||||
parameter [16:0] wr_a = 17'b0_0010_0000_0000_0000;
|
||||
parameter [16:0] wr_b = 17'b0_0100_0000_0000_0000;
|
||||
parameter [16:0] wr_c = 17'b0_1000_0000_0000_0000;
|
||||
parameter [16:0] wr_d = 17'b1_0000_0000_0000_0000;
|
||||
|
||||
always @(posedge clk or negedge nReset)
|
||||
if (!nReset)
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
cmd_ack <= #1 1'b0;
|
||||
scl_oen <= #1 1'b1;
|
||||
sda_oen <= #1 1'b1;
|
||||
sda_chk <= #1 1'b0;
|
||||
end
|
||||
else if (rst | al)
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
cmd_ack <= #1 1'b0;
|
||||
scl_oen <= #1 1'b1;
|
||||
sda_oen <= #1 1'b1;
|
||||
sda_chk <= #1 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
cmd_ack <= #1 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
|
||||
|
||||
if (clk_en)
|
||||
case (c_state) // synopsys full_case parallel_case
|
||||
// idle state
|
||||
idle:
|
||||
begin
|
||||
case (cmd) // synopsys full_case parallel_case
|
||||
`I2C_CMD_START:
|
||||
c_state <= #1 start_a;
|
||||
|
||||
`I2C_CMD_STOP:
|
||||
c_state <= #1 stop_a;
|
||||
|
||||
`I2C_CMD_WRITE:
|
||||
c_state <= #1 wr_a;
|
||||
|
||||
`I2C_CMD_READ:
|
||||
c_state <= #1 rd_a;
|
||||
|
||||
default:
|
||||
c_state <= #1 idle;
|
||||
endcase
|
||||
|
||||
scl_oen <= #1 scl_oen; // keep SCL in same state
|
||||
sda_oen <= #1 sda_oen; // keep SDA in same state
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
// start
|
||||
start_a:
|
||||
begin
|
||||
c_state <= #1 start_b;
|
||||
scl_oen <= #1 scl_oen; // keep SCL in same state
|
||||
sda_oen <= #1 1'b1; // set SDA high
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
start_b:
|
||||
begin
|
||||
c_state <= #1 start_c;
|
||||
scl_oen <= #1 1'b1; // set SCL high
|
||||
sda_oen <= #1 1'b1; // keep SDA high
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
start_c:
|
||||
begin
|
||||
c_state <= #1 start_d;
|
||||
scl_oen <= #1 1'b1; // keep SCL high
|
||||
sda_oen <= #1 1'b0; // set SDA low
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
start_d:
|
||||
begin
|
||||
c_state <= #1 start_e;
|
||||
scl_oen <= #1 1'b1; // keep SCL high
|
||||
sda_oen <= #1 1'b0; // keep SDA low
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
start_e:
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
cmd_ack <= #1 1'b1;
|
||||
scl_oen <= #1 1'b0; // set SCL low
|
||||
sda_oen <= #1 1'b0; // keep SDA low
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
// stop
|
||||
stop_a:
|
||||
begin
|
||||
c_state <= #1 stop_b;
|
||||
scl_oen <= #1 1'b0; // keep SCL low
|
||||
sda_oen <= #1 1'b0; // set SDA low
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
stop_b:
|
||||
begin
|
||||
c_state <= #1 stop_c;
|
||||
scl_oen <= #1 1'b1; // set SCL high
|
||||
sda_oen <= #1 1'b0; // keep SDA low
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
stop_c:
|
||||
begin
|
||||
c_state <= #1 stop_d;
|
||||
scl_oen <= #1 1'b1; // keep SCL high
|
||||
sda_oen <= #1 1'b0; // keep SDA low
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
stop_d:
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
cmd_ack <= #1 1'b1;
|
||||
scl_oen <= #1 1'b1; // keep SCL high
|
||||
sda_oen <= #1 1'b1; // set SDA high
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
// read
|
||||
rd_a:
|
||||
begin
|
||||
c_state <= #1 rd_b;
|
||||
scl_oen <= #1 1'b0; // keep SCL low
|
||||
sda_oen <= #1 1'b1; // tri-state SDA
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
rd_b:
|
||||
begin
|
||||
c_state <= #1 rd_c;
|
||||
scl_oen <= #1 1'b1; // set SCL high
|
||||
sda_oen <= #1 1'b1; // keep SDA tri-stated
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
rd_c:
|
||||
begin
|
||||
c_state <= #1 rd_d;
|
||||
scl_oen <= #1 1'b1; // keep SCL high
|
||||
sda_oen <= #1 1'b1; // keep SDA tri-stated
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
rd_d:
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
cmd_ack <= #1 1'b1;
|
||||
scl_oen <= #1 1'b0; // set SCL low
|
||||
sda_oen <= #1 1'b1; // keep SDA tri-stated
|
||||
sda_chk <= #1 1'b0; // don't check SDA output
|
||||
end
|
||||
|
||||
// write
|
||||
wr_a:
|
||||
begin
|
||||
c_state <= #1 wr_b;
|
||||
scl_oen <= #1 1'b0; // keep SCL low
|
||||
sda_oen <= #1 din; // set SDA
|
||||
sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
|
||||
end
|
||||
|
||||
wr_b:
|
||||
begin
|
||||
c_state <= #1 wr_c;
|
||||
scl_oen <= #1 1'b1; // set SCL high
|
||||
sda_oen <= #1 din; // keep SDA
|
||||
sda_chk <= #1 1'b1; // check SDA output
|
||||
end
|
||||
|
||||
wr_c:
|
||||
begin
|
||||
c_state <= #1 wr_d;
|
||||
scl_oen <= #1 1'b1; // keep SCL high
|
||||
sda_oen <= #1 din;
|
||||
sda_chk <= #1 1'b1; // check SDA output
|
||||
end
|
||||
|
||||
wr_d:
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
cmd_ack <= #1 1'b1;
|
||||
scl_oen <= #1 1'b0; // set SCL low
|
||||
sda_oen <= #1 din;
|
||||
sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// assign scl and sda output (always gnd)
|
||||
assign scl_o = 1'b0;
|
||||
assign sda_o = 1'b0;
|
||||
|
||||
endmodule
|
|
@ -1,344 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE rev.B2 compliant I2C Master byte-controller ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// www.asics.ws ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2001 Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: i2c_master_byte_ctrl.v,v 1.7 2004/02/18 11:40:46 rherveille Exp $
|
||||
//
|
||||
// $Date: 2004/02/18 11:40:46 $
|
||||
// $Revision: 1.7 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: i2c_master_byte_ctrl.v,v $
|
||||
// Revision 1.7 2004/02/18 11:40:46 rherveille
|
||||
// Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command.
|
||||
//
|
||||
// Revision 1.6 2003/08/09 07:01:33 rherveille
|
||||
// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
|
||||
// Fixed a potential bug in the byte controller's host-acknowledge generation.
|
||||
//
|
||||
// Revision 1.5 2002/12/26 15:02:32 rherveille
|
||||
// Core is now a Multimaster I2C controller
|
||||
//
|
||||
// Revision 1.4 2002/11/30 22:24:40 rherveille
|
||||
// Cleaned up code
|
||||
//
|
||||
// Revision 1.3 2001/11/05 11:59:25 rherveille
|
||||
// Fixed wb_ack_o generation bug.
|
||||
// Fixed bug in the byte_controller statemachine.
|
||||
// Added headers.
|
||||
//
|
||||
|
||||
// synopsys translate_off
|
||||
`include "timescale.v"
|
||||
// synopsys translate_on
|
||||
|
||||
`include "i2c_master_defines.v"
|
||||
|
||||
module i2c_master_byte_ctrl (
|
||||
clk, rst, nReset, ena, clk_cnt, start, stop, read, write, ack_in, din,
|
||||
cmd_ack, ack_out, dout, i2c_busy, i2c_al, scl_i, scl_o, scl_oen, sda_i, sda_o, sda_oen );
|
||||
|
||||
//
|
||||
// inputs & outputs
|
||||
//
|
||||
input clk; // master clock
|
||||
input rst; // synchronous active high reset
|
||||
input nReset; // asynchronous active low reset
|
||||
input ena; // core enable signal
|
||||
|
||||
input [15:0] clk_cnt; // 4x SCL
|
||||
|
||||
// control inputs
|
||||
input start;
|
||||
input stop;
|
||||
input read;
|
||||
input write;
|
||||
input ack_in;
|
||||
input [7:0] din;
|
||||
|
||||
// status outputs
|
||||
output cmd_ack;
|
||||
reg cmd_ack;
|
||||
output ack_out;
|
||||
reg ack_out;
|
||||
output i2c_busy;
|
||||
output i2c_al;
|
||||
output [7:0] dout;
|
||||
|
||||
// I2C signals
|
||||
input scl_i;
|
||||
output scl_o;
|
||||
output scl_oen;
|
||||
input sda_i;
|
||||
output sda_o;
|
||||
output sda_oen;
|
||||
|
||||
|
||||
//
|
||||
// Variable declarations
|
||||
//
|
||||
|
||||
// statemachine
|
||||
parameter [4:0] ST_IDLE = 5'b0_0000;
|
||||
parameter [4:0] ST_START = 5'b0_0001;
|
||||
parameter [4:0] ST_READ = 5'b0_0010;
|
||||
parameter [4:0] ST_WRITE = 5'b0_0100;
|
||||
parameter [4:0] ST_ACK = 5'b0_1000;
|
||||
parameter [4:0] ST_STOP = 5'b1_0000;
|
||||
|
||||
// signals for bit_controller
|
||||
reg [3:0] core_cmd;
|
||||
reg core_txd;
|
||||
wire core_ack, core_rxd;
|
||||
|
||||
// signals for shift register
|
||||
reg [7:0] sr; //8bit shift register
|
||||
reg shift, ld;
|
||||
|
||||
// signals for state machine
|
||||
wire go;
|
||||
reg [2:0] dcnt;
|
||||
wire cnt_done;
|
||||
|
||||
//
|
||||
// Module body
|
||||
//
|
||||
|
||||
// hookup bit_controller
|
||||
i2c_master_bit_ctrl bit_controller (
|
||||
.clk ( clk ),
|
||||
.rst ( rst ),
|
||||
.nReset ( nReset ),
|
||||
.ena ( ena ),
|
||||
.clk_cnt ( clk_cnt ),
|
||||
.cmd ( core_cmd ),
|
||||
.cmd_ack ( core_ack ),
|
||||
.busy ( i2c_busy ),
|
||||
.al ( i2c_al ),
|
||||
.din ( core_txd ),
|
||||
.dout ( core_rxd ),
|
||||
.scl_i ( scl_i ),
|
||||
.scl_o ( scl_o ),
|
||||
.scl_oen ( scl_oen ),
|
||||
.sda_i ( sda_i ),
|
||||
.sda_o ( sda_o ),
|
||||
.sda_oen ( sda_oen )
|
||||
);
|
||||
|
||||
// generate go-signal
|
||||
assign go = (read | write | stop) & ~cmd_ack;
|
||||
|
||||
// assign dout output to shift-register
|
||||
assign dout = sr;
|
||||
|
||||
// generate shift register
|
||||
always @(posedge clk or negedge nReset)
|
||||
if (!nReset)
|
||||
sr <= #1 8'h0;
|
||||
else if (rst)
|
||||
sr <= #1 8'h0;
|
||||
else if (ld)
|
||||
sr <= #1 din;
|
||||
else if (shift)
|
||||
sr <= #1 {sr[6:0], core_rxd};
|
||||
|
||||
// generate counter
|
||||
always @(posedge clk or negedge nReset)
|
||||
if (!nReset)
|
||||
dcnt <= #1 3'h0;
|
||||
else if (rst)
|
||||
dcnt <= #1 3'h0;
|
||||
else if (ld)
|
||||
dcnt <= #1 3'h7;
|
||||
else if (shift)
|
||||
dcnt <= #1 dcnt - 3'h1;
|
||||
|
||||
assign cnt_done = ~(|dcnt);
|
||||
|
||||
//
|
||||
// state machine
|
||||
//
|
||||
reg [4:0] c_state; // synopsis enum_state
|
||||
|
||||
always @(posedge clk or negedge nReset)
|
||||
if (!nReset)
|
||||
begin
|
||||
core_cmd <= #1 `I2C_CMD_NOP;
|
||||
core_txd <= #1 1'b0;
|
||||
shift <= #1 1'b0;
|
||||
ld <= #1 1'b0;
|
||||
cmd_ack <= #1 1'b0;
|
||||
c_state <= #1 ST_IDLE;
|
||||
ack_out <= #1 1'b0;
|
||||
end
|
||||
else if (rst | i2c_al)
|
||||
begin
|
||||
core_cmd <= #1 `I2C_CMD_NOP;
|
||||
core_txd <= #1 1'b0;
|
||||
shift <= #1 1'b0;
|
||||
ld <= #1 1'b0;
|
||||
cmd_ack <= #1 1'b0;
|
||||
c_state <= #1 ST_IDLE;
|
||||
ack_out <= #1 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// initially reset all signals
|
||||
core_txd <= #1 sr[7];
|
||||
shift <= #1 1'b0;
|
||||
ld <= #1 1'b0;
|
||||
cmd_ack <= #1 1'b0;
|
||||
|
||||
case (c_state) // synopsys full_case parallel_case
|
||||
ST_IDLE:
|
||||
if (go)
|
||||
begin
|
||||
if (start)
|
||||
begin
|
||||
c_state <= #1 ST_START;
|
||||
core_cmd <= #1 `I2C_CMD_START;
|
||||
end
|
||||
else if (read)
|
||||
begin
|
||||
c_state <= #1 ST_READ;
|
||||
core_cmd <= #1 `I2C_CMD_READ;
|
||||
end
|
||||
else if (write)
|
||||
begin
|
||||
c_state <= #1 ST_WRITE;
|
||||
core_cmd <= #1 `I2C_CMD_WRITE;
|
||||
end
|
||||
else // stop
|
||||
begin
|
||||
c_state <= #1 ST_STOP;
|
||||
core_cmd <= #1 `I2C_CMD_STOP;
|
||||
end
|
||||
|
||||
ld <= #1 1'b1;
|
||||
end
|
||||
|
||||
ST_START:
|
||||
if (core_ack)
|
||||
begin
|
||||
if (read)
|
||||
begin
|
||||
c_state <= #1 ST_READ;
|
||||
core_cmd <= #1 `I2C_CMD_READ;
|
||||
end
|
||||
else
|
||||
begin
|
||||
c_state <= #1 ST_WRITE;
|
||||
core_cmd <= #1 `I2C_CMD_WRITE;
|
||||
end
|
||||
|
||||
ld <= #1 1'b1;
|
||||
end
|
||||
|
||||
ST_WRITE:
|
||||
if (core_ack)
|
||||
if (cnt_done)
|
||||
begin
|
||||
c_state <= #1 ST_ACK;
|
||||
core_cmd <= #1 `I2C_CMD_READ;
|
||||
end
|
||||
else
|
||||
begin
|
||||
c_state <= #1 ST_WRITE; // stay in same state
|
||||
core_cmd <= #1 `I2C_CMD_WRITE; // write next bit
|
||||
shift <= #1 1'b1;
|
||||
end
|
||||
|
||||
ST_READ:
|
||||
if (core_ack)
|
||||
begin
|
||||
if (cnt_done)
|
||||
begin
|
||||
c_state <= #1 ST_ACK;
|
||||
core_cmd <= #1 `I2C_CMD_WRITE;
|
||||
end
|
||||
else
|
||||
begin
|
||||
c_state <= #1 ST_READ; // stay in same state
|
||||
core_cmd <= #1 `I2C_CMD_READ; // read next bit
|
||||
end
|
||||
|
||||
shift <= #1 1'b1;
|
||||
core_txd <= #1 ack_in;
|
||||
end
|
||||
|
||||
ST_ACK:
|
||||
if (core_ack)
|
||||
begin
|
||||
if (stop)
|
||||
begin
|
||||
c_state <= #1 ST_STOP;
|
||||
core_cmd <= #1 `I2C_CMD_STOP;
|
||||
end
|
||||
else
|
||||
begin
|
||||
c_state <= #1 ST_IDLE;
|
||||
core_cmd <= #1 `I2C_CMD_NOP;
|
||||
|
||||
// generate command acknowledge signal
|
||||
cmd_ack <= #1 1'b1;
|
||||
end
|
||||
|
||||
// assign ack_out output to bit_controller_rxd (contains last received bit)
|
||||
ack_out <= #1 core_rxd;
|
||||
|
||||
core_txd <= #1 1'b1;
|
||||
end
|
||||
else
|
||||
core_txd <= #1 ack_in;
|
||||
|
||||
ST_STOP:
|
||||
if (core_ack)
|
||||
begin
|
||||
c_state <= #1 ST_IDLE;
|
||||
core_cmd <= #1 `I2C_CMD_NOP;
|
||||
|
||||
// generate command acknowledge signal
|
||||
cmd_ack <= #1 1'b1;
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
endmodule
|
|
@ -1,64 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE rev.B2 compliant I2C Master controller defines ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// www.asics.ws ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2001 Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: i2c_master_defines.v,v 1.3 2001/11/05 11:59:25 rherveille Exp $
|
||||
//
|
||||
// $Date: 2001/11/05 11:59:25 $
|
||||
// $Revision: 1.3 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: i2c_master_defines.v,v $
|
||||
// Revision 1.3 2001/11/05 11:59:25 rherveille
|
||||
// Fixed wb_ack_o generation bug.
|
||||
// Fixed bug in the byte_controller statemachine.
|
||||
// Added headers.
|
||||
//
|
||||
|
||||
|
||||
// I2C registers wishbone addresses
|
||||
|
||||
// bitcontroller states
|
||||
`define I2C_CMD_NOP 4'b0000
|
||||
`define I2C_CMD_START 4'b0001
|
||||
`define I2C_CMD_STOP 4'b0010
|
||||
`define I2C_CMD_WRITE 4'b0100
|
||||
`define I2C_CMD_READ 4'b1000
|
|
@ -1,301 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE revB.2 compliant I2C Master controller Top-level ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// www.asics.ws ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2001 Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: i2c_master_top.v,v 1.11 2005/02/27 09:26:24 rherveille Exp $
|
||||
//
|
||||
// $Date: 2005/02/27 09:26:24 $
|
||||
// $Revision: 1.11 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: i2c_master_top.v,v $
|
||||
// Revision 1.11 2005/02/27 09:26:24 rherveille
|
||||
// Fixed register overwrite issue.
|
||||
// Removed full_case pragma, replaced it by a default statement.
|
||||
//
|
||||
// Revision 1.10 2003/09/01 10:34:38 rherveille
|
||||
// Fix a blocking vs. non-blocking error in the wb_dat output mux.
|
||||
//
|
||||
// Revision 1.9 2003/01/09 16:44:45 rherveille
|
||||
// Fixed a bug in the Command Register declaration.
|
||||
//
|
||||
// Revision 1.8 2002/12/26 16:05:12 rherveille
|
||||
// Small code simplifications
|
||||
//
|
||||
// Revision 1.7 2002/12/26 15:02:32 rherveille
|
||||
// Core is now a Multimaster I2C controller
|
||||
//
|
||||
// Revision 1.6 2002/11/30 22:24:40 rherveille
|
||||
// Cleaned up code
|
||||
//
|
||||
// Revision 1.5 2001/11/10 10:52:55 rherveille
|
||||
// Changed PRER reset value from 0x0000 to 0xffff, conform specs.
|
||||
//
|
||||
|
||||
// synopsys translate_off
|
||||
`include "timescale.v"
|
||||
// synopsys translate_on
|
||||
|
||||
`include "i2c_master_defines.v"
|
||||
|
||||
module i2c_master_top(
|
||||
wb_clk_i, wb_rst_i, arst_i, wb_adr_i, wb_dat_i, wb_dat_o,
|
||||
wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_inta_o,
|
||||
scl_pad_i, scl_pad_o, scl_padoen_o, sda_pad_i, sda_pad_o, sda_padoen_o );
|
||||
|
||||
// parameters
|
||||
parameter ARST_LVL = 1'b0; // asynchronous reset level
|
||||
|
||||
//
|
||||
// inputs & outputs
|
||||
//
|
||||
|
||||
// wishbone signals
|
||||
input wb_clk_i; // master clock input
|
||||
input wb_rst_i; // synchronous active high reset
|
||||
input arst_i; // asynchronous reset
|
||||
input [2:0] wb_adr_i; // lower address bits
|
||||
input [7:0] wb_dat_i; // databus input
|
||||
output [7:0] wb_dat_o; // databus output
|
||||
input wb_we_i; // write enable input
|
||||
input wb_stb_i; // stobe/core select signal
|
||||
input wb_cyc_i; // valid bus cycle input
|
||||
output wb_ack_o; // bus cycle acknowledge output
|
||||
output wb_inta_o; // interrupt request signal output
|
||||
|
||||
reg [7:0] wb_dat_o;
|
||||
reg wb_ack_o;
|
||||
reg wb_inta_o;
|
||||
|
||||
// I2C signals
|
||||
// i2c clock line
|
||||
input scl_pad_i; // SCL-line input
|
||||
output scl_pad_o; // SCL-line output (always 1'b0)
|
||||
output scl_padoen_o; // SCL-line output enable (active low)
|
||||
|
||||
// i2c data line
|
||||
input sda_pad_i; // SDA-line input
|
||||
output sda_pad_o; // SDA-line output (always 1'b0)
|
||||
output sda_padoen_o; // SDA-line output enable (active low)
|
||||
|
||||
|
||||
//
|
||||
// variable declarations
|
||||
//
|
||||
|
||||
// registers
|
||||
reg [15:0] prer; // clock prescale register
|
||||
reg [ 7:0] ctr; // control register
|
||||
reg [ 7:0] txr; // transmit register
|
||||
wire [ 7:0] rxr; // receive register
|
||||
reg [ 7:0] cr; // command register
|
||||
wire [ 7:0] sr; // status register
|
||||
|
||||
// done signal: command completed, clear command register
|
||||
wire done;
|
||||
|
||||
// core enable signal
|
||||
wire core_en;
|
||||
wire ien;
|
||||
|
||||
// status register signals
|
||||
wire irxack;
|
||||
reg rxack; // received aknowledge from slave
|
||||
reg tip; // transfer in progress
|
||||
reg irq_flag; // interrupt pending flag
|
||||
wire i2c_busy; // bus busy (start signal detected)
|
||||
wire i2c_al; // i2c bus arbitration lost
|
||||
reg al; // status register arbitration lost bit
|
||||
|
||||
//
|
||||
// module body
|
||||
//
|
||||
|
||||
// generate internal reset
|
||||
wire rst_i = arst_i ^ ARST_LVL;
|
||||
|
||||
// generate wishbone signals
|
||||
wire wb_wacc = wb_cyc_i & wb_stb_i & wb_we_i;
|
||||
|
||||
// generate acknowledge output signal
|
||||
always @(posedge wb_clk_i)
|
||||
wb_ack_o <= #1 wb_cyc_i & wb_stb_i & ~wb_ack_o; // because timing is always honored
|
||||
|
||||
// assign DAT_O
|
||||
always @(posedge wb_clk_i)
|
||||
begin
|
||||
case (wb_adr_i) // synopsis parallel_case
|
||||
3'b000: wb_dat_o <= #1 prer[ 7:0];
|
||||
3'b001: wb_dat_o <= #1 prer[15:8];
|
||||
3'b010: wb_dat_o <= #1 ctr;
|
||||
3'b011: wb_dat_o <= #1 rxr; // write is transmit register (txr)
|
||||
3'b100: wb_dat_o <= #1 sr; // write is command register (cr)
|
||||
3'b101: wb_dat_o <= #1 txr;
|
||||
3'b110: wb_dat_o <= #1 cr;
|
||||
3'b111: wb_dat_o <= #1 0; // reserved
|
||||
endcase
|
||||
end
|
||||
|
||||
// generate registers
|
||||
always @(posedge wb_clk_i or negedge rst_i)
|
||||
if (!rst_i)
|
||||
begin
|
||||
prer <= #1 16'hffff;
|
||||
ctr <= #1 8'h0;
|
||||
txr <= #1 8'h0;
|
||||
end
|
||||
else if (wb_rst_i)
|
||||
begin
|
||||
prer <= #1 16'hffff;
|
||||
ctr <= #1 8'h0;
|
||||
txr <= #1 8'h0;
|
||||
end
|
||||
else
|
||||
if (wb_wacc)
|
||||
case (wb_adr_i) // synopsis parallel_case
|
||||
3'b000 : prer [ 7:0] <= #1 wb_dat_i;
|
||||
3'b001 : prer [15:8] <= #1 wb_dat_i;
|
||||
3'b010 : ctr <= #1 wb_dat_i;
|
||||
3'b011 : txr <= #1 wb_dat_i;
|
||||
default: ;
|
||||
endcase
|
||||
|
||||
// generate command register (special case)
|
||||
always @(posedge wb_clk_i or negedge rst_i)
|
||||
if (~rst_i)
|
||||
cr <= #1 8'h0;
|
||||
else if (wb_rst_i)
|
||||
cr <= #1 8'h0;
|
||||
else if (wb_wacc)
|
||||
begin
|
||||
if (core_en & (wb_adr_i == 3'b100) )
|
||||
cr <= #1 wb_dat_i;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (done | i2c_al)
|
||||
cr[7:4] <= #1 4'h0; // clear command bits when done
|
||||
// or when aribitration lost
|
||||
cr[2:1] <= #1 2'b0; // reserved bits
|
||||
cr[0] <= #1 2'b0; // clear IRQ_ACK bit
|
||||
end
|
||||
|
||||
|
||||
// decode command register
|
||||
wire sta = cr[7];
|
||||
wire sto = cr[6];
|
||||
wire rd = cr[5];
|
||||
wire wr = cr[4];
|
||||
wire ack = cr[3];
|
||||
wire iack = cr[0];
|
||||
|
||||
// decode control register
|
||||
assign core_en = ctr[7];
|
||||
assign ien = ctr[6];
|
||||
|
||||
// hookup byte controller block
|
||||
i2c_master_byte_ctrl byte_controller (
|
||||
.clk ( wb_clk_i ),
|
||||
.rst ( wb_rst_i ),
|
||||
.nReset ( rst_i ),
|
||||
.ena ( core_en ),
|
||||
.clk_cnt ( prer ),
|
||||
.start ( sta ),
|
||||
.stop ( sto ),
|
||||
.read ( rd ),
|
||||
.write ( wr ),
|
||||
.ack_in ( ack ),
|
||||
.din ( txr ),
|
||||
.cmd_ack ( done ),
|
||||
.ack_out ( irxack ),
|
||||
.dout ( rxr ),
|
||||
.i2c_busy ( i2c_busy ),
|
||||
.i2c_al ( i2c_al ),
|
||||
.scl_i ( scl_pad_i ),
|
||||
.scl_o ( scl_pad_o ),
|
||||
.scl_oen ( scl_padoen_o ),
|
||||
.sda_i ( sda_pad_i ),
|
||||
.sda_o ( sda_pad_o ),
|
||||
.sda_oen ( sda_padoen_o )
|
||||
);
|
||||
|
||||
// status register block + interrupt request signal
|
||||
always @(posedge wb_clk_i or negedge rst_i)
|
||||
if (!rst_i)
|
||||
begin
|
||||
al <= #1 1'b0;
|
||||
rxack <= #1 1'b0;
|
||||
tip <= #1 1'b0;
|
||||
irq_flag <= #1 1'b0;
|
||||
end
|
||||
else if (wb_rst_i)
|
||||
begin
|
||||
al <= #1 1'b0;
|
||||
rxack <= #1 1'b0;
|
||||
tip <= #1 1'b0;
|
||||
irq_flag <= #1 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
al <= #1 i2c_al | (al & ~sta);
|
||||
rxack <= #1 irxack;
|
||||
tip <= #1 (rd | wr);
|
||||
irq_flag <= #1 (done | i2c_al | irq_flag) & ~iack; // interrupt request flag is always generated
|
||||
end
|
||||
|
||||
// generate interrupt request signals
|
||||
always @(posedge wb_clk_i or negedge rst_i)
|
||||
if (!rst_i)
|
||||
wb_inta_o <= #1 1'b0;
|
||||
else if (wb_rst_i)
|
||||
wb_inta_o <= #1 1'b0;
|
||||
else
|
||||
wb_inta_o <= #1 irq_flag && ien; // interrupt signal is only generated when IEN (interrupt enable bit is set)
|
||||
|
||||
// assign status register bits
|
||||
assign sr[7] = rxack;
|
||||
assign sr[6] = i2c_busy;
|
||||
assign sr[5] = al;
|
||||
assign sr[4:2] = 3'h0; // reserved
|
||||
assign sr[1] = tip;
|
||||
assign sr[0] = irq_flag;
|
||||
|
||||
endmodule
|
|
@ -1,2 +0,0 @@
|
|||
`timescale 1ns / 10ps
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ -n "$REMOTE_YOSYS_ROOT" ]; then
|
||||
rsync --exclude=".svn" --exclude="synth.log" --exclude="run-fm.sh" -rv -e "${REMOTE_YOSYS_SSH:-ssh}" "$REMOTE_YOSYS_ROOT"/tests/iwls2005/. .
|
||||
fi
|
||||
|
||||
exec_fm()
|
||||
{
|
||||
dir=$1; top=$2; shift; shift
|
||||
cat > $dir/fm.do <<- EOT
|
||||
set hdlin_ignore_full_case false
|
||||
set hdlin_warn_on_mismatch_message "FMR_ELAB-115 FMR_ELAB-146 FMR_ELAB-147"
|
||||
read_verilog -container r -libname WORK -01 { $* }
|
||||
set_top r:/WORK/$top
|
||||
read_verilog -container i -libname WORK -01 synth.v
|
||||
# read_verilog -container i -technology_library -libname TECH_WORK -01 ../../../techlibs/stdcells_sim.v
|
||||
set_top i:/WORK/$top
|
||||
if ![verify] start_gui exit
|
||||
EOT
|
||||
( cd $dir; fm_shell -64 -file fm.do 2>&1 | tee fm.log; )
|
||||
}
|
||||
|
||||
# cores that validated
|
||||
exec_fm aes_core aes_cipher_top aes_cipher_top.v aes_inv_cipher_top.v aes_inv_sbox.v aes_key_expand_128.v aes_rcon.v aes_sbox.v
|
||||
exec_fm i2c i2c_master_top i2c_master_top.v i2c_master_bit_ctrl.v i2c_master_byte_ctrl.v
|
||||
exec_fm sasc sasc_top sasc_top.v sasc_brg.v sasc_fifo4.v
|
||||
exec_fm simple_spi simple_spi_top simple_spi_top.v fifo4.v
|
||||
exec_fm spi spi_top spi_top.v spi_clgen.v spi_shift.v
|
||||
exec_fm ss_pcm pcm_slv_top pcm_slv_top.v
|
||||
exec_fm systemcaes aes aes.v byte_mixcolum.v keysched.v mixcolum.v sbox.v subbytes.v word_mixcolum.v
|
||||
exec_fm usb_phy usb_phy usb_phy.v usb_rx_phy.v usb_tx_phy.v
|
||||
|
||||
# cores with known problems (the fpu core unfortunately was designed with logic loops)
|
||||
#exec_fm fpu fpu fpu.v except.v post_norm.v pre_norm_fmul.v pre_norm.v primitives.v
|
||||
|
||||
# summary
|
||||
echo; echo
|
||||
for x in */fm.log; do
|
||||
echo -e "${x%/*}\\t$( egrep '^Verification (SUCCEEDED|FAILED)' $x; )"
|
||||
done | expand -t15
|
||||
echo; echo
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
make -C ../..
|
||||
set -x
|
||||
|
||||
vg=""
|
||||
# vg="valgrind --leak-check=full --show-reachable=yes --log-file=valgrind.log"
|
||||
|
||||
cd aes_core
|
||||
time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \
|
||||
aes_cipher_top.v aes_inv_cipher_top.v aes_inv_sbox.v \
|
||||
aes_key_expand_128.v aes_rcon.v aes_sbox.v
|
||||
|
||||
cd ../fpu
|
||||
time $vg ../../../yosys -qt -l synth.log -o synth.v -f "verilog -nolatches" -s ../run-synth.ys \
|
||||
fpu.v except.v post_norm.v pre_norm_fmul.v pre_norm.v primitives.v
|
||||
|
||||
cd ../i2c
|
||||
time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \
|
||||
i2c_master_top.v i2c_master_bit_ctrl.v i2c_master_byte_ctrl.v
|
||||
|
||||
cd ../sasc
|
||||
time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \
|
||||
sasc_top.v sasc_brg.v sasc_fifo4.v
|
||||
|
||||
cd ../simple_spi
|
||||
time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \
|
||||
simple_spi_top.v fifo4.v
|
||||
|
||||
cd ../spi
|
||||
time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \
|
||||
spi_top.v spi_clgen.v spi_shift.v
|
||||
|
||||
cd ../ss_pcm
|
||||
time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \
|
||||
pcm_slv_top.v
|
||||
|
||||
cd ../systemcaes
|
||||
time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \
|
||||
aes.v byte_mixcolum.v keysched.v mixcolum.v sbox.v subbytes.v word_mixcolum.v
|
||||
|
||||
cd ../usb_phy
|
||||
time $vg ../../../yosys -qt -l synth.log -o synth.v -s ../run-synth.ys \
|
||||
usb_phy.v usb_rx_phy.v usb_tx_phy.v
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
hierarchy
|
||||
proc
|
||||
opt
|
||||
memory
|
||||
opt
|
||||
# fsm -norecode
|
||||
# opt
|
||||
techmap
|
||||
opt
|
||||
abc
|
||||
opt
|
|
@ -1,160 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Simple Baud Rate Generator ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/sasc/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: sasc_brg.v,v 1.2 2002/11/08 15:22:49 rudi Exp $
|
||||
//
|
||||
// $Date: 2002/11/08 15:22:49 $
|
||||
// $Revision: 1.2 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: sasc_brg.v,v $
|
||||
// Revision 1.2 2002/11/08 15:22:49 rudi
|
||||
//
|
||||
// Fixed a typo in brg
|
||||
//
|
||||
// Revision 1.1.1.1 2002/09/16 16:16:40 rudi
|
||||
// Initial Checkin
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
`include "timescale.v"
|
||||
|
||||
/*
|
||||
Baud rate Generator
|
||||
==================
|
||||
|
||||
div0 - is the first stage divider
|
||||
Set this to the desired number of cycles less two
|
||||
div1 - is the second stage divider
|
||||
Set this to the actual number of cycles
|
||||
|
||||
Remember you have to generate a baud rate that is 4 higher than what
|
||||
you really want. This is because of the DPLL in the RX section ...
|
||||
|
||||
Example:
|
||||
If your system clock is 50MHz and you want to generate a 9.6 Kbps baud rate:
|
||||
9600*4 = 38400KHz
|
||||
50MHz/38400KHz=1302 or 6*217
|
||||
set div0=4 (6-2) and set div1=217
|
||||
|
||||
*/
|
||||
|
||||
module sasc_brg(clk, rst, div0, div1, sio_ce, sio_ce_x4);
|
||||
input clk;
|
||||
input rst;
|
||||
input [7:0] div0, div1;
|
||||
output sio_ce, sio_ce_x4;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and Registers
|
||||
//
|
||||
|
||||
reg [7:0] ps;
|
||||
reg ps_clr;
|
||||
reg [7:0] br_cnt;
|
||||
reg br_clr;
|
||||
reg sio_ce_x4_r;
|
||||
reg [1:0] cnt;
|
||||
reg sio_ce, sio_ce_x4;
|
||||
reg sio_ce_r ;
|
||||
reg sio_ce_x4_t;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Boud Rate Generator
|
||||
//
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Prescaler
|
||||
always @(posedge clk)
|
||||
if(!rst) ps <= #1 8'h0;
|
||||
else
|
||||
if(ps_clr) ps <= #1 8'h0;
|
||||
else ps <= #1 ps + 8'h1;
|
||||
|
||||
always @(posedge clk)
|
||||
ps_clr <= #1 (ps == div0); // Desired number of cycles less 2
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Oversampled Boud Rate (x4)
|
||||
always @(posedge clk)
|
||||
if(!rst) br_cnt <= #1 8'h0;
|
||||
else
|
||||
if(br_clr) br_cnt <= #1 8'h0;
|
||||
else
|
||||
if(ps_clr) br_cnt <= #1 br_cnt + 8'h1;
|
||||
|
||||
always @(posedge clk)
|
||||
br_clr <= #1 (br_cnt == div1); // Prciese number of PS cycles
|
||||
|
||||
always @(posedge clk)
|
||||
sio_ce_x4_r <= #1 br_clr;
|
||||
|
||||
always @(posedge clk)
|
||||
sio_ce_x4_t <= #1 !sio_ce_x4_r & br_clr;
|
||||
|
||||
always @(posedge clk)
|
||||
sio_ce_x4 <= #1 sio_ce_x4_t;
|
||||
|
||||
// -----------------------------------------------------
|
||||
// Actual Boud rate
|
||||
always @(posedge clk)
|
||||
if(!rst) cnt <= #1 2'h0;
|
||||
else
|
||||
if(!sio_ce_x4_r & br_clr) cnt <= #1 cnt + 2'h1;
|
||||
|
||||
always @(posedge clk)
|
||||
sio_ce_r <= #1 (cnt == 2'h0);
|
||||
|
||||
always @(posedge clk)
|
||||
sio_ce <= #1 !sio_ce_r & (cnt == 2'h0);
|
||||
|
||||
endmodule
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// FIFO 4 entries deep ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/sasc/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: sasc_fifo4.v,v 1.1.1.1 2002/09/16 16:16:41 rudi Exp $
|
||||
//
|
||||
// $Date: 2002/09/16 16:16:41 $
|
||||
// $Revision: 1.1.1.1 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: sasc_fifo4.v,v $
|
||||
// Revision 1.1.1.1 2002/09/16 16:16:41 rudi
|
||||
// Initial Checkin
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
`include "timescale.v"
|
||||
|
||||
// 4 entry deep fast fifo
|
||||
module sasc_fifo4(clk, rst, clr, din, we, dout, re, full, empty);
|
||||
|
||||
input clk, rst;
|
||||
input clr;
|
||||
input [7:0] din;
|
||||
input we;
|
||||
output [7:0] dout;
|
||||
input re;
|
||||
output full, empty;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires
|
||||
//
|
||||
|
||||
reg [7:0] mem[0:3];
|
||||
reg [1:0] wp;
|
||||
reg [1:0] rp;
|
||||
wire [1:0] wp_p1;
|
||||
wire [1:0] wp_p2;
|
||||
wire [1:0] rp_p1;
|
||||
wire full, empty;
|
||||
reg gb;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc Logic
|
||||
//
|
||||
|
||||
always @(posedge clk or negedge rst)
|
||||
if(!rst) wp <= #1 2'h0;
|
||||
else
|
||||
if(clr) wp <= #1 2'h0;
|
||||
else
|
||||
if(we) wp <= #1 wp_p1;
|
||||
|
||||
assign wp_p1 = wp + 2'h1;
|
||||
assign wp_p2 = wp + 2'h2;
|
||||
|
||||
always @(posedge clk or negedge rst)
|
||||
if(!rst) rp <= #1 2'h0;
|
||||
else
|
||||
if(clr) rp <= #1 2'h0;
|
||||
else
|
||||
if(re) rp <= #1 rp_p1;
|
||||
|
||||
assign rp_p1 = rp + 2'h1;
|
||||
|
||||
// Fifo Output
|
||||
assign dout = mem[ rp ];
|
||||
|
||||
// Fifo Input
|
||||
always @(posedge clk)
|
||||
if(we) mem[ wp ] <= #1 din;
|
||||
|
||||
// Status
|
||||
assign empty = (wp == rp) & !gb;
|
||||
assign full = (wp == rp) & gb;
|
||||
|
||||
// Guard Bit ...
|
||||
always @(posedge clk)
|
||||
if(!rst) gb <= #1 1'b0;
|
||||
else
|
||||
if(clr) gb <= #1 1'b0;
|
||||
else
|
||||
if((wp_p1 == rp) & we) gb <= #1 1'b1;
|
||||
else
|
||||
if(re) gb <= #1 1'b0;
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -1,301 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Simple Asynchronous Serial Comm. Device ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/sasc/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: sasc_top.v,v 1.1.1.1 2002/09/16 16:16:42 rudi Exp $
|
||||
//
|
||||
// $Date: 2002/09/16 16:16:42 $
|
||||
// $Revision: 1.1.1.1 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: sasc_top.v,v $
|
||||
// Revision 1.1.1.1 2002/09/16 16:16:42 rudi
|
||||
// Initial Checkin
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
`include "timescale.v"
|
||||
|
||||
/*
|
||||
Serial IO Interface
|
||||
===============================
|
||||
RTS I Request To Send
|
||||
CTS O Clear to send
|
||||
TD I Transmit Data
|
||||
RD O Receive Data
|
||||
*/
|
||||
|
||||
module sasc_top( clk, rst,
|
||||
|
||||
// SIO
|
||||
rxd_i, txd_o, cts_i, rts_o,
|
||||
|
||||
// External Baud Rate Generator
|
||||
sio_ce, sio_ce_x4,
|
||||
|
||||
// Internal Interface
|
||||
din_i, dout_o, re_i, we_i, full_o, empty_o);
|
||||
|
||||
input clk;
|
||||
input rst;
|
||||
input rxd_i;
|
||||
output txd_o;
|
||||
input cts_i;
|
||||
output rts_o;
|
||||
input sio_ce;
|
||||
input sio_ce_x4;
|
||||
input [7:0] din_i;
|
||||
output [7:0] dout_o;
|
||||
input re_i, we_i;
|
||||
output full_o, empty_o;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and Registers
|
||||
//
|
||||
|
||||
parameter START_BIT = 1'b0,
|
||||
STOP_BIT = 1'b1,
|
||||
IDLE_BIT = 1'b1;
|
||||
|
||||
wire [7:0] txd_p;
|
||||
reg load;
|
||||
reg load_r;
|
||||
wire load_e;
|
||||
reg [9:0] hold_reg;
|
||||
wire txf_empty;
|
||||
reg txd_o;
|
||||
reg shift_en;
|
||||
reg [3:0] tx_bit_cnt;
|
||||
reg rxd_s, rxd_r;
|
||||
wire start;
|
||||
reg [3:0] rx_bit_cnt;
|
||||
reg rx_go;
|
||||
reg [9:0] rxr;
|
||||
reg rx_valid, rx_valid_r;
|
||||
wire rx_we;
|
||||
wire rxf_full;
|
||||
reg rts_o;
|
||||
reg txf_empty_r;
|
||||
reg shift_en_r;
|
||||
reg rxd_r1, rxd_r2;
|
||||
wire lock_en;
|
||||
reg change;
|
||||
reg rx_sio_ce_d, rx_sio_ce_r1, rx_sio_ce_r2, rx_sio_ce;
|
||||
reg [1:0] dpll_state, dpll_next_state;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IO Fifo's
|
||||
//
|
||||
|
||||
sasc_fifo4 tx_fifo( .clk( clk ),
|
||||
.rst( rst ),
|
||||
.clr( 1'b0 ),
|
||||
.din( din_i ),
|
||||
.we( we_i ),
|
||||
.dout( txd_p ),
|
||||
.re( load_e ),
|
||||
.full( full_o ),
|
||||
.empty( txf_empty )
|
||||
);
|
||||
|
||||
sasc_fifo4 rx_fifo( .clk( clk ),
|
||||
.rst( rst ),
|
||||
.clr( 1'b0 ),
|
||||
.din( rxr[9:2] ),
|
||||
.we( rx_we ),
|
||||
.dout( dout_o ),
|
||||
.re( re_i ),
|
||||
.full( rxf_full ),
|
||||
.empty( empty_o )
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Transmit Logic
|
||||
//
|
||||
always @(posedge clk)
|
||||
if(!rst) txf_empty_r <= #1 1'b1;
|
||||
else
|
||||
if(sio_ce) txf_empty_r <= #1 txf_empty;
|
||||
|
||||
always @(posedge clk)
|
||||
load <= #1 !txf_empty_r & !shift_en & !cts_i;
|
||||
|
||||
always @(posedge clk)
|
||||
load_r <= #1 load;
|
||||
|
||||
assign load_e = load & sio_ce;
|
||||
|
||||
always @(posedge clk)
|
||||
if(load_e) hold_reg <= #1 {STOP_BIT, txd_p, START_BIT};
|
||||
else
|
||||
if(shift_en & sio_ce) hold_reg <= #1 {IDLE_BIT, hold_reg[9:1]};
|
||||
|
||||
always @(posedge clk)
|
||||
if(!rst) txd_o <= #1 IDLE_BIT;
|
||||
else
|
||||
if(sio_ce)
|
||||
if(shift_en | shift_en_r) txd_o <= #1 hold_reg[0];
|
||||
else txd_o <= #1 IDLE_BIT;
|
||||
|
||||
always @(posedge clk)
|
||||
if(!rst) tx_bit_cnt <= #1 4'h9;
|
||||
else
|
||||
if(load_e) tx_bit_cnt <= #1 4'h0;
|
||||
else
|
||||
if(shift_en & sio_ce) tx_bit_cnt <= #1 tx_bit_cnt + 4'h1;
|
||||
|
||||
always @(posedge clk)
|
||||
shift_en <= #1 (tx_bit_cnt != 4'h9);
|
||||
|
||||
always @(posedge clk)
|
||||
if(!rst) shift_en_r <= #1 1'b0;
|
||||
else
|
||||
if(sio_ce) shift_en_r <= #1 shift_en;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Recieve Logic
|
||||
//
|
||||
|
||||
always @(posedge clk)
|
||||
rxd_s <= #1 rxd_i;
|
||||
|
||||
always @(posedge clk)
|
||||
rxd_r <= #1 rxd_s;
|
||||
|
||||
assign start = (rxd_r == IDLE_BIT) & (rxd_s == START_BIT);
|
||||
|
||||
always @(posedge clk)
|
||||
if(!rst) rx_bit_cnt <= #1 4'ha;
|
||||
else
|
||||
if(!rx_go & start) rx_bit_cnt <= #1 4'h0;
|
||||
else
|
||||
if(rx_go & rx_sio_ce) rx_bit_cnt <= #1 rx_bit_cnt + 4'h1;
|
||||
|
||||
always @(posedge clk)
|
||||
rx_go <= #1 (rx_bit_cnt != 4'ha);
|
||||
|
||||
always @(posedge clk)
|
||||
rx_valid <= #1 (rx_bit_cnt == 4'h9);
|
||||
|
||||
always @(posedge clk)
|
||||
rx_valid_r <= #1 rx_valid;
|
||||
|
||||
assign rx_we = !rx_valid_r & rx_valid & !rxf_full;
|
||||
|
||||
always @(posedge clk)
|
||||
if(rx_go & rx_sio_ce) rxr <= {rxd_s, rxr[9:1]};
|
||||
|
||||
always @(posedge clk)
|
||||
rts_o <= #1 rxf_full;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Reciever DPLL
|
||||
//
|
||||
|
||||
// Uses 4x baud clock to lock to incoming stream
|
||||
|
||||
// Edge detector
|
||||
always @(posedge clk)
|
||||
if(sio_ce_x4) rxd_r1 <= #1 rxd_s;
|
||||
|
||||
always @(posedge clk)
|
||||
if(sio_ce_x4) rxd_r2 <= #1 rxd_r1;
|
||||
|
||||
always @(posedge clk)
|
||||
if(!rst) change <= #1 1'b0;
|
||||
else
|
||||
if(rxd_r != rxd_s) change <= #1 1'b1;
|
||||
else
|
||||
if(sio_ce_x4) change <= #1 1'b0;
|
||||
|
||||
// DPLL FSM
|
||||
always @(posedge clk or negedge rst)
|
||||
if(!rst) dpll_state <= #1 2'h1;
|
||||
else
|
||||
if(sio_ce_x4) dpll_state <= #1 dpll_next_state;
|
||||
|
||||
always @(dpll_state or change)
|
||||
begin
|
||||
rx_sio_ce_d = 1'b0;
|
||||
case(dpll_state)
|
||||
2'h0:
|
||||
if(change) dpll_next_state = 3'h0;
|
||||
else dpll_next_state = 3'h1;
|
||||
2'h1:begin
|
||||
rx_sio_ce_d = 1'b1;
|
||||
if(change) dpll_next_state = 3'h3;
|
||||
else dpll_next_state = 3'h2;
|
||||
end
|
||||
2'h2:
|
||||
if(change) dpll_next_state = 3'h0;
|
||||
else dpll_next_state = 3'h3;
|
||||
2'h3:
|
||||
if(change) dpll_next_state = 3'h0;
|
||||
else dpll_next_state = 3'h0;
|
||||
endcase
|
||||
end
|
||||
|
||||
// Compensate for sync registers at the input - allign sio
|
||||
// clock enable to be in the middle between two bit changes ...
|
||||
always @(posedge clk)
|
||||
rx_sio_ce_r1 <= #1 rx_sio_ce_d;
|
||||
|
||||
always @(posedge clk)
|
||||
rx_sio_ce_r2 <= #1 rx_sio_ce_r1;
|
||||
|
||||
always @(posedge clk)
|
||||
rx_sio_ce <= #1 rx_sio_ce_r1 & !rx_sio_ce_r2;
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -1 +0,0 @@
|
|||
`timescale 1ns / 10ps
|
|
@ -1,134 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// FIFO 4 entries deep ////
|
||||
//// ////
|
||||
//// Authors: Rudolf Usselmann, Richard Herveille ////
|
||||
//// rudi@asics.ws richard@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Download from: http://www.opencores.org/projects/sasc ////
|
||||
//// http://www.opencores.org/projects/simple_spi ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2002 Rudolf Usselmann, Richard Herveille ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws, richard@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: fifo4.v,v 1.1.1.1 2002/12/22 16:07:14 rherveille Exp $
|
||||
//
|
||||
// $Date: 2002/12/22 16:07:14 $
|
||||
// $Revision: 1.1.1.1 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: fifo4.v,v $
|
||||
// Revision 1.1.1.1 2002/12/22 16:07:14 rherveille
|
||||
// Initial release
|
||||
//
|
||||
//
|
||||
|
||||
// synopsys translate_off
|
||||
`include "timescale.v"
|
||||
// synopsys translate_on
|
||||
|
||||
|
||||
// 4 entry deep fast fifo
|
||||
module fifo4(clk, rst, clr, din, we, dout, re, full, empty);
|
||||
|
||||
parameter dw = 8;
|
||||
|
||||
input clk, rst;
|
||||
input clr;
|
||||
input [dw:1] din;
|
||||
input we;
|
||||
output [dw:1] dout;
|
||||
input re;
|
||||
output full, empty;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires
|
||||
//
|
||||
|
||||
reg [dw:1] mem[0:3];
|
||||
reg [1:0] wp;
|
||||
reg [1:0] rp;
|
||||
wire [1:0] wp_p1;
|
||||
wire [1:0] wp_p2;
|
||||
wire [1:0] rp_p1;
|
||||
wire full, empty;
|
||||
reg gb;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc Logic
|
||||
//
|
||||
|
||||
always @(posedge clk or negedge rst)
|
||||
if(!rst) wp <= #1 2'h0;
|
||||
else
|
||||
if(clr) wp <= #1 2'h0;
|
||||
else
|
||||
if(we) wp <= #1 wp_p1;
|
||||
|
||||
assign wp_p1 = wp + 2'h1;
|
||||
assign wp_p2 = wp + 2'h2;
|
||||
|
||||
always @(posedge clk or negedge rst)
|
||||
if(!rst) rp <= #1 2'h0;
|
||||
else
|
||||
if(clr) rp <= #1 2'h0;
|
||||
else
|
||||
if(re) rp <= #1 rp_p1;
|
||||
|
||||
assign rp_p1 = rp + 2'h1;
|
||||
|
||||
// Fifo Output
|
||||
assign dout = mem[ rp ];
|
||||
|
||||
// Fifo Input
|
||||
always @(posedge clk)
|
||||
if(we) mem[ wp ] <= #1 din;
|
||||
|
||||
// Status
|
||||
assign empty = (wp == rp) & !gb;
|
||||
assign full = (wp == rp) & gb;
|
||||
|
||||
// Guard Bit ...
|
||||
always @(posedge clk)
|
||||
if(!rst) gb <= #1 1'b0;
|
||||
else
|
||||
if(clr) gb <= #1 1'b0;
|
||||
else
|
||||
if((wp_p1 == rp) & we) gb <= #1 1'b1;
|
||||
else
|
||||
if(re) gb <= #1 1'b0;
|
||||
|
||||
endmodule
|
|
@ -1,329 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// OpenCores MC68HC11E based SPI interface ////
|
||||
//// ////
|
||||
//// Author: Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// www.asics.ws ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2002 Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: simple_spi_top.v,v 1.5 2004/02/28 15:59:50 rherveille Exp $
|
||||
//
|
||||
// $Date: 2004/02/28 15:59:50 $
|
||||
// $Revision: 1.5 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: simple_spi_top.v,v $
|
||||
// Revision 1.5 2004/02/28 15:59:50 rherveille
|
||||
// Fixed SCK_O generation bug.
|
||||
// This resulted in a major rewrite of the serial interface engine.
|
||||
//
|
||||
// Revision 1.4 2003/08/01 11:41:54 rherveille
|
||||
// Fixed some timing bugs.
|
||||
//
|
||||
// Revision 1.3 2003/01/09 16:47:59 rherveille
|
||||
// Updated clkcnt size and decoding due to new SPR bit assignments.
|
||||
//
|
||||
// Revision 1.2 2003/01/07 13:29:52 rherveille
|
||||
// Changed SPR bits coding.
|
||||
//
|
||||
// Revision 1.1.1.1 2002/12/22 16:07:15 rherveille
|
||||
// Initial release
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Motorola MC68HC11E based SPI interface
|
||||
//
|
||||
// Currently only MASTER mode is supported
|
||||
//
|
||||
|
||||
// synopsys translate_off
|
||||
`include "timescale.v"
|
||||
// synopsys translate_on
|
||||
|
||||
module simple_spi_top(
|
||||
// 8bit WISHBONE bus slave interface
|
||||
input wire clk_i, // clock
|
||||
input wire rst_i, // reset (asynchronous active low)
|
||||
input wire cyc_i, // cycle
|
||||
input wire stb_i, // strobe
|
||||
input wire [1:0] adr_i, // address
|
||||
input wire we_i, // write enable
|
||||
input wire [7:0] dat_i, // data input
|
||||
output reg [7:0] dat_o, // data output
|
||||
output reg ack_o, // normal bus termination
|
||||
output reg inta_o, // interrupt output
|
||||
|
||||
// SPI port
|
||||
output reg sck_o, // serial clock output
|
||||
output wire mosi_o, // MasterOut SlaveIN
|
||||
input wire miso_i // MasterIn SlaveOut
|
||||
);
|
||||
|
||||
//
|
||||
// Module body
|
||||
//
|
||||
reg [7:0] spcr; // Serial Peripheral Control Register ('HC11 naming)
|
||||
wire [7:0] spsr; // Serial Peripheral Status register ('HC11 naming)
|
||||
reg [7:0] sper; // Serial Peripheral Extension register
|
||||
reg [7:0] treg, rreg; // Transmit/Receive register
|
||||
|
||||
// fifo signals
|
||||
wire [7:0] rfdout;
|
||||
reg wfre, rfwe;
|
||||
wire rfre, rffull, rfempty;
|
||||
wire [7:0] wfdout;
|
||||
wire wfwe, wffull, wfempty;
|
||||
|
||||
// misc signals
|
||||
wire tirq; // transfer interrupt (selected number of transfers done)
|
||||
wire wfov; // write fifo overrun (writing while fifo full)
|
||||
reg [1:0] state; // statemachine state
|
||||
reg [2:0] bcnt;
|
||||
|
||||
//
|
||||
// Wishbone interface
|
||||
wire wb_acc = cyc_i & stb_i; // WISHBONE access
|
||||
wire wb_wr = wb_acc & we_i; // WISHBONE write access
|
||||
|
||||
// dat_i
|
||||
always @(posedge clk_i or negedge rst_i)
|
||||
if (~rst_i)
|
||||
begin
|
||||
spcr <= #1 8'h10; // set master bit
|
||||
sper <= #1 8'h00;
|
||||
end
|
||||
else if (wb_wr)
|
||||
begin
|
||||
if (adr_i == 2'b00)
|
||||
spcr <= #1 dat_i | 8'h10; // always set master bit
|
||||
|
||||
if (adr_i == 2'b11)
|
||||
sper <= #1 dat_i;
|
||||
end
|
||||
|
||||
// write fifo
|
||||
assign wfwe = wb_acc & (adr_i == 2'b10) & ack_o & we_i;
|
||||
assign wfov = wfwe & wffull;
|
||||
|
||||
// dat_o
|
||||
always @(posedge clk_i)
|
||||
case(adr_i) // synopsys full_case parallel_case
|
||||
2'b00: dat_o <= #1 spcr;
|
||||
2'b01: dat_o <= #1 spsr;
|
||||
2'b10: dat_o <= #1 rfdout;
|
||||
2'b11: dat_o <= #1 sper;
|
||||
endcase
|
||||
|
||||
// read fifo
|
||||
assign rfre = wb_acc & (adr_i == 2'b10) & ack_o & ~we_i;
|
||||
|
||||
// ack_o
|
||||
always @(posedge clk_i or negedge rst_i)
|
||||
if (~rst_i)
|
||||
ack_o <= #1 1'b0;
|
||||
else
|
||||
ack_o <= #1 wb_acc & !ack_o;
|
||||
|
||||
// decode Serial Peripheral Control Register
|
||||
wire spie = spcr[7]; // Interrupt enable bit
|
||||
wire spe = spcr[6]; // System Enable bit
|
||||
wire dwom = spcr[5]; // Port D Wired-OR Mode Bit
|
||||
wire mstr = spcr[4]; // Master Mode Select Bit
|
||||
wire cpol = spcr[3]; // Clock Polarity Bit
|
||||
wire cpha = spcr[2]; // Clock Phase Bit
|
||||
wire [1:0] spr = spcr[1:0]; // Clock Rate Select Bits
|
||||
|
||||
// decode Serial Peripheral Extension Register
|
||||
wire [1:0] icnt = sper[7:6]; // interrupt on transfer count
|
||||
wire [1:0] spre = sper[1:0]; // extended clock rate select
|
||||
|
||||
wire [3:0] espr = {spre, spr};
|
||||
|
||||
// generate status register
|
||||
wire wr_spsr = wb_wr & (adr_i == 2'b01);
|
||||
|
||||
reg spif;
|
||||
always @(posedge clk_i)
|
||||
if (~spe)
|
||||
spif <= #1 1'b0;
|
||||
else
|
||||
spif <= #1 (tirq | spif) & ~(wr_spsr & dat_i[7]);
|
||||
|
||||
reg wcol;
|
||||
always @(posedge clk_i)
|
||||
if (~spe)
|
||||
wcol <= #1 1'b0;
|
||||
else
|
||||
wcol <= #1 (wfov | wcol) & ~(wr_spsr & dat_i[6]);
|
||||
|
||||
assign spsr[7] = spif;
|
||||
assign spsr[6] = wcol;
|
||||
assign spsr[5:4] = 2'b00;
|
||||
assign spsr[3] = wffull;
|
||||
assign spsr[2] = wfempty;
|
||||
assign spsr[1] = rffull;
|
||||
assign spsr[0] = rfempty;
|
||||
|
||||
|
||||
// generate IRQ output (inta_o)
|
||||
always @(posedge clk_i)
|
||||
inta_o <= #1 spif & spie;
|
||||
|
||||
//
|
||||
// hookup read/write buffer fifo
|
||||
fifo4 #(8)
|
||||
rfifo(
|
||||
.clk ( clk_i ),
|
||||
.rst ( rst_i ),
|
||||
.clr ( ~spe ),
|
||||
.din ( treg ),
|
||||
.we ( rfwe ),
|
||||
.dout ( rfdout ),
|
||||
.re ( rfre ),
|
||||
.full ( rffull ),
|
||||
.empty ( rfempty )
|
||||
),
|
||||
wfifo(
|
||||
.clk ( clk_i ),
|
||||
.rst ( rst_i ),
|
||||
.clr ( ~spe ),
|
||||
.din ( dat_i ),
|
||||
.we ( wfwe ),
|
||||
.dout ( wfdout ),
|
||||
.re ( wfre ),
|
||||
.full ( wffull ),
|
||||
.empty ( wfempty )
|
||||
);
|
||||
|
||||
//
|
||||
// generate clk divider
|
||||
reg [11:0] clkcnt;
|
||||
always @(posedge clk_i)
|
||||
if(spe & (|clkcnt & |state))
|
||||
clkcnt <= #1 clkcnt - 11'h1;
|
||||
else
|
||||
case (espr) // synopsys full_case parallel_case
|
||||
4'b0000: clkcnt <= #1 12'h0; // 2 -- original M68HC11 coding
|
||||
4'b0001: clkcnt <= #1 12'h1; // 4 -- original M68HC11 coding
|
||||
4'b0010: clkcnt <= #1 12'h3; // 16 -- original M68HC11 coding
|
||||
4'b0011: clkcnt <= #1 12'hf; // 32 -- original M68HC11 coding
|
||||
4'b0100: clkcnt <= #1 12'h1f; // 8
|
||||
4'b0101: clkcnt <= #1 12'h7; // 64
|
||||
4'b0110: clkcnt <= #1 12'h3f; // 128
|
||||
4'b0111: clkcnt <= #1 12'h7f; // 256
|
||||
4'b1000: clkcnt <= #1 12'hff; // 512
|
||||
4'b1001: clkcnt <= #1 12'h1ff; // 1024
|
||||
4'b1010: clkcnt <= #1 12'h3ff; // 2048
|
||||
4'b1011: clkcnt <= #1 12'h7ff; // 4096
|
||||
endcase
|
||||
|
||||
// generate clock enable signal
|
||||
wire ena = ~|clkcnt;
|
||||
|
||||
// transfer statemachine
|
||||
always @(posedge clk_i)
|
||||
if (~spe)
|
||||
begin
|
||||
state <= #1 2'b00; // idle
|
||||
bcnt <= #1 3'h0;
|
||||
treg <= #1 8'h00;
|
||||
wfre <= #1 1'b0;
|
||||
rfwe <= #1 1'b0;
|
||||
sck_o <= #1 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
wfre <= #1 1'b0;
|
||||
rfwe <= #1 1'b0;
|
||||
|
||||
case (state) //synopsys full_case parallel_case
|
||||
2'b00: // idle state
|
||||
begin
|
||||
bcnt <= #1 3'h7; // set transfer counter
|
||||
treg <= #1 wfdout; // load transfer register
|
||||
sck_o <= #1 cpol; // set sck
|
||||
|
||||
if (~wfempty) begin
|
||||
wfre <= #1 1'b1;
|
||||
state <= #1 2'b01;
|
||||
if (cpha) sck_o <= #1 ~sck_o;
|
||||
end
|
||||
end
|
||||
|
||||
2'b01: // clock-phase2, next data
|
||||
if (ena) begin
|
||||
sck_o <= #1 ~sck_o;
|
||||
state <= #1 2'b11;
|
||||
end
|
||||
|
||||
2'b11: // clock phase1
|
||||
if (ena) begin
|
||||
treg <= #1 {treg[6:0], miso_i};
|
||||
bcnt <= #1 bcnt -3'h1;
|
||||
|
||||
if (~|bcnt) begin
|
||||
state <= #1 2'b00;
|
||||
sck_o <= #1 cpol;
|
||||
rfwe <= #1 1'b1;
|
||||
end else begin
|
||||
state <= #1 2'b01;
|
||||
sck_o <= #1 ~sck_o;
|
||||
end
|
||||
end
|
||||
|
||||
2'b10: state <= #1 2'b00;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign mosi_o = treg[7];
|
||||
|
||||
|
||||
// count number of transfers (for interrupt generation)
|
||||
reg [1:0] tcnt; // transfer count
|
||||
always @(posedge clk_i)
|
||||
if (~spe)
|
||||
tcnt <= #1 icnt;
|
||||
else if (rfwe) // rfwe gets asserted when all bits have been transfered
|
||||
if (|tcnt)
|
||||
tcnt <= #1 tcnt - 2'h1;
|
||||
else
|
||||
tcnt <= #1 icnt;
|
||||
|
||||
assign tirq = ~|tcnt & rfwe;
|
||||
|
||||
endmodule
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// spi_clgen.v ////
|
||||
//// ////
|
||||
//// This file is part of the SPI IP core project ////
|
||||
//// http://www.opencores.org/projects/spi/ ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Simon Srot (simons@opencores.org) ////
|
||||
//// ////
|
||||
//// All additional information is avaliable in the Readme.txt ////
|
||||
//// file. ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2002 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 ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "spi_defines.v"
|
||||
`include "timescale.v"
|
||||
|
||||
module spi_clgen (clk_in, rst, go, enable, last_clk, divider, clk_out, pos_edge, neg_edge);
|
||||
|
||||
parameter Tp = 1;
|
||||
|
||||
input clk_in; // input clock (system clock)
|
||||
input rst; // reset
|
||||
input enable; // clock enable
|
||||
input go; // start transfer
|
||||
input last_clk; // last clock
|
||||
input [`SPI_DIVIDER_LEN-1:0] divider; // clock divider (output clock is divided by this value)
|
||||
output clk_out; // output clock
|
||||
output pos_edge; // pulse marking positive edge of clk_out
|
||||
output neg_edge; // pulse marking negative edge of clk_out
|
||||
|
||||
reg clk_out;
|
||||
reg pos_edge;
|
||||
reg neg_edge;
|
||||
|
||||
reg [`SPI_DIVIDER_LEN-1:0] cnt; // clock counter
|
||||
wire cnt_zero; // conter is equal to zero
|
||||
wire cnt_one; // conter is equal to one
|
||||
|
||||
|
||||
assign cnt_zero = cnt == {`SPI_DIVIDER_LEN{1'b0}};
|
||||
assign cnt_one = cnt == {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
|
||||
|
||||
// Counter counts half period
|
||||
always @(posedge clk_in or posedge rst)
|
||||
begin
|
||||
if(rst)
|
||||
cnt <= #Tp {`SPI_DIVIDER_LEN{1'b1}};
|
||||
else
|
||||
begin
|
||||
if(!enable || cnt_zero)
|
||||
cnt <= #Tp divider;
|
||||
else
|
||||
cnt <= #Tp cnt - {{`SPI_DIVIDER_LEN-1{1'b0}}, 1'b1};
|
||||
end
|
||||
end
|
||||
|
||||
// clk_out is asserted every other half period
|
||||
always @(posedge clk_in or posedge rst)
|
||||
begin
|
||||
if(rst)
|
||||
clk_out <= #Tp 1'b0;
|
||||
else
|
||||
clk_out <= #Tp (enable && cnt_zero && (!last_clk || clk_out)) ? ~clk_out : clk_out;
|
||||
end
|
||||
|
||||
// Pos and neg edge signals
|
||||
always @(posedge clk_in or posedge rst)
|
||||
begin
|
||||
if(rst)
|
||||
begin
|
||||
pos_edge <= #Tp 1'b0;
|
||||
neg_edge <= #Tp 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
pos_edge <= #Tp (enable && !clk_out && cnt_one) || (!(|divider) && clk_out) || (!(|divider) && go && !enable);
|
||||
neg_edge <= #Tp (enable && clk_out && cnt_one) || (!(|divider) && !clk_out && enable);
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
@ -1,159 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// spi_define.v ////
|
||||
//// ////
|
||||
//// This file is part of the SPI IP core project ////
|
||||
//// http://www.opencores.org/projects/spi/ ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Simon Srot (simons@opencores.org) ////
|
||||
//// ////
|
||||
//// All additional information is avaliable in the Readme.txt ////
|
||||
//// file. ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2002 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 ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Number of bits used for devider register. If used in system with
|
||||
// low frequency of system clock this can be reduced.
|
||||
// Use SPI_DIVIDER_LEN for fine tuning theexact number.
|
||||
//
|
||||
//`define SPI_DIVIDER_LEN_8
|
||||
`define SPI_DIVIDER_LEN_16
|
||||
//`define SPI_DIVIDER_LEN_24
|
||||
//`define SPI_DIVIDER_LEN_32
|
||||
|
||||
`ifdef SPI_DIVIDER_LEN_8
|
||||
`define SPI_DIVIDER_LEN 8 // Can be set from 1 to 8
|
||||
`endif
|
||||
`ifdef SPI_DIVIDER_LEN_16
|
||||
`define SPI_DIVIDER_LEN 16 // Can be set from 9 to 16
|
||||
`endif
|
||||
`ifdef SPI_DIVIDER_LEN_24
|
||||
`define SPI_DIVIDER_LEN 24 // Can be set from 17 to 24
|
||||
`endif
|
||||
`ifdef SPI_DIVIDER_LEN_32
|
||||
`define SPI_DIVIDER_LEN 32 // Can be set from 25 to 32
|
||||
`endif
|
||||
|
||||
//
|
||||
// Maximum nuber of bits that can be send/received at once.
|
||||
// Use SPI_MAX_CHAR for fine tuning the exact number, when using
|
||||
// SPI_MAX_CHAR_32, SPI_MAX_CHAR_24, SPI_MAX_CHAR_16, SPI_MAX_CHAR_8.
|
||||
//
|
||||
`define SPI_MAX_CHAR_128
|
||||
//`define SPI_MAX_CHAR_64
|
||||
//`define SPI_MAX_CHAR_32
|
||||
//`define SPI_MAX_CHAR_24
|
||||
//`define SPI_MAX_CHAR_16
|
||||
//`define SPI_MAX_CHAR_8
|
||||
|
||||
`ifdef SPI_MAX_CHAR_128
|
||||
`define SPI_MAX_CHAR 128 // Can only be set to 128
|
||||
`define SPI_CHAR_LEN_BITS 7
|
||||
`endif
|
||||
`ifdef SPI_MAX_CHAR_64
|
||||
`define SPI_MAX_CHAR 64 // Can only be set to 64
|
||||
`define SPI_CHAR_LEN_BITS 6
|
||||
`endif
|
||||
`ifdef SPI_MAX_CHAR_32
|
||||
`define SPI_MAX_CHAR 32 // Can be set from 25 to 32
|
||||
`define SPI_CHAR_LEN_BITS 5
|
||||
`endif
|
||||
`ifdef SPI_MAX_CHAR_24
|
||||
`define SPI_MAX_CHAR 24 // Can be set from 17 to 24
|
||||
`define SPI_CHAR_LEN_BITS 5
|
||||
`endif
|
||||
`ifdef SPI_MAX_CHAR_16
|
||||
`define SPI_MAX_CHAR 16 // Can be set from 9 to 16
|
||||
`define SPI_CHAR_LEN_BITS 4
|
||||
`endif
|
||||
`ifdef SPI_MAX_CHAR_8
|
||||
`define SPI_MAX_CHAR 8 // Can be set from 1 to 8
|
||||
`define SPI_CHAR_LEN_BITS 3
|
||||
`endif
|
||||
|
||||
//
|
||||
// Number of device select signals. Use SPI_SS_NB for fine tuning the
|
||||
// exact number.
|
||||
//
|
||||
`define SPI_SS_NB_8
|
||||
//`define SPI_SS_NB_16
|
||||
//`define SPI_SS_NB_24
|
||||
//`define SPI_SS_NB_32
|
||||
|
||||
`ifdef SPI_SS_NB_8
|
||||
`define SPI_SS_NB 8 // Can be set from 1 to 8
|
||||
`endif
|
||||
`ifdef SPI_SS_NB_16
|
||||
`define SPI_SS_NB 16 // Can be set from 9 to 16
|
||||
`endif
|
||||
`ifdef SPI_SS_NB_24
|
||||
`define SPI_SS_NB 24 // Can be set from 17 to 24
|
||||
`endif
|
||||
`ifdef SPI_SS_NB_32
|
||||
`define SPI_SS_NB 32 // Can be set from 25 to 32
|
||||
`endif
|
||||
|
||||
//
|
||||
// Bits of WISHBONE address used for partial decoding of SPI registers.
|
||||
//
|
||||
`define SPI_OFS_BITS 4:2
|
||||
|
||||
//
|
||||
// Register offset
|
||||
//
|
||||
`define SPI_RX_0 0
|
||||
`define SPI_RX_1 1
|
||||
`define SPI_RX_2 2
|
||||
`define SPI_RX_3 3
|
||||
`define SPI_TX_0 0
|
||||
`define SPI_TX_1 1
|
||||
`define SPI_TX_2 2
|
||||
`define SPI_TX_3 3
|
||||
`define SPI_CTRL 4
|
||||
`define SPI_DEVIDE 5
|
||||
`define SPI_SS 6
|
||||
|
||||
//
|
||||
// Number of bits in ctrl register
|
||||
//
|
||||
`define SPI_CTRL_BIT_NB 14
|
||||
|
||||
//
|
||||
// Control register bit position
|
||||
//
|
||||
`define SPI_CTRL_ASS 13
|
||||
`define SPI_CTRL_IE 12
|
||||
`define SPI_CTRL_LSB 11
|
||||
`define SPI_CTRL_TX_NEGEDGE 10
|
||||
`define SPI_CTRL_RX_NEGEDGE 9
|
||||
`define SPI_CTRL_GO 8
|
||||
`define SPI_CTRL_RES_1 7
|
||||
`define SPI_CTRL_CHAR_LEN 6:0
|
||||
|
|
@ -1,238 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// spi_shift.v ////
|
||||
//// ////
|
||||
//// This file is part of the SPI IP core project ////
|
||||
//// http://www.opencores.org/projects/spi/ ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Simon Srot (simons@opencores.org) ////
|
||||
//// ////
|
||||
//// All additional information is avaliable in the Readme.txt ////
|
||||
//// file. ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2002 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 ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "spi_defines.v"
|
||||
`include "timescale.v"
|
||||
|
||||
module spi_shift (clk, rst, latch, byte_sel, len, lsb, go,
|
||||
pos_edge, neg_edge, rx_negedge, tx_negedge,
|
||||
tip, last,
|
||||
p_in, p_out, s_clk, s_in, s_out);
|
||||
|
||||
parameter Tp = 1;
|
||||
|
||||
input clk; // system clock
|
||||
input rst; // reset
|
||||
input [3:0] latch; // latch signal for storing the data in shift register
|
||||
input [3:0] byte_sel; // byte select signals for storing the data in shift register
|
||||
input [`SPI_CHAR_LEN_BITS-1:0] len; // data len in bits (minus one)
|
||||
input lsb; // lbs first on the line
|
||||
input go; // start stansfer
|
||||
input pos_edge; // recognize posedge of sclk
|
||||
input neg_edge; // recognize negedge of sclk
|
||||
input rx_negedge; // s_in is sampled on negative edge
|
||||
input tx_negedge; // s_out is driven on negative edge
|
||||
output tip; // transfer in progress
|
||||
output last; // last bit
|
||||
input [31:0] p_in; // parallel in
|
||||
output [`SPI_MAX_CHAR-1:0] p_out; // parallel out
|
||||
input s_clk; // serial clock
|
||||
input s_in; // serial in
|
||||
output s_out; // serial out
|
||||
|
||||
reg s_out;
|
||||
reg tip;
|
||||
|
||||
reg [`SPI_CHAR_LEN_BITS:0] cnt; // data bit count
|
||||
reg [`SPI_MAX_CHAR-1:0] data; // shift register
|
||||
wire [`SPI_CHAR_LEN_BITS:0] tx_bit_pos; // next bit position
|
||||
wire [`SPI_CHAR_LEN_BITS:0] rx_bit_pos; // next bit position
|
||||
wire rx_clk; // rx clock enable
|
||||
wire tx_clk; // tx clock enable
|
||||
|
||||
assign p_out = data;
|
||||
|
||||
assign tx_bit_pos = lsb ? {!(|len), len} - cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1};
|
||||
assign rx_bit_pos = lsb ? {!(|len), len} - (rx_negedge ? cnt + {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1} : cnt) :
|
||||
(rx_negedge ? cnt : cnt - {{`SPI_CHAR_LEN_BITS{1'b0}},1'b1});
|
||||
|
||||
assign last = !(|cnt);
|
||||
|
||||
assign rx_clk = (rx_negedge ? neg_edge : pos_edge) && (!last || s_clk);
|
||||
assign tx_clk = (tx_negedge ? neg_edge : pos_edge) && !last;
|
||||
|
||||
// Character bit counter
|
||||
always @(posedge clk or posedge rst)
|
||||
begin
|
||||
if(rst)
|
||||
cnt <= #Tp {`SPI_CHAR_LEN_BITS+1{1'b0}};
|
||||
else
|
||||
begin
|
||||
if(tip)
|
||||
cnt <= #Tp pos_edge ? (cnt - {{`SPI_CHAR_LEN_BITS{1'b0}}, 1'b1}) : cnt;
|
||||
else
|
||||
cnt <= #Tp !(|len) ? {1'b1, {`SPI_CHAR_LEN_BITS{1'b0}}} : {1'b0, len};
|
||||
end
|
||||
end
|
||||
|
||||
// Transfer in progress
|
||||
always @(posedge clk or posedge rst)
|
||||
begin
|
||||
if(rst)
|
||||
tip <= #Tp 1'b0;
|
||||
else if(go && ~tip)
|
||||
tip <= #Tp 1'b1;
|
||||
else if(tip && last && pos_edge)
|
||||
tip <= #Tp 1'b0;
|
||||
end
|
||||
|
||||
// Sending bits to the line
|
||||
always @(posedge clk or posedge rst)
|
||||
begin
|
||||
if (rst)
|
||||
s_out <= #Tp 1'b0;
|
||||
else
|
||||
s_out <= #Tp (tx_clk || !tip) ? data[tx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] : s_out;
|
||||
end
|
||||
|
||||
// Receiving bits from the line
|
||||
always @(posedge clk or posedge rst)
|
||||
begin
|
||||
if (rst)
|
||||
data <= #Tp {`SPI_MAX_CHAR{1'b0}};
|
||||
`ifdef SPI_MAX_CHAR_128
|
||||
else if (latch[0] && !tip)
|
||||
begin
|
||||
if (byte_sel[3])
|
||||
data[31:24] <= #Tp p_in[31:24];
|
||||
if (byte_sel[2])
|
||||
data[23:16] <= #Tp p_in[23:16];
|
||||
if (byte_sel[1])
|
||||
data[15:8] <= #Tp p_in[15:8];
|
||||
if (byte_sel[0])
|
||||
data[7:0] <= #Tp p_in[7:0];
|
||||
end
|
||||
else if (latch[1] && !tip)
|
||||
begin
|
||||
if (byte_sel[3])
|
||||
data[63:56] <= #Tp p_in[31:24];
|
||||
if (byte_sel[2])
|
||||
data[55:48] <= #Tp p_in[23:16];
|
||||
if (byte_sel[1])
|
||||
data[47:40] <= #Tp p_in[15:8];
|
||||
if (byte_sel[0])
|
||||
data[39:32] <= #Tp p_in[7:0];
|
||||
end
|
||||
else if (latch[2] && !tip)
|
||||
begin
|
||||
if (byte_sel[3])
|
||||
data[95:88] <= #Tp p_in[31:24];
|
||||
if (byte_sel[2])
|
||||
data[87:80] <= #Tp p_in[23:16];
|
||||
if (byte_sel[1])
|
||||
data[79:72] <= #Tp p_in[15:8];
|
||||
if (byte_sel[0])
|
||||
data[71:64] <= #Tp p_in[7:0];
|
||||
end
|
||||
else if (latch[3] && !tip)
|
||||
begin
|
||||
if (byte_sel[3])
|
||||
data[127:120] <= #Tp p_in[31:24];
|
||||
if (byte_sel[2])
|
||||
data[119:112] <= #Tp p_in[23:16];
|
||||
if (byte_sel[1])
|
||||
data[111:104] <= #Tp p_in[15:8];
|
||||
if (byte_sel[0])
|
||||
data[103:96] <= #Tp p_in[7:0];
|
||||
end
|
||||
`else
|
||||
`ifdef SPI_MAX_CHAR_64
|
||||
else if (latch[0] && !tip)
|
||||
begin
|
||||
if (byte_sel[3])
|
||||
data[31:24] <= #Tp p_in[31:24];
|
||||
if (byte_sel[2])
|
||||
data[23:16] <= #Tp p_in[23:16];
|
||||
if (byte_sel[1])
|
||||
data[15:8] <= #Tp p_in[15:8];
|
||||
if (byte_sel[0])
|
||||
data[7:0] <= #Tp p_in[7:0];
|
||||
end
|
||||
else if (latch[1] && !tip)
|
||||
begin
|
||||
if (byte_sel[3])
|
||||
data[63:56] <= #Tp p_in[31:24];
|
||||
if (byte_sel[2])
|
||||
data[55:48] <= #Tp p_in[23:16];
|
||||
if (byte_sel[1])
|
||||
data[47:40] <= #Tp p_in[15:8];
|
||||
if (byte_sel[0])
|
||||
data[39:32] <= #Tp p_in[7:0];
|
||||
end
|
||||
`else
|
||||
else if (latch[0] && !tip)
|
||||
begin
|
||||
`ifdef SPI_MAX_CHAR_8
|
||||
if (byte_sel[0])
|
||||
data[`SPI_MAX_CHAR-1:0] <= #Tp p_in[`SPI_MAX_CHAR-1:0];
|
||||
`endif
|
||||
`ifdef SPI_MAX_CHAR_16
|
||||
if (byte_sel[0])
|
||||
data[7:0] <= #Tp p_in[7:0];
|
||||
if (byte_sel[1])
|
||||
data[`SPI_MAX_CHAR-1:8] <= #Tp p_in[`SPI_MAX_CHAR-1:8];
|
||||
`endif
|
||||
`ifdef SPI_MAX_CHAR_24
|
||||
if (byte_sel[0])
|
||||
data[7:0] <= #Tp p_in[7:0];
|
||||
if (byte_sel[1])
|
||||
data[15:8] <= #Tp p_in[15:8];
|
||||
if (byte_sel[2])
|
||||
data[`SPI_MAX_CHAR-1:16] <= #Tp p_in[`SPI_MAX_CHAR-1:16];
|
||||
`endif
|
||||
`ifdef SPI_MAX_CHAR_32
|
||||
if (byte_sel[0])
|
||||
data[7:0] <= #Tp p_in[7:0];
|
||||
if (byte_sel[1])
|
||||
data[15:8] <= #Tp p_in[15:8];
|
||||
if (byte_sel[2])
|
||||
data[23:16] <= #Tp p_in[23:16];
|
||||
if (byte_sel[3])
|
||||
data[`SPI_MAX_CHAR-1:24] <= #Tp p_in[`SPI_MAX_CHAR-1:24];
|
||||
`endif
|
||||
end
|
||||
`endif
|
||||
`endif
|
||||
else
|
||||
data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] <= #Tp rx_clk ? s_in : data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]];
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -1,287 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// spi_top.v ////
|
||||
//// ////
|
||||
//// This file is part of the SPI IP core project ////
|
||||
//// http://www.opencores.org/projects/spi/ ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Simon Srot (simons@opencores.org) ////
|
||||
//// ////
|
||||
//// All additional information is avaliable in the Readme.txt ////
|
||||
//// file. ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2002 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 ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
`include "spi_defines.v"
|
||||
`include "timescale.v"
|
||||
|
||||
module spi_top
|
||||
(
|
||||
// Wishbone signals
|
||||
wb_clk_i, wb_rst_i, wb_adr_i, wb_dat_i, wb_dat_o, wb_sel_i,
|
||||
wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_err_o, wb_int_o,
|
||||
|
||||
// SPI signals
|
||||
ss_pad_o, sclk_pad_o, mosi_pad_o, miso_pad_i
|
||||
);
|
||||
|
||||
parameter Tp = 1;
|
||||
|
||||
// Wishbone signals
|
||||
input wb_clk_i; // master clock input
|
||||
input wb_rst_i; // synchronous active high reset
|
||||
input [4:0] wb_adr_i; // lower address bits
|
||||
input [32-1:0] wb_dat_i; // databus input
|
||||
output [32-1:0] wb_dat_o; // databus output
|
||||
input [3:0] wb_sel_i; // byte select inputs
|
||||
input wb_we_i; // write enable input
|
||||
input wb_stb_i; // stobe/core select signal
|
||||
input wb_cyc_i; // valid bus cycle input
|
||||
output wb_ack_o; // bus cycle acknowledge output
|
||||
output wb_err_o; // termination w/ error
|
||||
output wb_int_o; // interrupt request signal output
|
||||
|
||||
// SPI signals
|
||||
output [`SPI_SS_NB-1:0] ss_pad_o; // slave select
|
||||
output sclk_pad_o; // serial clock
|
||||
output mosi_pad_o; // master out slave in
|
||||
input miso_pad_i; // master in slave out
|
||||
|
||||
reg [32-1:0] wb_dat_o;
|
||||
reg wb_ack_o;
|
||||
reg wb_int_o;
|
||||
|
||||
// Internal signals
|
||||
reg [`SPI_DIVIDER_LEN-1:0] divider; // Divider register
|
||||
reg [`SPI_CTRL_BIT_NB-1:0] ctrl; // Control and status register
|
||||
reg [`SPI_SS_NB-1:0] ss; // Slave select register
|
||||
reg [32-1:0] wb_dat; // wb data out
|
||||
wire [`SPI_MAX_CHAR-1:0] rx; // Rx register
|
||||
wire rx_negedge; // miso is sampled on negative edge
|
||||
wire tx_negedge; // mosi is driven on negative edge
|
||||
wire [`SPI_CHAR_LEN_BITS-1:0] char_len; // char len
|
||||
wire go; // go
|
||||
wire lsb; // lsb first on line
|
||||
wire ie; // interrupt enable
|
||||
wire ass; // automatic slave select
|
||||
wire spi_divider_sel; // divider register select
|
||||
wire spi_ctrl_sel; // ctrl register select
|
||||
wire [3:0] spi_tx_sel; // tx_l register select
|
||||
wire spi_ss_sel; // ss register select
|
||||
wire tip; // transfer in progress
|
||||
wire pos_edge; // recognize posedge of sclk
|
||||
wire neg_edge; // recognize negedge of sclk
|
||||
wire last_bit; // marks last character bit
|
||||
|
||||
// Address decoder
|
||||
assign spi_divider_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_DEVIDE);
|
||||
assign spi_ctrl_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_CTRL);
|
||||
assign spi_tx_sel[0] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_0);
|
||||
assign spi_tx_sel[1] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_1);
|
||||
assign spi_tx_sel[2] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_2);
|
||||
assign spi_tx_sel[3] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_3);
|
||||
assign spi_ss_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_SS);
|
||||
|
||||
// Read from registers
|
||||
always @(wb_adr_i or rx or ctrl or divider or ss)
|
||||
begin
|
||||
case (wb_adr_i[`SPI_OFS_BITS])
|
||||
`ifdef SPI_MAX_CHAR_128
|
||||
`SPI_RX_0: wb_dat = rx[31:0];
|
||||
`SPI_RX_1: wb_dat = rx[63:32];
|
||||
`SPI_RX_2: wb_dat = rx[95:64];
|
||||
`SPI_RX_3: wb_dat = {{128-`SPI_MAX_CHAR{1'b0}}, rx[`SPI_MAX_CHAR-1:96]};
|
||||
`else
|
||||
`ifdef SPI_MAX_CHAR_64
|
||||
`SPI_RX_0: wb_dat = rx[31:0];
|
||||
`SPI_RX_1: wb_dat = {{64-`SPI_MAX_CHAR{1'b0}}, rx[`SPI_MAX_CHAR-1:32]};
|
||||
`SPI_RX_2: wb_dat = 32'b0;
|
||||
`SPI_RX_3: wb_dat = 32'b0;
|
||||
`else
|
||||
`SPI_RX_0: wb_dat = {{32-`SPI_MAX_CHAR{1'b0}}, rx[`SPI_MAX_CHAR-1:0]};
|
||||
`SPI_RX_1: wb_dat = 32'b0;
|
||||
`SPI_RX_2: wb_dat = 32'b0;
|
||||
`SPI_RX_3: wb_dat = 32'b0;
|
||||
`endif
|
||||
`endif
|
||||
`SPI_CTRL: wb_dat = {{32-`SPI_CTRL_BIT_NB{1'b0}}, ctrl};
|
||||
`SPI_DEVIDE: wb_dat = {{32-`SPI_DIVIDER_LEN{1'b0}}, divider};
|
||||
`SPI_SS: wb_dat = {{32-`SPI_SS_NB{1'b0}}, ss};
|
||||
default: wb_dat = 32'bx;
|
||||
endcase
|
||||
end
|
||||
|
||||
// Wb data out
|
||||
always @(posedge wb_clk_i or posedge wb_rst_i)
|
||||
begin
|
||||
if (wb_rst_i)
|
||||
wb_dat_o <= #Tp 32'b0;
|
||||
else
|
||||
wb_dat_o <= #Tp wb_dat;
|
||||
end
|
||||
|
||||
// Wb acknowledge
|
||||
always @(posedge wb_clk_i or posedge wb_rst_i)
|
||||
begin
|
||||
if (wb_rst_i)
|
||||
wb_ack_o <= #Tp 1'b0;
|
||||
else
|
||||
wb_ack_o <= #Tp wb_cyc_i & wb_stb_i & ~wb_ack_o;
|
||||
end
|
||||
|
||||
// Wb error
|
||||
assign wb_err_o = 1'b0;
|
||||
|
||||
// Interrupt
|
||||
always @(posedge wb_clk_i or posedge wb_rst_i)
|
||||
begin
|
||||
if (wb_rst_i)
|
||||
wb_int_o <= #Tp 1'b0;
|
||||
else if (ie && tip && last_bit && pos_edge)
|
||||
wb_int_o <= #Tp 1'b1;
|
||||
else if (wb_ack_o)
|
||||
wb_int_o <= #Tp 1'b0;
|
||||
end
|
||||
|
||||
// Divider register
|
||||
always @(posedge wb_clk_i or posedge wb_rst_i)
|
||||
begin
|
||||
if (wb_rst_i)
|
||||
divider <= #Tp {`SPI_DIVIDER_LEN{1'b0}};
|
||||
else if (spi_divider_sel && wb_we_i && !tip)
|
||||
begin
|
||||
`ifdef SPI_DIVIDER_LEN_8
|
||||
if (wb_sel_i[0])
|
||||
divider <= #Tp wb_dat_i[`SPI_DIVIDER_LEN-1:0];
|
||||
`endif
|
||||
`ifdef SPI_DIVIDER_LEN_16
|
||||
if (wb_sel_i[0])
|
||||
divider[7:0] <= #Tp wb_dat_i[7:0];
|
||||
if (wb_sel_i[1])
|
||||
divider[`SPI_DIVIDER_LEN-1:8] <= #Tp wb_dat_i[`SPI_DIVIDER_LEN-1:8];
|
||||
`endif
|
||||
`ifdef SPI_DIVIDER_LEN_24
|
||||
if (wb_sel_i[0])
|
||||
divider[7:0] <= #Tp wb_dat_i[7:0];
|
||||
if (wb_sel_i[1])
|
||||
divider[15:8] <= #Tp wb_dat_i[15:8];
|
||||
if (wb_sel_i[2])
|
||||
divider[`SPI_DIVIDER_LEN-1:16] <= #Tp wb_dat_i[`SPI_DIVIDER_LEN-1:16];
|
||||
`endif
|
||||
`ifdef SPI_DIVIDER_LEN_32
|
||||
if (wb_sel_i[0])
|
||||
divider[7:0] <= #Tp wb_dat_i[7:0];
|
||||
if (wb_sel_i[1])
|
||||
divider[15:8] <= #Tp wb_dat_i[15:8];
|
||||
if (wb_sel_i[2])
|
||||
divider[23:16] <= #Tp wb_dat_i[23:16];
|
||||
if (wb_sel_i[3])
|
||||
divider[`SPI_DIVIDER_LEN-1:24] <= #Tp wb_dat_i[`SPI_DIVIDER_LEN-1:24];
|
||||
`endif
|
||||
end
|
||||
end
|
||||
|
||||
// Ctrl register
|
||||
always @(posedge wb_clk_i or posedge wb_rst_i)
|
||||
begin
|
||||
if (wb_rst_i)
|
||||
ctrl <= #Tp {`SPI_CTRL_BIT_NB{1'b0}};
|
||||
else if(spi_ctrl_sel && wb_we_i && !tip)
|
||||
begin
|
||||
if (wb_sel_i[0])
|
||||
ctrl[7:0] <= #Tp wb_dat_i[7:0] | {7'b0, ctrl[0]};
|
||||
if (wb_sel_i[1])
|
||||
ctrl[`SPI_CTRL_BIT_NB-1:8] <= #Tp wb_dat_i[`SPI_CTRL_BIT_NB-1:8];
|
||||
end
|
||||
else if(tip && last_bit && pos_edge)
|
||||
ctrl[`SPI_CTRL_GO] <= #Tp 1'b0;
|
||||
end
|
||||
|
||||
assign rx_negedge = ctrl[`SPI_CTRL_RX_NEGEDGE];
|
||||
assign tx_negedge = ctrl[`SPI_CTRL_TX_NEGEDGE];
|
||||
assign go = ctrl[`SPI_CTRL_GO];
|
||||
assign char_len = ctrl[`SPI_CTRL_CHAR_LEN];
|
||||
assign lsb = ctrl[`SPI_CTRL_LSB];
|
||||
assign ie = ctrl[`SPI_CTRL_IE];
|
||||
assign ass = ctrl[`SPI_CTRL_ASS];
|
||||
|
||||
// Slave select register
|
||||
always @(posedge wb_clk_i or posedge wb_rst_i)
|
||||
begin
|
||||
if (wb_rst_i)
|
||||
ss <= #Tp {`SPI_SS_NB{1'b0}};
|
||||
else if(spi_ss_sel && wb_we_i && !tip)
|
||||
begin
|
||||
`ifdef SPI_SS_NB_8
|
||||
if (wb_sel_i[0])
|
||||
ss <= #Tp wb_dat_i[`SPI_SS_NB-1:0];
|
||||
`endif
|
||||
`ifdef SPI_SS_NB_16
|
||||
if (wb_sel_i[0])
|
||||
ss[7:0] <= #Tp wb_dat_i[7:0];
|
||||
if (wb_sel_i[1])
|
||||
ss[`SPI_SS_NB-1:8] <= #Tp wb_dat_i[`SPI_SS_NB-1:8];
|
||||
`endif
|
||||
`ifdef SPI_SS_NB_24
|
||||
if (wb_sel_i[0])
|
||||
ss[7:0] <= #Tp wb_dat_i[7:0];
|
||||
if (wb_sel_i[1])
|
||||
ss[15:8] <= #Tp wb_dat_i[15:8];
|
||||
if (wb_sel_i[2])
|
||||
ss[`SPI_SS_NB-1:16] <= #Tp wb_dat_i[`SPI_SS_NB-1:16];
|
||||
`endif
|
||||
`ifdef SPI_SS_NB_32
|
||||
if (wb_sel_i[0])
|
||||
ss[7:0] <= #Tp wb_dat_i[7:0];
|
||||
if (wb_sel_i[1])
|
||||
ss[15:8] <= #Tp wb_dat_i[15:8];
|
||||
if (wb_sel_i[2])
|
||||
ss[23:16] <= #Tp wb_dat_i[23:16];
|
||||
if (wb_sel_i[3])
|
||||
ss[`SPI_SS_NB-1:24] <= #Tp wb_dat_i[`SPI_SS_NB-1:24];
|
||||
`endif
|
||||
end
|
||||
end
|
||||
|
||||
assign ss_pad_o = ~((ss & {`SPI_SS_NB{tip & ass}}) | (ss & {`SPI_SS_NB{!ass}}));
|
||||
|
||||
spi_clgen clgen (.clk_in(wb_clk_i), .rst(wb_rst_i), .go(go), .enable(tip), .last_clk(last_bit),
|
||||
.divider(divider), .clk_out(sclk_pad_o), .pos_edge(pos_edge),
|
||||
.neg_edge(neg_edge));
|
||||
|
||||
spi_shift shift (.clk(wb_clk_i), .rst(wb_rst_i), .len(char_len[`SPI_CHAR_LEN_BITS-1:0]),
|
||||
.latch(spi_tx_sel[3:0] & {4{wb_we_i}}), .byte_sel(wb_sel_i), .lsb(lsb),
|
||||
.go(go), .pos_edge(pos_edge), .neg_edge(neg_edge),
|
||||
.rx_negedge(rx_negedge), .tx_negedge(tx_negedge),
|
||||
.tip(tip), .last(last_bit),
|
||||
.p_in(wb_dat_i), .p_out(rx),
|
||||
.s_clk(sclk_pad_o), .s_in(miso_pad_i), .s_out(mosi_pad_o));
|
||||
endmodule
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
`timescale 1ns / 10ps
|
||||
|
|
@ -1,222 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// PCM IO Slave Module ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/ss_pcm/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: pcm_slv_top.v,v 1.2 2002/09/17 15:32:50 rudi Exp $
|
||||
//
|
||||
// $Date: 2002/09/17 15:32:50 $
|
||||
// $Revision: 1.2 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: pcm_slv_top.v,v $
|
||||
// Revision 1.2 2002/09/17 15:32:50 rudi
|
||||
// *** empty log message ***
|
||||
//
|
||||
// Revision 1.1.1.1 2002/09/17 15:17:25 rudi
|
||||
// Initial Checkin
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
`include "timescale.v"
|
||||
|
||||
/*
|
||||
PCM Interface
|
||||
===============================
|
||||
PCM_CLK
|
||||
PCM_SYNC
|
||||
PCM_DIN
|
||||
PCM_DOUT
|
||||
*/
|
||||
|
||||
module pcm_slv_top( clk, rst,
|
||||
|
||||
ssel,
|
||||
|
||||
// PCM
|
||||
pcm_clk_i, pcm_sync_i, pcm_din_i, pcm_dout_o,
|
||||
|
||||
// Internal Interface
|
||||
din_i, dout_o, re_i, we_i);
|
||||
|
||||
input clk, rst;
|
||||
input [2:0] ssel; // Number of bits to delay (0-7)
|
||||
input pcm_clk_i, pcm_sync_i, pcm_din_i;
|
||||
output pcm_dout_o;
|
||||
input [7:0] din_i;
|
||||
output [7:0] dout_o;
|
||||
input re_i;
|
||||
input [1:0] we_i;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and Registers
|
||||
//
|
||||
|
||||
reg pclk_t, pclk_s, pclk_r;
|
||||
wire pclk_ris, pclk_fal;
|
||||
reg psync;
|
||||
reg pcm_sync_r1, pcm_sync_r2, pcm_sync_r3;
|
||||
reg tx_go;
|
||||
wire tx_data_le;
|
||||
reg [15:0] tx_hold_reg;
|
||||
reg [7:0] tx_hold_byte_h, tx_hold_byte_l;
|
||||
reg [3:0] tx_cnt;
|
||||
wire tx_done;
|
||||
reg [15:0] rx_hold_reg, rx_reg;
|
||||
wire rx_data_le;
|
||||
reg rxd_t, rxd;
|
||||
reg tx_go_r1, tx_go_r2;
|
||||
reg [7:0] psa;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc Logic
|
||||
//
|
||||
|
||||
always @(posedge clk)
|
||||
pclk_t <= #1 pcm_clk_i;
|
||||
|
||||
always @(posedge clk)
|
||||
pclk_s <= #1 pclk_t;
|
||||
|
||||
always @(posedge clk)
|
||||
pclk_r <= #1 pclk_s;
|
||||
|
||||
assign pclk_ris = !pclk_r & pclk_s;
|
||||
assign pclk_fal = pclk_r & !pclk_s;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Retrieve Sync Signal
|
||||
//
|
||||
|
||||
always @(posedge clk) // Latch it at falling edge
|
||||
if(pclk_fal) pcm_sync_r1 <= #1 pcm_sync_i;
|
||||
|
||||
always @(posedge clk) // resync to rising edge
|
||||
if(pclk_ris) psa <= #1 {psa[6:0], pcm_sync_r1};
|
||||
|
||||
always @(posedge clk) //delay bit N
|
||||
pcm_sync_r2 <= #1 psa[ssel];
|
||||
|
||||
always @(posedge clk) // edge detector
|
||||
pcm_sync_r3 <= #1 pcm_sync_r2;
|
||||
|
||||
always @(posedge clk)
|
||||
psync <= #1 !pcm_sync_r3 & pcm_sync_r2;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Transmit Logic
|
||||
//
|
||||
|
||||
assign tx_data_le = tx_go & pclk_ris;
|
||||
|
||||
always @(posedge clk)
|
||||
if(we_i[1]) tx_hold_byte_h <= #1 din_i;
|
||||
|
||||
always @(posedge clk)
|
||||
if(we_i[0]) tx_hold_byte_l <= #1 din_i;
|
||||
|
||||
always @(posedge clk)
|
||||
if(!rst) tx_go <= #1 1'b0;
|
||||
else
|
||||
if(psync) tx_go <= #1 1'b1;
|
||||
else
|
||||
if(tx_done) tx_go <= #1 1'b0;
|
||||
|
||||
always @(posedge clk)
|
||||
if(!rst) tx_hold_reg <= #1 16'h0;
|
||||
else
|
||||
if(psync) tx_hold_reg <= #1 {tx_hold_byte_h, tx_hold_byte_l};
|
||||
else
|
||||
if(tx_data_le) tx_hold_reg <= #1 {tx_hold_reg[14:0],1'b0};
|
||||
|
||||
assign pcm_dout_o = tx_hold_reg[15];
|
||||
|
||||
always @(posedge clk)
|
||||
if(!rst) tx_cnt <= #1 4'h0;
|
||||
else
|
||||
if(tx_data_le) tx_cnt <= tx_cnt + 4'h1;
|
||||
|
||||
assign tx_done = (tx_cnt == 4'hf) & tx_data_le;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Recieve Logic
|
||||
//
|
||||
|
||||
always @(posedge clk)
|
||||
if(pclk_ris) tx_go_r1 <= #1 tx_go;
|
||||
|
||||
always @(posedge clk)
|
||||
if(pclk_ris) tx_go_r2 <= #1 tx_go_r1;
|
||||
|
||||
// Receive is in sync with transmit ...
|
||||
always @(posedge clk)
|
||||
if(pclk_fal) rxd_t <= #1 pcm_din_i;
|
||||
|
||||
always @(posedge clk)
|
||||
rxd <= #1 rxd_t;
|
||||
|
||||
assign rx_data_le = (tx_go_r1 | tx_go) & pclk_fal;
|
||||
|
||||
always @(posedge clk)
|
||||
if(!rst) rx_hold_reg <= #1 16'h0;
|
||||
else
|
||||
if(rx_data_le) rx_hold_reg <= #1 {rx_hold_reg[14:0], rxd};
|
||||
|
||||
always @(posedge clk)
|
||||
if(!rst) rx_reg <= #1 16'h0;
|
||||
else
|
||||
if(tx_go_r1 & !tx_go & pclk_ris) rx_reg <= #1 rx_hold_reg;
|
||||
|
||||
assign dout_o = re_i ? rx_reg[15:8] : rx_reg[7:0];
|
||||
|
||||
endmodule
|
||||
|
|
@ -1 +0,0 @@
|
|||
`timescale 1ns / 10ps
|
|
@ -1,358 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// AES top file ////
|
||||
//// ////
|
||||
//// This file is part of the SystemC AES ////
|
||||
//// ////
|
||||
//// Description: ////
|
||||
//// AES top ////
|
||||
//// ////
|
||||
//// Generated automatically using SystemC to Verilog translator ////
|
||||
//// ////
|
||||
//// To Do: ////
|
||||
//// - done ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Javier Castillo, jcastilo@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: aes.v,v $
|
||||
// Revision 1.1.1.1 2004/07/05 09:46:23 jcastillo
|
||||
// First import
|
||||
//
|
||||
|
||||
module aes(clk,reset,load_i,decrypt_i,data_i,key_i,ready_o,data_o);
|
||||
input clk;
|
||||
input reset;
|
||||
input load_i;
|
||||
input decrypt_i;
|
||||
input [127:0] data_i;
|
||||
input [127:0] key_i;
|
||||
output ready_o;
|
||||
output [127:0] data_o;
|
||||
|
||||
reg ready_o;
|
||||
reg [127:0] data_o;
|
||||
|
||||
reg next_ready_o;
|
||||
reg keysched_start_i;
|
||||
reg [3:0] keysched_round_i;
|
||||
reg [127:0] keysched_last_key_i;
|
||||
wire [127:0] keysched_new_key_o;
|
||||
|
||||
wire keysched_ready_o;
|
||||
|
||||
wire keysched_sbox_access_o;
|
||||
|
||||
wire [7:0] keysched_sbox_data_o;
|
||||
|
||||
wire keysched_sbox_decrypt_o;
|
||||
|
||||
reg mixcol_start_i;
|
||||
reg [127:0] mixcol_data_i;
|
||||
wire mixcol_ready_o;
|
||||
|
||||
wire [127:0] mixcol_data_o;
|
||||
|
||||
reg subbytes_start_i;
|
||||
reg [127:0] subbytes_data_i;
|
||||
wire subbytes_ready_o;
|
||||
|
||||
wire [127:0] subbytes_data_o;
|
||||
|
||||
wire [7:0] subbytes_sbox_data_o;
|
||||
|
||||
wire subbytes_sbox_decrypt_o;
|
||||
|
||||
wire [7:0] sbox_data_o;
|
||||
|
||||
reg [7:0] sbox_data_i;
|
||||
reg sbox_decrypt_i;
|
||||
reg state;
|
||||
reg next_state;
|
||||
reg [3:0] round;
|
||||
reg [3:0] next_round;
|
||||
reg [127:0] addroundkey_data_o;
|
||||
reg [127:0] next_addroundkey_data_reg;
|
||||
reg [127:0] addroundkey_data_reg;
|
||||
reg [127:0] addroundkey_data_i;
|
||||
reg addroundkey_ready_o;
|
||||
reg next_addroundkey_ready_o;
|
||||
reg addroundkey_start_i;
|
||||
reg next_addroundkey_start_i;
|
||||
reg [3:0] addroundkey_round;
|
||||
reg [3:0] next_addroundkey_round;
|
||||
reg first_round_reg;
|
||||
reg next_first_round_reg;
|
||||
|
||||
sbox sbox1 (.clk(clk), .reset(reset), .data_i(sbox_data_i), .decrypt_i(sbox_decrypt_i), .data_o(sbox_data_o));
|
||||
subbytes sub1 (.clk(clk), .reset(reset), .start_i(subbytes_start_i), .decrypt_i(decrypt_i), .data_i(subbytes_data_i), .ready_o(subbytes_ready_o), .data_o(subbytes_data_o), .sbox_data_o(subbytes_sbox_data_o), .sbox_data_i(sbox_data_o), .sbox_decrypt_o(subbytes_sbox_decrypt_o));
|
||||
mixcolum mix1 (.clk(clk), .reset(reset), .decrypt_i(decrypt_i), .start_i(mixcol_start_i), .data_i(mixcol_data_i), .ready_o(mixcol_ready_o), .data_o(mixcol_data_o));
|
||||
keysched ks1 (.clk(clk), .reset(reset), .start_i(keysched_start_i), .round_i(keysched_round_i), .last_key_i(keysched_last_key_i), .new_key_o(keysched_new_key_o), .ready_o(keysched_ready_o), .sbox_access_o(keysched_sbox_access_o), .sbox_data_o(keysched_sbox_data_o), .sbox_data_i(sbox_data_o), .sbox_decrypt_o(keysched_sbox_decrypt_o));
|
||||
|
||||
//registers:
|
||||
always @(posedge clk or negedge reset)
|
||||
|
||||
begin
|
||||
|
||||
if(!reset)
|
||||
begin
|
||||
|
||||
state = (0);
|
||||
ready_o = (0);
|
||||
round = (0);
|
||||
addroundkey_round = (0);
|
||||
addroundkey_data_reg = (0);
|
||||
addroundkey_ready_o = (0);
|
||||
addroundkey_start_i = (0);
|
||||
first_round_reg = (0);
|
||||
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
||||
state = (next_state);
|
||||
ready_o = (next_ready_o);
|
||||
round = (next_round);
|
||||
addroundkey_round = (next_addroundkey_round);
|
||||
addroundkey_data_reg = (next_addroundkey_data_reg);
|
||||
addroundkey_ready_o = (next_addroundkey_ready_o);
|
||||
first_round_reg = (next_first_round_reg);
|
||||
addroundkey_start_i = (next_addroundkey_start_i);
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
//control:
|
||||
always @( state or round or addroundkey_data_o or data_i or load_i or decrypt_i or addroundkey_ready_o or mixcol_ready_o or subbytes_ready_o or subbytes_data_o or mixcol_data_o or first_round_reg)
|
||||
|
||||
begin
|
||||
|
||||
|
||||
next_state = (state);
|
||||
next_round = (round);
|
||||
data_o = (addroundkey_data_o);
|
||||
next_ready_o = (0);
|
||||
|
||||
//Tokeyschedulemodule
|
||||
|
||||
next_first_round_reg = (0);
|
||||
|
||||
|
||||
subbytes_data_i = (0);
|
||||
mixcol_data_i = (0);
|
||||
addroundkey_data_i = (0);
|
||||
next_addroundkey_start_i = (first_round_reg);
|
||||
mixcol_start_i = ((addroundkey_ready_o&decrypt_i&round!=10)|(subbytes_ready_o&!decrypt_i));
|
||||
subbytes_start_i = ((addroundkey_ready_o&!decrypt_i)|(mixcol_ready_o&decrypt_i)|(addroundkey_ready_o&decrypt_i&round==10));
|
||||
|
||||
if(decrypt_i&&round!=10)
|
||||
begin
|
||||
addroundkey_data_i = (subbytes_data_o);
|
||||
subbytes_data_i = (mixcol_data_o);
|
||||
mixcol_data_i = (addroundkey_data_o);
|
||||
end
|
||||
else if(!decrypt_i&&round!=0)
|
||||
begin
|
||||
addroundkey_data_i = (mixcol_data_o);
|
||||
subbytes_data_i = (addroundkey_data_o);
|
||||
mixcol_data_i = (subbytes_data_o);
|
||||
end
|
||||
else
|
||||
begin
|
||||
mixcol_data_i = (subbytes_data_o);
|
||||
subbytes_data_i = (addroundkey_data_o);
|
||||
addroundkey_data_i = (data_i);
|
||||
end
|
||||
|
||||
|
||||
case(state)
|
||||
|
||||
0:
|
||||
begin
|
||||
if(load_i)
|
||||
begin
|
||||
next_state = (1);
|
||||
if(decrypt_i)
|
||||
next_round = (10);
|
||||
else
|
||||
next_round = (0);
|
||||
next_first_round_reg = (1);
|
||||
end
|
||||
end
|
||||
|
||||
1:
|
||||
begin
|
||||
|
||||
//Counter
|
||||
if(!decrypt_i&&mixcol_ready_o)
|
||||
begin
|
||||
next_addroundkey_start_i = (1);
|
||||
addroundkey_data_i = (mixcol_data_o);
|
||||
next_round = (round+1);
|
||||
end
|
||||
else if(decrypt_i&&subbytes_ready_o)
|
||||
begin
|
||||
next_addroundkey_start_i = (1);
|
||||
addroundkey_data_i = (subbytes_data_o);
|
||||
next_round = (round-1);
|
||||
end
|
||||
|
||||
//Output
|
||||
if((round==9&&!decrypt_i)||(round==0&&decrypt_i))
|
||||
begin
|
||||
next_addroundkey_start_i = (0);
|
||||
mixcol_start_i = (0);
|
||||
if(subbytes_ready_o)
|
||||
begin
|
||||
addroundkey_data_i = (subbytes_data_o);
|
||||
next_addroundkey_start_i = (1);
|
||||
next_round = (round+1);
|
||||
end
|
||||
end
|
||||
|
||||
if((round==10&&!decrypt_i)||(round==0&&decrypt_i))
|
||||
begin
|
||||
addroundkey_data_i = (subbytes_data_o);
|
||||
subbytes_start_i = (0);
|
||||
if(addroundkey_ready_o)
|
||||
begin
|
||||
next_ready_o = (1);
|
||||
next_state = (0);
|
||||
next_addroundkey_start_i = (0);
|
||||
next_round = (0);
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
default:
|
||||
begin
|
||||
next_state = (0);
|
||||
end
|
||||
endcase
|
||||
|
||||
|
||||
end
|
||||
//addroundkey:
|
||||
reg[127:0] data_var,round_data_var,round_key_var;
|
||||
always @( addroundkey_data_i or addroundkey_start_i or addroundkey_data_reg or addroundkey_round or keysched_new_key_o or keysched_ready_o or key_i or round)
|
||||
|
||||
begin
|
||||
|
||||
|
||||
|
||||
round_data_var=addroundkey_data_reg;
|
||||
next_addroundkey_data_reg = (addroundkey_data_reg);
|
||||
next_addroundkey_ready_o = (0);
|
||||
next_addroundkey_round = (addroundkey_round);
|
||||
addroundkey_data_o = (addroundkey_data_reg);
|
||||
|
||||
if(addroundkey_round==1||addroundkey_round==0)
|
||||
keysched_last_key_i = (key_i);
|
||||
else
|
||||
keysched_last_key_i = (keysched_new_key_o);
|
||||
|
||||
keysched_start_i = (0);
|
||||
|
||||
keysched_round_i = (addroundkey_round);
|
||||
|
||||
if(round==0&&addroundkey_start_i)
|
||||
begin
|
||||
|
||||
//Taketheinputandxorthemwithdataifround==0;
|
||||
data_var=addroundkey_data_i;
|
||||
round_key_var=key_i;
|
||||
round_data_var=round_key_var^data_var;
|
||||
next_addroundkey_data_reg = (round_data_var);
|
||||
next_addroundkey_ready_o = (1);
|
||||
|
||||
end
|
||||
else if(addroundkey_start_i&&round!=0)
|
||||
begin
|
||||
|
||||
keysched_last_key_i = (key_i);
|
||||
keysched_start_i = (1);
|
||||
keysched_round_i = (1);
|
||||
next_addroundkey_round = (1);
|
||||
|
||||
end
|
||||
else if(addroundkey_round!=round&&keysched_ready_o)
|
||||
begin
|
||||
|
||||
next_addroundkey_round = (addroundkey_round+1);
|
||||
keysched_last_key_i = (keysched_new_key_o);
|
||||
keysched_start_i = (1);
|
||||
keysched_round_i = (addroundkey_round+1);
|
||||
|
||||
end
|
||||
else if(addroundkey_round==round&&keysched_ready_o)
|
||||
begin
|
||||
|
||||
data_var=addroundkey_data_i;
|
||||
round_key_var=keysched_new_key_o;
|
||||
round_data_var=round_key_var^data_var;
|
||||
next_addroundkey_data_reg = (round_data_var);
|
||||
next_addroundkey_ready_o = (1);
|
||||
next_addroundkey_round = (0);
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
//sbox_muxes:
|
||||
always @( keysched_sbox_access_o or keysched_sbox_decrypt_o or keysched_sbox_data_o or subbytes_sbox_decrypt_o or subbytes_sbox_data_o)
|
||||
|
||||
begin
|
||||
|
||||
|
||||
if(keysched_sbox_access_o)
|
||||
begin
|
||||
|
||||
sbox_decrypt_i = (keysched_sbox_decrypt_o);
|
||||
sbox_data_i = (keysched_sbox_data_o);
|
||||
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
||||
sbox_decrypt_i = (subbytes_sbox_decrypt_o);
|
||||
sbox_data_i = (subbytes_sbox_data_o);
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -1,92 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Mixcolumns for 8 bit ////
|
||||
//// ////
|
||||
//// This file is part of the SystemC AES ////
|
||||
//// ////
|
||||
//// Description: ////
|
||||
//// Mixcolum for a byte ////
|
||||
//// ////
|
||||
//// Generated automatically using SystemC to Verilog translator ////
|
||||
//// ////
|
||||
//// To Do: ////
|
||||
//// - done ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Javier Castillo, jcastilo@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: byte_mixcolum.v,v $
|
||||
// Revision 1.1.1.1 2004/07/05 09:46:23 jcastillo
|
||||
// First import
|
||||
//
|
||||
|
||||
module byte_mixcolum(a,b,c,d,outx,outy);
|
||||
|
||||
input [7:0] a,b,c,d;
|
||||
output [7:0] outx, outy;
|
||||
|
||||
reg [7:0] outx, outy;
|
||||
|
||||
function [7:0] xtime;
|
||||
input [7:0] in;
|
||||
reg [3:0] xtime_t;
|
||||
|
||||
begin
|
||||
xtime[7:5] = in[6:4];
|
||||
xtime_t[3] = in[7];
|
||||
xtime_t[2] = in[7];
|
||||
xtime_t[1] = 0;
|
||||
xtime_t[0] = in[7];
|
||||
xtime[4:1] =xtime_t^in[3:0];
|
||||
xtime[0] = in[7];
|
||||
end
|
||||
endfunction
|
||||
|
||||
reg [7:0] w1,w2,w3,w4,w5,w6,w7,w8,outx_var;
|
||||
always @ (a, b, c, d)
|
||||
begin
|
||||
w1 = a ^b;
|
||||
w2 = a ^c;
|
||||
w3 = c ^d;
|
||||
w4 = xtime(w1);
|
||||
w5 = xtime(w3);
|
||||
w6 = w2 ^w4 ^w5;
|
||||
w7 = xtime(w6);
|
||||
w8 = xtime(w7);
|
||||
|
||||
outx_var = b^w3^w4;
|
||||
outx=outx_var;
|
||||
outy=w8^outx_var;
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -1,248 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Key schedule ////
|
||||
//// ////
|
||||
//// This file is part of the SystemC AES ////
|
||||
//// ////
|
||||
//// Description: ////
|
||||
//// Generate the next round key from the previous one ////
|
||||
//// ////
|
||||
//// Generated automatically using SystemC to Verilog translator ////
|
||||
//// ////
|
||||
//// To Do: ////
|
||||
//// - done ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Javier Castillo, jcastilo@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: keysched.v,v $
|
||||
// Revision 1.1.1.1 2004/07/05 09:46:23 jcastillo
|
||||
// First import
|
||||
//
|
||||
|
||||
module keysched(clk,reset,start_i,round_i,last_key_i,new_key_o,ready_o,sbox_access_o,sbox_data_o,sbox_data_i,sbox_decrypt_o);
|
||||
input clk;
|
||||
input reset;
|
||||
input start_i;
|
||||
input [3:0] round_i;
|
||||
input [127:0] last_key_i;
|
||||
output [127:0] new_key_o;
|
||||
output ready_o;
|
||||
output sbox_access_o;
|
||||
output [7:0] sbox_data_o;
|
||||
input [7:0] sbox_data_i;
|
||||
output sbox_decrypt_o;
|
||||
|
||||
reg [127:0] new_key_o;
|
||||
reg ready_o;
|
||||
reg sbox_access_o;
|
||||
reg [7:0] sbox_data_o;
|
||||
reg sbox_decrypt_o;
|
||||
|
||||
reg [2:0] next_state;
|
||||
reg [2:0] state;
|
||||
reg [7:0] rcon_o;
|
||||
reg [31:0] next_col;
|
||||
reg [31:0] col;
|
||||
reg [127:0] key_reg;
|
||||
reg [127:0] next_key_reg;
|
||||
reg next_ready_o;
|
||||
|
||||
|
||||
//rcon:
|
||||
always @( round_i)
|
||||
|
||||
begin
|
||||
|
||||
|
||||
case(round_i)
|
||||
1:
|
||||
begin
|
||||
rcon_o = (1);
|
||||
end
|
||||
2:
|
||||
begin
|
||||
rcon_o = (2);
|
||||
end
|
||||
3:
|
||||
begin
|
||||
rcon_o = (4);
|
||||
end
|
||||
4:
|
||||
begin
|
||||
rcon_o = (8);
|
||||
end
|
||||
5:
|
||||
begin
|
||||
rcon_o = ('h10);
|
||||
end
|
||||
6:
|
||||
begin
|
||||
rcon_o = ('h20);
|
||||
end
|
||||
7:
|
||||
begin
|
||||
rcon_o = ('h40);
|
||||
end
|
||||
8:
|
||||
begin
|
||||
rcon_o = ('h80);
|
||||
end
|
||||
9:
|
||||
begin
|
||||
rcon_o = ('h1B);
|
||||
end
|
||||
10:
|
||||
begin
|
||||
rcon_o = ('h36);
|
||||
end
|
||||
default:
|
||||
begin
|
||||
rcon_o = (0);
|
||||
end
|
||||
endcase
|
||||
|
||||
|
||||
end
|
||||
//registers:
|
||||
always @(posedge clk or negedge reset)
|
||||
|
||||
begin
|
||||
|
||||
if(!reset)
|
||||
begin
|
||||
state = (0);
|
||||
col = (0);
|
||||
key_reg = (0);
|
||||
ready_o = (0);
|
||||
end
|
||||
else
|
||||
begin
|
||||
state = (next_state);
|
||||
col = (next_col);
|
||||
key_reg = (next_key_reg);
|
||||
ready_o = (next_ready_o);
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
//generate_key:
|
||||
reg[127:0] K_var,W_var;
|
||||
reg[31:0] col_t;
|
||||
reg[23:0] zero;
|
||||
|
||||
always @( start_i or last_key_i or sbox_data_i or state or rcon_o or col or key_reg)
|
||||
|
||||
begin
|
||||
|
||||
|
||||
zero=0;
|
||||
|
||||
col_t=col;
|
||||
W_var=0;
|
||||
|
||||
next_state = (state);
|
||||
next_col = (col);
|
||||
|
||||
next_ready_o = (0);
|
||||
next_key_reg = (key_reg);
|
||||
new_key_o = (key_reg);
|
||||
|
||||
sbox_decrypt_o = (0);
|
||||
sbox_access_o = (0);
|
||||
sbox_data_o = (0);
|
||||
K_var=last_key_i;
|
||||
|
||||
case(state)
|
||||
//Substitutethebyteswhilerotatingthem
|
||||
//FouraccessestoSBoxareneeded
|
||||
0:
|
||||
begin
|
||||
if(start_i)
|
||||
begin
|
||||
|
||||
col_t=0;
|
||||
sbox_access_o = (1);
|
||||
sbox_data_o = (K_var[31:24]);
|
||||
next_state = (1);
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
1:
|
||||
begin
|
||||
sbox_access_o = (1);
|
||||
sbox_data_o = (K_var[23:16]);
|
||||
col_t[7:0]=sbox_data_i;
|
||||
next_col = (col_t);
|
||||
next_state = (2);
|
||||
end
|
||||
2:
|
||||
begin
|
||||
sbox_access_o = (1);
|
||||
sbox_data_o = (K_var[15:8]);
|
||||
col_t[31:24]=sbox_data_i;
|
||||
next_col = (col_t);
|
||||
next_state = (3);
|
||||
end
|
||||
3:
|
||||
begin
|
||||
sbox_access_o = (1);
|
||||
sbox_data_o = (K_var[7:0]);
|
||||
col_t[23:16]=sbox_data_i;
|
||||
next_col = (col_t);
|
||||
next_state = (4);
|
||||
end
|
||||
4:
|
||||
begin
|
||||
sbox_access_o = (1);
|
||||
col_t[15:8]=sbox_data_i;
|
||||
next_col = (col_t);
|
||||
W_var[127:96]=col_t^K_var[127:96]^{rcon_o,zero};
|
||||
W_var[95:64]=W_var[127:96]^K_var[95:64];
|
||||
W_var[63:32]=W_var[95:64]^K_var[63:32];
|
||||
W_var[31:0]=W_var[63:32]^K_var[31:0];
|
||||
next_ready_o = (1);
|
||||
next_key_reg = (W_var);
|
||||
next_state = (0);
|
||||
end
|
||||
|
||||
default:
|
||||
begin
|
||||
next_state = (0);
|
||||
end
|
||||
endcase
|
||||
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -1,188 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Mixcolumns module implementation ////
|
||||
//// ////
|
||||
//// This file is part of the SystemC AES ////
|
||||
//// ////
|
||||
//// Description: ////
|
||||
//// Mixcolum module ////
|
||||
//// ////
|
||||
//// Generated automatically using SystemC to Verilog translator ////
|
||||
//// ////
|
||||
//// To Do: ////
|
||||
//// - done ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Javier Castillo, jcastilo@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: mixcolum.v,v $
|
||||
// Revision 1.1.1.1 2004/07/05 09:46:23 jcastillo
|
||||
// First import
|
||||
//
|
||||
|
||||
|
||||
module mixcolum(clk,reset,decrypt_i,start_i,data_i,ready_o,data_o);
|
||||
input clk;
|
||||
input reset;
|
||||
input decrypt_i;
|
||||
input start_i;
|
||||
input [127:0] data_i;
|
||||
output ready_o;
|
||||
output [127:0] data_o;
|
||||
|
||||
reg ready_o;
|
||||
reg [127:0] data_o;
|
||||
|
||||
reg [127:0] data_reg;
|
||||
reg [127:0] next_data_reg;
|
||||
reg [127:0] data_o_reg;
|
||||
reg [127:0] next_data_o;
|
||||
reg next_ready_o;
|
||||
reg [1:0] state;
|
||||
reg [1:0] next_state;
|
||||
wire [31:0] outx;
|
||||
|
||||
wire [31:0] outy;
|
||||
|
||||
reg [31:0] mix_word;
|
||||
reg [31:0] outmux;
|
||||
|
||||
word_mixcolum w1 (.in(mix_word), .outx(outx), .outy(outy));
|
||||
|
||||
//assign_data_o:
|
||||
always @( data_o_reg)
|
||||
|
||||
begin
|
||||
|
||||
data_o = (data_o_reg);
|
||||
|
||||
end
|
||||
//mux:
|
||||
always @( outx or outy or decrypt_i)
|
||||
|
||||
begin
|
||||
|
||||
outmux = (decrypt_i?outy:outx);
|
||||
|
||||
end
|
||||
//registers:
|
||||
always @(posedge clk or negedge reset)
|
||||
|
||||
begin
|
||||
|
||||
if(!reset)
|
||||
begin
|
||||
data_reg = (0);
|
||||
state = (0);
|
||||
ready_o = (0);
|
||||
data_o_reg = (0);
|
||||
end
|
||||
else
|
||||
begin
|
||||
data_reg = (next_data_reg);
|
||||
state = (next_state);
|
||||
ready_o = (next_ready_o);
|
||||
data_o_reg = (next_data_o);
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
//mixcol:
|
||||
reg[127:0] data_i_var;
|
||||
reg[31:0] aux;
|
||||
reg[127:0] data_reg_var;
|
||||
|
||||
always @( decrypt_i or start_i or state or data_reg or outmux or data_o_reg or data_i)
|
||||
|
||||
begin
|
||||
|
||||
|
||||
data_i_var=data_i;
|
||||
data_reg_var=data_reg;
|
||||
next_data_reg = (data_reg);
|
||||
next_state = (state);
|
||||
|
||||
mix_word = (0);
|
||||
|
||||
next_ready_o = (0);
|
||||
next_data_o = (data_o_reg);
|
||||
|
||||
case(state)
|
||||
|
||||
0:
|
||||
begin
|
||||
if(start_i)
|
||||
begin
|
||||
|
||||
aux=data_i_var[127:96];
|
||||
mix_word = (aux);
|
||||
data_reg_var[127:96]=outmux;
|
||||
next_data_reg = (data_reg_var);
|
||||
next_state = (1);
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
1:
|
||||
begin
|
||||
aux=data_i_var[95:64];
|
||||
mix_word = (aux);
|
||||
data_reg_var[95:64]=outmux;
|
||||
next_data_reg = (data_reg_var);
|
||||
next_state = (2);
|
||||
end
|
||||
2:
|
||||
begin
|
||||
aux=data_i_var[63:32];
|
||||
mix_word = (aux);
|
||||
data_reg_var[63:32]=outmux;
|
||||
next_data_reg = (data_reg_var);
|
||||
next_state = (3);
|
||||
end
|
||||
3:
|
||||
begin
|
||||
aux=data_i_var[31:0];
|
||||
mix_word = (aux);
|
||||
data_reg_var[31:0]=outmux;
|
||||
next_data_o = (data_reg_var);
|
||||
next_ready_o = (1);
|
||||
next_state = (0);
|
||||
end
|
||||
default:
|
||||
begin
|
||||
end
|
||||
endcase
|
||||
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -1,392 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// S-Box calculation ////
|
||||
//// ////
|
||||
//// This file is part of the SystemC AES ////
|
||||
//// ////
|
||||
//// Description: ////
|
||||
//// S-box calculation calculating inverse on gallois field ////
|
||||
//// ////
|
||||
//// Generated automatically using SystemC to Verilog translator ////
|
||||
//// ////
|
||||
//// To Do: ////
|
||||
//// - done ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Javier Castillo, jcastilo@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: sbox.v,v $
|
||||
// Revision 1.1.1.1 2004/07/05 09:46:23 jcastillo
|
||||
// First import
|
||||
//
|
||||
|
||||
module sbox(clk,reset,data_i,decrypt_i,data_o);
|
||||
input clk;
|
||||
input reset;
|
||||
input [7:0] data_i;
|
||||
input decrypt_i;
|
||||
output [7:0] data_o;
|
||||
|
||||
reg [7:0] data_o;
|
||||
|
||||
reg [7:0] inva;
|
||||
reg [3:0] ah;
|
||||
reg [3:0] al;
|
||||
reg [3:0] ah2;
|
||||
reg [3:0] al2;
|
||||
reg [3:0] alxh;
|
||||
reg [3:0] alph;
|
||||
reg [3:0] d;
|
||||
reg [3:0] ahp;
|
||||
reg [3:0] alp;
|
||||
reg [3:0] to_invert;
|
||||
reg [3:0] next_to_invert;
|
||||
reg [3:0] ah_reg;
|
||||
reg [3:0] next_ah_reg;
|
||||
reg [3:0] next_alph;
|
||||
|
||||
|
||||
//registers:
|
||||
always @(posedge clk or negedge reset)
|
||||
|
||||
begin
|
||||
|
||||
if(!reset)
|
||||
begin
|
||||
|
||||
to_invert = (0);
|
||||
ah_reg = (0);
|
||||
alph = (0);
|
||||
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
||||
to_invert = (next_to_invert);
|
||||
ah_reg = (next_ah_reg);
|
||||
alph = (next_alph);
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
//first_mux:
|
||||
reg[7:0] first_mux_data_var;
|
||||
reg[7:0] first_mux_InvInput;
|
||||
reg[3:0] first_mux_ah_t,first_mux_al_t;
|
||||
reg first_mux_aA,first_mux_aB,first_mux_aC,first_mux_aD;
|
||||
|
||||
always @( data_i or decrypt_i)
|
||||
|
||||
begin
|
||||
|
||||
|
||||
first_mux_data_var=data_i;
|
||||
first_mux_InvInput=first_mux_data_var;
|
||||
|
||||
case(decrypt_i)
|
||||
1:
|
||||
begin
|
||||
//Applyinverseaffinetrasformation
|
||||
first_mux_aA=first_mux_data_var[0]^first_mux_data_var[5];first_mux_aB=first_mux_data_var[1]^first_mux_data_var[4];
|
||||
first_mux_aC=first_mux_data_var[2]^first_mux_data_var[7];first_mux_aD=first_mux_data_var[3]^first_mux_data_var[6];
|
||||
first_mux_InvInput[0]=(!first_mux_data_var[5])^first_mux_aC;
|
||||
first_mux_InvInput[1]=first_mux_data_var[0]^first_mux_aD;
|
||||
first_mux_InvInput[2]=(!first_mux_data_var[7])^first_mux_aB;
|
||||
first_mux_InvInput[3]=first_mux_data_var[2]^first_mux_aA;
|
||||
first_mux_InvInput[4]=first_mux_data_var[1]^first_mux_aD;
|
||||
first_mux_InvInput[5]=first_mux_data_var[4]^first_mux_aC;
|
||||
first_mux_InvInput[6]=first_mux_data_var[3]^first_mux_aA;
|
||||
first_mux_InvInput[7]=first_mux_data_var[6]^first_mux_aB;
|
||||
end
|
||||
default:
|
||||
begin
|
||||
first_mux_InvInput=first_mux_data_var;
|
||||
end
|
||||
endcase
|
||||
|
||||
|
||||
//ConvertelementsfromGF(2^8)intotwoelementsofGF(2^4^2)
|
||||
|
||||
first_mux_aA=first_mux_InvInput[1]^first_mux_InvInput[7];
|
||||
first_mux_aB=first_mux_InvInput[5]^first_mux_InvInput[7];
|
||||
first_mux_aC=first_mux_InvInput[4]^first_mux_InvInput[6];
|
||||
|
||||
|
||||
first_mux_al_t[0]=first_mux_aC^first_mux_InvInput[0]^first_mux_InvInput[5];
|
||||
first_mux_al_t[1]=first_mux_InvInput[1]^first_mux_InvInput[2];
|
||||
first_mux_al_t[2]=first_mux_aA;
|
||||
first_mux_al_t[3]=first_mux_InvInput[2]^first_mux_InvInput[4];
|
||||
|
||||
first_mux_ah_t[0]=first_mux_aC^first_mux_InvInput[5];
|
||||
first_mux_ah_t[1]=first_mux_aA^first_mux_aC;
|
||||
first_mux_ah_t[2]=first_mux_aB^first_mux_InvInput[2]^first_mux_InvInput[3];
|
||||
first_mux_ah_t[3]=first_mux_aB;
|
||||
|
||||
al = (first_mux_al_t);
|
||||
ah = (first_mux_ah_t);
|
||||
next_ah_reg = (first_mux_ah_t);
|
||||
|
||||
end
|
||||
//end_mux:
|
||||
reg[7:0] end_mux_data_var,end_mux_data_o_var;
|
||||
reg end_mux_aA,end_mux_aB,end_mux_aC,end_mux_aD;
|
||||
|
||||
always @( decrypt_i or inva)
|
||||
|
||||
begin
|
||||
|
||||
|
||||
|
||||
//Taketheoutputoftheinverter
|
||||
end_mux_data_var=inva;
|
||||
|
||||
case(decrypt_i)
|
||||
0:
|
||||
begin
|
||||
//Applyaffinetrasformation
|
||||
end_mux_aA=end_mux_data_var[0]^end_mux_data_var[1];end_mux_aB=end_mux_data_var[2]^end_mux_data_var[3];
|
||||
end_mux_aC=end_mux_data_var[4]^end_mux_data_var[5];end_mux_aD=end_mux_data_var[6]^end_mux_data_var[7];
|
||||
end_mux_data_o_var[0]=(!end_mux_data_var[0])^end_mux_aC^end_mux_aD;
|
||||
end_mux_data_o_var[1]=(!end_mux_data_var[5])^end_mux_aA^end_mux_aD;
|
||||
end_mux_data_o_var[2]=end_mux_data_var[2]^end_mux_aA^end_mux_aD;
|
||||
end_mux_data_o_var[3]=end_mux_data_var[7]^end_mux_aA^end_mux_aB;
|
||||
end_mux_data_o_var[4]=end_mux_data_var[4]^end_mux_aA^end_mux_aB;
|
||||
end_mux_data_o_var[5]=(!end_mux_data_var[1])^end_mux_aB^end_mux_aC;
|
||||
end_mux_data_o_var[6]=(!end_mux_data_var[6])^end_mux_aB^end_mux_aC;
|
||||
end_mux_data_o_var[7]=end_mux_data_var[3]^end_mux_aC^end_mux_aD;
|
||||
data_o = (end_mux_data_o_var);
|
||||
end
|
||||
default:
|
||||
begin
|
||||
data_o = (end_mux_data_var);
|
||||
end
|
||||
endcase
|
||||
|
||||
|
||||
|
||||
end
|
||||
//inversemap:
|
||||
reg[3:0] aA,aB;
|
||||
reg[3:0] inversemap_alp_t,inversemap_ahp_t;
|
||||
reg[7:0] inversemap_inva_t;
|
||||
|
||||
always @( alp or ahp)
|
||||
begin
|
||||
|
||||
|
||||
inversemap_alp_t=alp;
|
||||
inversemap_ahp_t=ahp;
|
||||
|
||||
aA=inversemap_alp_t[1]^inversemap_ahp_t[3];
|
||||
aB=inversemap_ahp_t[0]^inversemap_ahp_t[1];
|
||||
|
||||
inversemap_inva_t[0]=inversemap_alp_t[0]^inversemap_ahp_t[0];
|
||||
inversemap_inva_t[1]=aB^inversemap_ahp_t[3];
|
||||
inversemap_inva_t[2]=aA^aB;
|
||||
inversemap_inva_t[3]=aB^inversemap_alp_t[1]^inversemap_ahp_t[2];
|
||||
inversemap_inva_t[4]=aA^aB^inversemap_alp_t[3];
|
||||
inversemap_inva_t[5]=aB^inversemap_alp_t[2];
|
||||
inversemap_inva_t[6]=aA^inversemap_alp_t[2]^inversemap_alp_t[3]^inversemap_ahp_t[0];
|
||||
inversemap_inva_t[7]=aB^inversemap_alp_t[2]^inversemap_ahp_t[3];
|
||||
|
||||
inva = (inversemap_inva_t);
|
||||
|
||||
end
|
||||
//mul1:
|
||||
reg[3:0] mul1_alxh_t;
|
||||
reg[3:0] mul1_aA,mul1_a;
|
||||
|
||||
always @( ah or al)
|
||||
|
||||
begin
|
||||
|
||||
//alxah
|
||||
|
||||
mul1_aA=al[0]^al[3];
|
||||
mul1_a=al[2]^al[3];
|
||||
|
||||
mul1_alxh_t[0]=(al[0]&ah[0])^(al[3]&ah[1])^(al[2]&ah[2])^(al[1]&ah[3]);
|
||||
mul1_alxh_t[1]=(al[1]&ah[0])^(mul1_aA&ah[1])^(mul1_a&ah[2])^((al[1]^al[2])&ah[3]);
|
||||
mul1_alxh_t[2]=(al[2]&ah[0])^(al[1]&ah[1])^(mul1_aA&ah[2])^(mul1_a&ah[3]);
|
||||
mul1_alxh_t[3]=(al[3]&ah[0])^(al[2]&ah[1])^(al[1]&ah[2])^(mul1_aA&ah[3]);
|
||||
|
||||
alxh = (mul1_alxh_t);
|
||||
|
||||
end
|
||||
//mul2:
|
||||
reg[3:0] mul2_ahp_t;
|
||||
reg[3:0] mul2_aA,mul2_aB;
|
||||
|
||||
always @( d or ah_reg)
|
||||
|
||||
begin
|
||||
|
||||
//ahxd
|
||||
|
||||
mul2_aA=ah_reg[0]^ah_reg[3];
|
||||
mul2_aB=ah_reg[2]^ah_reg[3];
|
||||
|
||||
mul2_ahp_t[0]=(ah_reg[0]&d[0])^(ah_reg[3]&d[1])^(ah_reg[2]&d[2])^(ah_reg[1]&d[3]);
|
||||
mul2_ahp_t[1]=(ah_reg[1]&d[0])^(mul2_aA&d[1])^(mul2_aB&d[2])^((ah_reg[1]^ah_reg[2])&d[3]);
|
||||
mul2_ahp_t[2]=(ah_reg[2]&d[0])^(ah_reg[1]&d[1])^(mul2_aA&d[2])^(mul2_aB&d[3]);
|
||||
mul2_ahp_t[3]=(ah_reg[3]&d[0])^(ah_reg[2]&d[1])^(ah_reg[1]&d[2])^(mul2_aA&d[3]);
|
||||
|
||||
ahp = (mul2_ahp_t);
|
||||
|
||||
end
|
||||
//mul3:
|
||||
reg[3:0] mul3_alp_t;
|
||||
reg[3:0] mul3_aA,mul3_aB;
|
||||
|
||||
always @( d or alph)
|
||||
|
||||
begin
|
||||
|
||||
//dxal
|
||||
|
||||
mul3_aA=d[0]^d[3];
|
||||
mul3_aB=d[2]^d[3];
|
||||
|
||||
mul3_alp_t[0]=(d[0]&alph[0])^(d[3]&alph[1])^(d[2]&alph[2])^(d[1]&alph[3]);
|
||||
mul3_alp_t[1]=(d[1]&alph[0])^(mul3_aA&alph[1])^(mul3_aB&alph[2])^((d[1]^d[2])&alph[3]);
|
||||
mul3_alp_t[2]=(d[2]&alph[0])^(d[1]&alph[1])^(mul3_aA&alph[2])^(mul3_aB&alph[3]);
|
||||
mul3_alp_t[3]=(d[3]&alph[0])^(d[2]&alph[1])^(d[1]&alph[2])^(mul3_aA&alph[3]);
|
||||
|
||||
alp = (mul3_alp_t);
|
||||
|
||||
end
|
||||
//intermediate:
|
||||
reg[3:0] intermediate_aA,intermediate_aB;
|
||||
reg[3:0] intermediate_ah2e,intermediate_ah2epl2,intermediate_to_invert_var;
|
||||
|
||||
always @( ah2 or al2 or alxh)
|
||||
|
||||
begin
|
||||
|
||||
|
||||
//ahsquareismultipliedwithe
|
||||
intermediate_aA=ah2[0]^ah2[1];
|
||||
intermediate_aB=ah2[2]^ah2[3];
|
||||
intermediate_ah2e[0]=ah2[1]^intermediate_aB;
|
||||
intermediate_ah2e[1]=intermediate_aA;
|
||||
intermediate_ah2e[2]=intermediate_aA^ah2[2];
|
||||
intermediate_ah2e[3]=intermediate_aA^intermediate_aB;
|
||||
|
||||
//Additionofintermediate_ah2eplusal2
|
||||
intermediate_ah2epl2[0]=intermediate_ah2e[0]^al2[0];
|
||||
intermediate_ah2epl2[1]=intermediate_ah2e[1]^al2[1];
|
||||
intermediate_ah2epl2[2]=intermediate_ah2e[2]^al2[2];
|
||||
intermediate_ah2epl2[3]=intermediate_ah2e[3]^al2[3];
|
||||
|
||||
//Additionoflastresultwiththeresultof(alxah)
|
||||
intermediate_to_invert_var[0]=intermediate_ah2epl2[0]^alxh[0];
|
||||
intermediate_to_invert_var[1]=intermediate_ah2epl2[1]^alxh[1];
|
||||
intermediate_to_invert_var[2]=intermediate_ah2epl2[2]^alxh[2];
|
||||
intermediate_to_invert_var[3]=intermediate_ah2epl2[3]^alxh[3];
|
||||
|
||||
//Registers
|
||||
next_to_invert = (intermediate_to_invert_var);
|
||||
|
||||
end
|
||||
//inversion:
|
||||
reg[3:0] inversion_to_invert_var;
|
||||
reg[3:0] inversion_aA,inversion_d_t;
|
||||
|
||||
always @( to_invert)
|
||||
|
||||
begin
|
||||
|
||||
|
||||
inversion_to_invert_var=to_invert;
|
||||
|
||||
//InverttheresultinGF(2^4)
|
||||
inversion_aA=inversion_to_invert_var[1]^inversion_to_invert_var[2]^inversion_to_invert_var[3]^(inversion_to_invert_var[1]&inversion_to_invert_var[2]&inversion_to_invert_var[3]);
|
||||
inversion_d_t[0]=inversion_aA^inversion_to_invert_var[0]^(inversion_to_invert_var[0]&inversion_to_invert_var[2])^(inversion_to_invert_var[1]&inversion_to_invert_var[2])^(inversion_to_invert_var[0]&inversion_to_invert_var[1]&inversion_to_invert_var[2]);
|
||||
inversion_d_t[1]=(inversion_to_invert_var[0]&inversion_to_invert_var[1])^(inversion_to_invert_var[0]&inversion_to_invert_var[2])^(inversion_to_invert_var[1]&inversion_to_invert_var[2])^inversion_to_invert_var[3]^(inversion_to_invert_var[1]&inversion_to_invert_var[3])^(inversion_to_invert_var[0]&inversion_to_invert_var[1]&inversion_to_invert_var[3]);
|
||||
inversion_d_t[2]=(inversion_to_invert_var[0]&inversion_to_invert_var[1])^inversion_to_invert_var[2]^(inversion_to_invert_var[0]&inversion_to_invert_var[2])^inversion_to_invert_var[3]^(inversion_to_invert_var[0]&inversion_to_invert_var[3])^(inversion_to_invert_var[0]&inversion_to_invert_var[2]&inversion_to_invert_var[3]);
|
||||
inversion_d_t[3]=inversion_aA^(inversion_to_invert_var[0]&inversion_to_invert_var[3])^(inversion_to_invert_var[1]&inversion_to_invert_var[3])^(inversion_to_invert_var[2]&inversion_to_invert_var[3]);
|
||||
|
||||
d = (inversion_d_t);
|
||||
|
||||
|
||||
end
|
||||
//sum1:
|
||||
reg[3:0] sum1_alph_t;
|
||||
|
||||
always @( ah or al)
|
||||
|
||||
begin
|
||||
|
||||
|
||||
sum1_alph_t[0]=al[0]^ah[0];
|
||||
sum1_alph_t[1]=al[1]^ah[1];
|
||||
sum1_alph_t[2]=al[2]^ah[2];
|
||||
sum1_alph_t[3]=al[3]^ah[3];
|
||||
|
||||
next_alph = (sum1_alph_t);
|
||||
|
||||
end
|
||||
//square1:
|
||||
reg[3:0] square1_ah_t;
|
||||
|
||||
always @( ah)
|
||||
|
||||
begin
|
||||
|
||||
|
||||
square1_ah_t[0]=ah[0]^ah[2];
|
||||
square1_ah_t[1]=ah[2];
|
||||
square1_ah_t[2]=ah[1]^ah[3];
|
||||
square1_ah_t[3]=ah[3];
|
||||
|
||||
ah2 = (square1_ah_t);
|
||||
|
||||
end
|
||||
//square2:
|
||||
reg[3:0] square2_al_t;
|
||||
|
||||
always @( al)
|
||||
|
||||
begin
|
||||
|
||||
|
||||
square2_al_t[0]=al[0]^al[2];
|
||||
square2_al_t[1]=al[2];
|
||||
square2_al_t[2]=al[1]^al[3];
|
||||
square2_al_t[3]=al[3];
|
||||
|
||||
al2 = (square2_al_t);
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -1,259 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Subbytes module implementation ////
|
||||
//// ////
|
||||
//// This file is part of the SystemC AES ////
|
||||
//// ////
|
||||
//// Description: ////
|
||||
//// Subbytes module implementation ////
|
||||
//// ////
|
||||
//// Generated automatically using SystemC to Verilog translator ////
|
||||
//// ////
|
||||
//// To Do: ////
|
||||
//// - done ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Javier Castillo, jcastilo@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: subbytes.v,v $
|
||||
// Revision 1.1.1.1 2004/07/05 09:46:23 jcastillo
|
||||
// First import
|
||||
//
|
||||
|
||||
module subbytes(clk,reset,start_i,decrypt_i,data_i,ready_o,data_o,sbox_data_o,sbox_data_i,sbox_decrypt_o);
|
||||
input clk;
|
||||
input reset;
|
||||
input start_i;
|
||||
input decrypt_i;
|
||||
input [127:0] data_i;
|
||||
output ready_o;
|
||||
output [127:0] data_o;
|
||||
output [7:0] sbox_data_o;
|
||||
input [7:0] sbox_data_i;
|
||||
output sbox_decrypt_o;
|
||||
|
||||
reg ready_o;
|
||||
reg [127:0] data_o;
|
||||
reg [7:0] sbox_data_o;
|
||||
reg sbox_decrypt_o;
|
||||
|
||||
reg [4:0] state;
|
||||
reg [4:0] next_state;
|
||||
reg [127:0] data_reg;
|
||||
reg [127:0] next_data_reg;
|
||||
reg next_ready_o;
|
||||
|
||||
`define assign_array_to_128 \
|
||||
data_reg_128[127:120]=data_reg_var[0]; \
|
||||
data_reg_128[119:112]=data_reg_var[1]; \
|
||||
data_reg_128[111:104]=data_reg_var[2]; \
|
||||
data_reg_128[103:96]=data_reg_var[3]; \
|
||||
data_reg_128[95:88]=data_reg_var[4]; \
|
||||
data_reg_128[87:80]=data_reg_var[5]; \
|
||||
data_reg_128[79:72]=data_reg_var[6]; \
|
||||
data_reg_128[71:64]=data_reg_var[7]; \
|
||||
data_reg_128[63:56]=data_reg_var[8]; \
|
||||
data_reg_128[55:48]=data_reg_var[9]; \
|
||||
data_reg_128[47:40]=data_reg_var[10]; \
|
||||
data_reg_128[39:32]=data_reg_var[11]; \
|
||||
data_reg_128[31:24]=data_reg_var[12]; \
|
||||
data_reg_128[23:16]=data_reg_var[13]; \
|
||||
data_reg_128[15:8]=data_reg_var[14]; \
|
||||
data_reg_128[7:0]=data_reg_var[15];
|
||||
|
||||
`define shift_array_to_128 \
|
||||
data_reg_128[127:120]=data_reg_var[0]; \
|
||||
data_reg_128[119:112]=data_reg_var[5]; \
|
||||
data_reg_128[111:104]=data_reg_var[10]; \
|
||||
data_reg_128[103:96]=data_reg_var[15]; \
|
||||
data_reg_128[95:88]=data_reg_var[4]; \
|
||||
data_reg_128[87:80]=data_reg_var[9]; \
|
||||
data_reg_128[79:72]=data_reg_var[14]; \
|
||||
data_reg_128[71:64]=data_reg_var[3]; \
|
||||
data_reg_128[63:56]=data_reg_var[8]; \
|
||||
data_reg_128[55:48]=data_reg_var[13]; \
|
||||
data_reg_128[47:40]=data_reg_var[2]; \
|
||||
data_reg_128[39:32]=data_reg_var[7]; \
|
||||
data_reg_128[31:24]=data_reg_var[12]; \
|
||||
data_reg_128[23:16]=data_reg_var[1]; \
|
||||
data_reg_128[15:8]=data_reg_var[6]; \
|
||||
data_reg_128[7:0]=data_reg_var[11];
|
||||
|
||||
`define invert_shift_array_to_128 \
|
||||
data_reg_128[127:120]=data_reg_var[0]; \
|
||||
data_reg_128[119:112]=data_reg_var[13]; \
|
||||
data_reg_128[111:104]=data_reg_var[10]; \
|
||||
data_reg_128[103:96]=data_reg_var[7]; \
|
||||
data_reg_128[95:88]=data_reg_var[4]; \
|
||||
data_reg_128[87:80]=data_reg_var[1]; \
|
||||
data_reg_128[79:72]=data_reg_var[14]; \
|
||||
data_reg_128[71:64]=data_reg_var[11]; \
|
||||
data_reg_128[63:56]=data_reg_var[8]; \
|
||||
data_reg_128[55:48]=data_reg_var[5]; \
|
||||
data_reg_128[47:40]=data_reg_var[2]; \
|
||||
data_reg_128[39:32]=data_reg_var[15]; \
|
||||
data_reg_128[31:24]=data_reg_var[12]; \
|
||||
data_reg_128[23:16]=data_reg_var[9]; \
|
||||
data_reg_128[15:8]=data_reg_var[6]; \
|
||||
data_reg_128[7:0]=data_reg_var[3];
|
||||
|
||||
|
||||
//registers:
|
||||
always @(posedge clk or negedge reset)
|
||||
|
||||
begin
|
||||
|
||||
if(!reset)
|
||||
begin
|
||||
|
||||
data_reg = (0);
|
||||
state = (0);
|
||||
ready_o = (0);
|
||||
|
||||
end
|
||||
else
|
||||
begin
|
||||
|
||||
data_reg = (next_data_reg);
|
||||
state = (next_state);
|
||||
ready_o = (next_ready_o);
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
//sub:
|
||||
reg[127:0] data_i_var,data_reg_128;
|
||||
reg[7:0] data_array[15:0],data_reg_var[15:0];
|
||||
|
||||
always @( decrypt_i or start_i or state or data_i or sbox_data_i or data_reg)
|
||||
|
||||
begin
|
||||
|
||||
|
||||
data_i_var=data_i;
|
||||
|
||||
data_array[0]=data_i_var[127:120];
|
||||
data_array[1]=data_i_var[119:112];
|
||||
data_array[2]=data_i_var[111:104];
|
||||
data_array[3]=data_i_var[103:96];
|
||||
data_array[4]=data_i_var[95:88];
|
||||
data_array[5]=data_i_var[87:80];
|
||||
data_array[6]=data_i_var[79:72];
|
||||
data_array[7]=data_i_var[71:64];
|
||||
data_array[8]=data_i_var[63:56];
|
||||
data_array[9]=data_i_var[55:48];
|
||||
data_array[10]=data_i_var[47:40];
|
||||
data_array[11]=data_i_var[39:32];
|
||||
data_array[12]=data_i_var[31:24];
|
||||
data_array[13]=data_i_var[23:16];
|
||||
data_array[14]=data_i_var[15:8];
|
||||
data_array[15]=data_i_var[7:0];
|
||||
|
||||
data_reg_var[0]=data_reg[127:120];
|
||||
data_reg_var[1]=data_reg[119:112];
|
||||
data_reg_var[2]=data_reg[111:104];
|
||||
data_reg_var[3]=data_reg[103:96];
|
||||
data_reg_var[4]=data_reg[95:88];
|
||||
data_reg_var[5]=data_reg[87:80];
|
||||
data_reg_var[6]=data_reg[79:72];
|
||||
data_reg_var[7]=data_reg[71:64];
|
||||
data_reg_var[8]=data_reg[63:56];
|
||||
data_reg_var[9]=data_reg[55:48];
|
||||
data_reg_var[10]=data_reg[47:40];
|
||||
data_reg_var[11]=data_reg[39:32];
|
||||
data_reg_var[12]=data_reg[31:24];
|
||||
data_reg_var[13]=data_reg[23:16];
|
||||
data_reg_var[14]=data_reg[15:8];
|
||||
data_reg_var[15]=data_reg[7:0];
|
||||
|
||||
|
||||
sbox_decrypt_o = (decrypt_i);
|
||||
sbox_data_o = (0);
|
||||
next_state = (state);
|
||||
next_data_reg = (data_reg);
|
||||
|
||||
next_ready_o = (0);
|
||||
data_o = (data_reg);
|
||||
|
||||
case(state)
|
||||
|
||||
0:
|
||||
begin
|
||||
if(start_i)
|
||||
begin
|
||||
|
||||
sbox_data_o = (data_array[0]);
|
||||
next_state = (1);
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
16:
|
||||
begin
|
||||
data_reg_var[15]=sbox_data_i;
|
||||
//Makeshiftrowsstage
|
||||
case(decrypt_i)
|
||||
0:
|
||||
begin
|
||||
`shift_array_to_128
|
||||
end
|
||||
1:
|
||||
begin
|
||||
`invert_shift_array_to_128
|
||||
end
|
||||
endcase
|
||||
|
||||
next_data_reg = (data_reg_128);
|
||||
next_ready_o = (1);
|
||||
next_state = (0);
|
||||
end
|
||||
default:
|
||||
begin
|
||||
/* original version (causing troubles with synopsys formality):
|
||||
sbox_data_o = (data_array[state]);
|
||||
data_reg_var[state-1]=sbox_data_i;
|
||||
improved version: */
|
||||
sbox_data_o = (data_array[state & 15]);
|
||||
data_reg_var[(state-1) & 15]=sbox_data_i;
|
||||
/* end of improved version */
|
||||
`assign_array_to_128
|
||||
next_data_reg = (data_reg_128);
|
||||
next_state = (state+1);
|
||||
end
|
||||
|
||||
endcase
|
||||
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -1 +0,0 @@
|
|||
`timescale 1ns / 10ps
|
|
@ -1,124 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Mixcolumns for a 16 bit word module implementation ////
|
||||
//// ////
|
||||
//// This file is part of the SystemC AES ////
|
||||
//// ////
|
||||
//// Description: ////
|
||||
//// Mixcolum for a 16 bit word ////
|
||||
//// ////
|
||||
//// Generated automatically using SystemC to Verilog translator ////
|
||||
//// ////
|
||||
//// To Do: ////
|
||||
//// - done ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Javier Castillo, jcastilo@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: word_mixcolum.v,v $
|
||||
// Revision 1.1.1.1 2004/07/05 09:46:23 jcastillo
|
||||
// First import
|
||||
//
|
||||
|
||||
module word_mixcolum(in,outx,outy);
|
||||
input [31:0] in;
|
||||
output [31:0] outx;
|
||||
output [31:0] outy;
|
||||
|
||||
reg [31:0] outx;
|
||||
reg [31:0] outy;
|
||||
|
||||
reg [7:0] a;
|
||||
reg [7:0] b;
|
||||
reg [7:0] c;
|
||||
reg [7:0] d;
|
||||
wire [7:0] x1;
|
||||
|
||||
wire [7:0] x2;
|
||||
|
||||
wire [7:0] x3;
|
||||
|
||||
wire [7:0] x4;
|
||||
|
||||
wire [7:0] y1;
|
||||
|
||||
wire [7:0] y2;
|
||||
|
||||
wire [7:0] y3;
|
||||
|
||||
wire [7:0] y4;
|
||||
|
||||
|
||||
byte_mixcolum bm1 (.a(a), .b(b), .c(c), .d(d), .outx(x1), .outy(y1));
|
||||
byte_mixcolum bm2 (.a(b), .b(c), .c(d), .d(a), .outx(x2), .outy(y2));
|
||||
byte_mixcolum bm3 (.a(c), .b(d), .c(a), .d(b), .outx(x3), .outy(y3));
|
||||
byte_mixcolum bm4 (.a(d), .b(a), .c(b), .d(c), .outx(x4), .outy(y4));
|
||||
|
||||
|
||||
reg[31:0] in_var;
|
||||
reg[31:0] outx_var,outy_var;
|
||||
//split:
|
||||
always @( in)
|
||||
|
||||
begin
|
||||
|
||||
|
||||
|
||||
in_var=in;
|
||||
a = (in_var[31:24]);
|
||||
b = (in_var[23:16]);
|
||||
c = (in_var[15:8]);
|
||||
d = (in_var[7:0]);
|
||||
|
||||
end
|
||||
//mix:
|
||||
always @( x1 or x2 or x3 or x4 or y1 or y2 or y3 or y4)
|
||||
|
||||
begin
|
||||
|
||||
|
||||
|
||||
outx_var[31:24]=x1;
|
||||
outx_var[23:16]=x2;
|
||||
outx_var[15:8]=x3;
|
||||
outx_var[7:0]=x4;
|
||||
outy_var[31:24]=y1;
|
||||
outy_var[23:16]=y2;
|
||||
outy_var[15:8]=y3;
|
||||
outy_var[7:0]=y4;
|
||||
|
||||
outx = (outx_var);
|
||||
outy = (outy_var);
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -1 +0,0 @@
|
|||
`timescale 1ns / 10ps
|
|
@ -1,184 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// USB 1.1 PHY ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb_phy/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usb_phy.v,v 1.4 2003/10/21 05:58:40 rudi Exp $
|
||||
//
|
||||
// $Date: 2003/10/21 05:58:40 $
|
||||
// $Revision: 1.4 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: usb_phy.v,v $
|
||||
// Revision 1.4 2003/10/21 05:58:40 rudi
|
||||
// usb_rst is no longer or'ed with the incomming reset internally.
|
||||
// Now usb_rst is simply an output, the application can decide how
|
||||
// to utilize it.
|
||||
//
|
||||
// Revision 1.3 2003/10/19 17:40:13 rudi
|
||||
// - Made core more robust against line noise
|
||||
// - Added Error Checking and Reporting
|
||||
// (See README.txt for more info)
|
||||
//
|
||||
// Revision 1.2 2002/09/16 16:06:37 rudi
|
||||
// Changed top level name to be consistent ...
|
||||
//
|
||||
// Revision 1.1.1.1 2002/09/16 14:26:59 rudi
|
||||
// Created Directory Structure
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
`include "timescale.v"
|
||||
|
||||
module usb_phy(clk, rst, phy_tx_mode, usb_rst,
|
||||
|
||||
// Transciever Interface
|
||||
txdp, txdn, txoe,
|
||||
rxd, rxdp, rxdn,
|
||||
|
||||
// UTMI Interface
|
||||
DataOut_i, TxValid_i, TxReady_o, RxValid_o,
|
||||
RxActive_o, RxError_o, DataIn_o, LineState_o
|
||||
);
|
||||
|
||||
input clk;
|
||||
input rst;
|
||||
input phy_tx_mode;
|
||||
output usb_rst;
|
||||
output txdp, txdn, txoe;
|
||||
input rxd, rxdp, rxdn;
|
||||
input [7:0] DataOut_i;
|
||||
input TxValid_i;
|
||||
output TxReady_o;
|
||||
output [7:0] DataIn_o;
|
||||
output RxValid_o;
|
||||
output RxActive_o;
|
||||
output RxError_o;
|
||||
output [1:0] LineState_o;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and Registers
|
||||
//
|
||||
|
||||
reg [4:0] rst_cnt;
|
||||
reg usb_rst;
|
||||
wire fs_ce;
|
||||
wire rst;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc Logic
|
||||
//
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TX Phy
|
||||
//
|
||||
|
||||
usb_tx_phy i_tx_phy(
|
||||
.clk( clk ),
|
||||
.rst( rst ),
|
||||
.fs_ce( fs_ce ),
|
||||
.phy_mode( phy_tx_mode ),
|
||||
|
||||
// Transciever Interface
|
||||
.txdp( txdp ),
|
||||
.txdn( txdn ),
|
||||
.txoe( txoe ),
|
||||
|
||||
// UTMI Interface
|
||||
.DataOut_i( DataOut_i ),
|
||||
.TxValid_i( TxValid_i ),
|
||||
.TxReady_o( TxReady_o )
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// RX Phy and DPLL
|
||||
//
|
||||
|
||||
usb_rx_phy i_rx_phy(
|
||||
.clk( clk ),
|
||||
.rst( rst ),
|
||||
.fs_ce( fs_ce ),
|
||||
|
||||
// Transciever Interface
|
||||
.rxd( rxd ),
|
||||
.rxdp( rxdp ),
|
||||
.rxdn( rxdn ),
|
||||
|
||||
// UTMI Interface
|
||||
.DataIn_o( DataIn_o ),
|
||||
.RxValid_o( RxValid_o ),
|
||||
.RxActive_o( RxActive_o ),
|
||||
.RxError_o( RxError_o ),
|
||||
.RxEn_i( txoe ),
|
||||
.LineState( LineState_o )
|
||||
);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generate an USB Reset is we see SE0 for at least 2.5uS
|
||||
//
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) rst_cnt <= 5'h0;
|
||||
else
|
||||
if(LineState_o != 2'h0) rst_cnt <= 5'h0;
|
||||
else
|
||||
if(!usb_rst && fs_ce) rst_cnt <= rst_cnt + 5'h1;
|
||||
|
||||
always @(posedge clk)
|
||||
usb_rst <= (rst_cnt == 5'h1f);
|
||||
|
||||
endmodule
|
||||
|
|
@ -1,452 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// USB 1.1 PHY ////
|
||||
//// RX & DPLL ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb_phy/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usb_rx_phy.v,v 1.5 2004/10/19 09:29:07 rudi Exp $
|
||||
//
|
||||
// $Date: 2004/10/19 09:29:07 $
|
||||
// $Revision: 1.5 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: usb_rx_phy.v,v $
|
||||
// Revision 1.5 2004/10/19 09:29:07 rudi
|
||||
// Fixed DPLL alignment in the rx_phy and bit stuffing errors in the tx_phy (if last bit bit was a stuff bit in a packet it was omitted).
|
||||
//
|
||||
// Revision 1.4 2003/12/02 04:56:00 rudi
|
||||
// Fixed a bug reported by Karl C. Posch from Graz University of Technology. Thanks Karl !
|
||||
//
|
||||
// Revision 1.3 2003/10/19 18:07:45 rudi
|
||||
// - Fixed Sync Error to be only checked/generated during the sync phase
|
||||
//
|
||||
// Revision 1.2 2003/10/19 17:40:13 rudi
|
||||
// - Made core more robust against line noise
|
||||
// - Added Error Checking and Reporting
|
||||
// (See README.txt for more info)
|
||||
//
|
||||
// Revision 1.1.1.1 2002/09/16 14:27:01 rudi
|
||||
// Created Directory Structure
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
`include "timescale.v"
|
||||
|
||||
module usb_rx_phy( clk, rst, fs_ce,
|
||||
|
||||
// Transciever Interface
|
||||
rxd, rxdp, rxdn,
|
||||
|
||||
// UTMI Interface
|
||||
RxValid_o, RxActive_o, RxError_o, DataIn_o,
|
||||
RxEn_i, LineState);
|
||||
|
||||
input clk;
|
||||
input rst;
|
||||
output fs_ce;
|
||||
input rxd, rxdp, rxdn;
|
||||
output [7:0] DataIn_o;
|
||||
output RxValid_o;
|
||||
output RxActive_o;
|
||||
output RxError_o;
|
||||
input RxEn_i;
|
||||
output [1:0] LineState;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and Registers
|
||||
//
|
||||
|
||||
reg rxd_s0, rxd_s1, rxd_s;
|
||||
reg rxdp_s0, rxdp_s1, rxdp_s, rxdp_s_r;
|
||||
reg rxdn_s0, rxdn_s1, rxdn_s, rxdn_s_r;
|
||||
reg synced_d;
|
||||
wire k, j, se0;
|
||||
reg rxd_r;
|
||||
reg rx_en;
|
||||
reg rx_active;
|
||||
reg [2:0] bit_cnt;
|
||||
reg rx_valid1, rx_valid;
|
||||
reg shift_en;
|
||||
reg sd_r;
|
||||
reg sd_nrzi;
|
||||
reg [7:0] hold_reg;
|
||||
wire drop_bit; // Indicates a stuffed bit
|
||||
reg [2:0] one_cnt;
|
||||
|
||||
reg [1:0] dpll_state, dpll_next_state;
|
||||
reg fs_ce_d;
|
||||
reg fs_ce;
|
||||
wire change;
|
||||
wire lock_en;
|
||||
reg [2:0] fs_state, fs_next_state;
|
||||
reg rx_valid_r;
|
||||
reg sync_err_d, sync_err;
|
||||
reg bit_stuff_err;
|
||||
reg se0_r, byte_err;
|
||||
reg se0_s;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc Logic
|
||||
//
|
||||
|
||||
assign RxActive_o = rx_active;
|
||||
assign RxValid_o = rx_valid;
|
||||
assign RxError_o = sync_err | bit_stuff_err | byte_err;
|
||||
assign DataIn_o = hold_reg;
|
||||
assign LineState = {rxdn_s1, rxdp_s1};
|
||||
|
||||
always @(posedge clk) rx_en <= RxEn_i;
|
||||
always @(posedge clk) sync_err <= !rx_active & sync_err_d;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Synchronize Inputs
|
||||
//
|
||||
|
||||
// First synchronize to the local system clock to
|
||||
// avoid metastability outside the sync block (*_s0).
|
||||
// Then make sure we see the signal for at least two
|
||||
// clock cycles stable to avoid glitches and noise
|
||||
|
||||
always @(posedge clk) rxd_s0 <= rxd;
|
||||
always @(posedge clk) rxd_s1 <= rxd_s0;
|
||||
always @(posedge clk) // Avoid detecting Line Glitches and noise
|
||||
if(rxd_s0 && rxd_s1) rxd_s <= 1'b1;
|
||||
else
|
||||
if(!rxd_s0 && !rxd_s1) rxd_s <= 1'b0;
|
||||
|
||||
always @(posedge clk) rxdp_s0 <= rxdp;
|
||||
always @(posedge clk) rxdp_s1 <= rxdp_s0;
|
||||
always @(posedge clk) rxdp_s_r <= rxdp_s0 & rxdp_s1;
|
||||
always @(posedge clk) rxdp_s <= (rxdp_s0 & rxdp_s1) | rxdp_s_r; // Avoid detecting Line Glitches and noise
|
||||
|
||||
always @(posedge clk) rxdn_s0 <= rxdn;
|
||||
always @(posedge clk) rxdn_s1 <= rxdn_s0;
|
||||
always @(posedge clk) rxdn_s_r <= rxdn_s0 & rxdn_s1;
|
||||
always @(posedge clk) rxdn_s <= (rxdn_s0 & rxdn_s1) | rxdn_s_r; // Avoid detecting Line Glitches and noise
|
||||
|
||||
assign k = !rxdp_s & rxdn_s;
|
||||
assign j = rxdp_s & !rxdn_s;
|
||||
assign se0 = !rxdp_s & !rxdn_s;
|
||||
|
||||
always @(posedge clk) if(fs_ce) se0_s <= se0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DPLL
|
||||
//
|
||||
|
||||
// This design uses a clock enable to do 12Mhz timing and not a
|
||||
// real 12Mhz clock. Everything always runs at 48Mhz. We want to
|
||||
// make sure however, that the clock enable is always exactly in
|
||||
// the middle between two virtual 12Mhz rising edges.
|
||||
// We monitor rxdp and rxdn for any changes and do the appropiate
|
||||
// adjustments.
|
||||
// In addition to the locking done in the dpll FSM, we adjust the
|
||||
// final latch enable to compensate for various sync registers ...
|
||||
|
||||
// Allow lockinf only when we are receiving
|
||||
assign lock_en = rx_en;
|
||||
|
||||
always @(posedge clk) rxd_r <= rxd_s;
|
||||
|
||||
// Edge detector
|
||||
assign change = rxd_r != rxd_s;
|
||||
|
||||
// DPLL FSM
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) dpll_state <= 2'h1;
|
||||
else dpll_state <= dpll_next_state;
|
||||
|
||||
always @(dpll_state or lock_en or change)
|
||||
begin
|
||||
fs_ce_d = 1'b0;
|
||||
case(dpll_state) // synopsys full_case parallel_case
|
||||
2'h0:
|
||||
if(lock_en && change) dpll_next_state = 2'h0;
|
||||
else dpll_next_state = 2'h1;
|
||||
2'h1:begin
|
||||
fs_ce_d = 1'b1;
|
||||
if(lock_en && change) dpll_next_state = 2'h3;
|
||||
else dpll_next_state = 2'h2;
|
||||
end
|
||||
2'h2:
|
||||
if(lock_en && change) dpll_next_state = 2'h0;
|
||||
else dpll_next_state = 2'h3;
|
||||
2'h3:
|
||||
if(lock_en && change) dpll_next_state = 2'h0;
|
||||
else dpll_next_state = 2'h0;
|
||||
endcase
|
||||
end
|
||||
|
||||
// Compensate for sync registers at the input - allign full speed
|
||||
// clock enable to be in the middle between two bit changes ...
|
||||
reg fs_ce_r1, fs_ce_r2;
|
||||
|
||||
always @(posedge clk) fs_ce_r1 <= fs_ce_d;
|
||||
always @(posedge clk) fs_ce_r2 <= fs_ce_r1;
|
||||
always @(posedge clk) fs_ce <= fs_ce_r2;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Find Sync Pattern FSM
|
||||
//
|
||||
|
||||
parameter FS_IDLE = 3'h0,
|
||||
K1 = 3'h1,
|
||||
J1 = 3'h2,
|
||||
K2 = 3'h3,
|
||||
J2 = 3'h4,
|
||||
K3 = 3'h5,
|
||||
J3 = 3'h6,
|
||||
K4 = 3'h7;
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) fs_state <= FS_IDLE;
|
||||
else fs_state <= fs_next_state;
|
||||
|
||||
always @(fs_state or fs_ce or k or j or rx_en or rx_active or se0 or se0_s)
|
||||
begin
|
||||
synced_d = 1'b0;
|
||||
sync_err_d = 1'b0;
|
||||
fs_next_state = fs_state;
|
||||
if(fs_ce && !rx_active && !se0 && !se0_s)
|
||||
case(fs_state) // synopsys full_case parallel_case
|
||||
FS_IDLE:
|
||||
begin
|
||||
if(k && rx_en) fs_next_state = K1;
|
||||
end
|
||||
K1:
|
||||
begin
|
||||
if(j && rx_en) fs_next_state = J1;
|
||||
else
|
||||
begin
|
||||
sync_err_d = 1'b1;
|
||||
fs_next_state = FS_IDLE;
|
||||
end
|
||||
end
|
||||
J1:
|
||||
begin
|
||||
if(k && rx_en) fs_next_state = K2;
|
||||
else
|
||||
begin
|
||||
sync_err_d = 1'b1;
|
||||
fs_next_state = FS_IDLE;
|
||||
end
|
||||
end
|
||||
K2:
|
||||
begin
|
||||
if(j && rx_en) fs_next_state = J2;
|
||||
else
|
||||
begin
|
||||
sync_err_d = 1'b1;
|
||||
fs_next_state = FS_IDLE;
|
||||
end
|
||||
end
|
||||
J2:
|
||||
begin
|
||||
if(k && rx_en) fs_next_state = K3;
|
||||
else
|
||||
begin
|
||||
sync_err_d = 1'b1;
|
||||
fs_next_state = FS_IDLE;
|
||||
end
|
||||
end
|
||||
K3:
|
||||
begin
|
||||
if(j && rx_en) fs_next_state = J3;
|
||||
else
|
||||
if(k && rx_en)
|
||||
begin
|
||||
fs_next_state = FS_IDLE; // Allow missing first K-J
|
||||
synced_d = 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
sync_err_d = 1'b1;
|
||||
fs_next_state = FS_IDLE;
|
||||
end
|
||||
end
|
||||
J3:
|
||||
begin
|
||||
if(k && rx_en) fs_next_state = K4;
|
||||
else
|
||||
begin
|
||||
sync_err_d = 1'b1;
|
||||
fs_next_state = FS_IDLE;
|
||||
end
|
||||
end
|
||||
K4:
|
||||
begin
|
||||
if(k) synced_d = 1'b1;
|
||||
fs_next_state = FS_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generate RxActive
|
||||
//
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) rx_active <= 1'b0;
|
||||
else
|
||||
if(synced_d && rx_en) rx_active <= 1'b1;
|
||||
else
|
||||
if(se0 && rx_valid_r) rx_active <= 1'b0;
|
||||
|
||||
always @(posedge clk)
|
||||
if(rx_valid) rx_valid_r <= 1'b1;
|
||||
else
|
||||
if(fs_ce) rx_valid_r <= 1'b0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// NRZI Decoder
|
||||
//
|
||||
|
||||
always @(posedge clk)
|
||||
if(fs_ce) sd_r <= rxd_s;
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) sd_nrzi <= 1'b0;
|
||||
else
|
||||
if(!rx_active) sd_nrzi <= 1'b1;
|
||||
else
|
||||
if(rx_active && fs_ce) sd_nrzi <= !(rxd_s ^ sd_r);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bit Stuff Detect
|
||||
//
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) one_cnt <= 3'h0;
|
||||
else
|
||||
if(!shift_en) one_cnt <= 3'h0;
|
||||
else
|
||||
if(fs_ce)
|
||||
begin
|
||||
if(!sd_nrzi || drop_bit) one_cnt <= 3'h0;
|
||||
else one_cnt <= one_cnt + 3'h1;
|
||||
end
|
||||
|
||||
assign drop_bit = (one_cnt==3'h6);
|
||||
|
||||
always @(posedge clk) bit_stuff_err <= drop_bit & sd_nrzi & fs_ce & !se0 & rx_active; // Bit Stuff Error
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Serial => Parallel converter
|
||||
//
|
||||
|
||||
always @(posedge clk)
|
||||
if(fs_ce) shift_en <= synced_d | rx_active;
|
||||
|
||||
always @(posedge clk)
|
||||
if(fs_ce && shift_en && !drop_bit)
|
||||
hold_reg <= {sd_nrzi, hold_reg[7:1]};
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generate RxValid
|
||||
//
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) bit_cnt <= 3'b0;
|
||||
else
|
||||
if(!shift_en) bit_cnt <= 3'h0;
|
||||
else
|
||||
if(fs_ce && !drop_bit) bit_cnt <= bit_cnt + 3'h1;
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) rx_valid1 <= 1'b0;
|
||||
else
|
||||
if(fs_ce && !drop_bit && (bit_cnt==3'h7)) rx_valid1 <= 1'b1;
|
||||
else
|
||||
if(rx_valid1 && fs_ce && !drop_bit) rx_valid1 <= 1'b0;
|
||||
|
||||
always @(posedge clk) rx_valid <= !drop_bit & rx_valid1 & fs_ce;
|
||||
|
||||
always @(posedge clk) se0_r <= se0;
|
||||
|
||||
always @(posedge clk) byte_err <= se0 & !se0_r & (|bit_cnt[2:1]) & rx_active;
|
||||
|
||||
endmodule
|
||||
|
|
@ -1,465 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// USB 1.1 PHY ////
|
||||
//// TX ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/usb_phy/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2002 Rudolf Usselmann ////
|
||||
//// www.asics.ws ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: usb_tx_phy.v,v 1.4 2004/10/19 09:29:07 rudi Exp $
|
||||
//
|
||||
// $Date: 2004/10/19 09:29:07 $
|
||||
// $Revision: 1.4 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: usb_tx_phy.v,v $
|
||||
// Revision 1.4 2004/10/19 09:29:07 rudi
|
||||
// Fixed DPLL alignment in the rx_phy and bit stuffing errors in the tx_phy (if last bit bit was a stuff bit in a packet it was omitted).
|
||||
//
|
||||
// Revision 1.3 2003/10/21 05:58:41 rudi
|
||||
// usb_rst is no longer or'ed with the incomming reset internally.
|
||||
// Now usb_rst is simply an output, the application can decide how
|
||||
// to utilize it.
|
||||
//
|
||||
// Revision 1.2 2003/10/19 17:40:13 rudi
|
||||
// - Made core more robust against line noise
|
||||
// - Added Error Checking and Reporting
|
||||
// (See README.txt for more info)
|
||||
//
|
||||
// Revision 1.1.1.1 2002/09/16 14:27:02 rudi
|
||||
// Created Directory Structure
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
`include "timescale.v"
|
||||
|
||||
module usb_tx_phy(
|
||||
clk, rst, fs_ce, phy_mode,
|
||||
|
||||
// Transciever Interface
|
||||
txdp, txdn, txoe,
|
||||
|
||||
// UTMI Interface
|
||||
DataOut_i, TxValid_i, TxReady_o
|
||||
);
|
||||
|
||||
input clk;
|
||||
input rst;
|
||||
input fs_ce;
|
||||
input phy_mode;
|
||||
output txdp, txdn, txoe;
|
||||
input [7:0] DataOut_i;
|
||||
input TxValid_i;
|
||||
output TxReady_o;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires and Registers
|
||||
//
|
||||
|
||||
parameter IDLE = 3'd0,
|
||||
SOP = 3'h1,
|
||||
DATA = 3'h2,
|
||||
EOP1 = 3'h3,
|
||||
EOP2 = 3'h4,
|
||||
WAIT = 3'h5;
|
||||
|
||||
reg TxReady_o;
|
||||
reg [2:0] state, next_state;
|
||||
reg tx_ready_d;
|
||||
reg ld_sop_d;
|
||||
reg ld_data_d;
|
||||
reg ld_eop_d;
|
||||
reg tx_ip;
|
||||
reg tx_ip_sync;
|
||||
reg [2:0] bit_cnt;
|
||||
reg [7:0] hold_reg;
|
||||
reg [7:0] hold_reg_d;
|
||||
|
||||
reg sd_raw_o;
|
||||
wire hold;
|
||||
reg data_done;
|
||||
reg sft_done;
|
||||
reg sft_done_r;
|
||||
wire sft_done_e;
|
||||
reg ld_data;
|
||||
wire eop_done;
|
||||
reg [2:0] one_cnt;
|
||||
wire stuff;
|
||||
reg sd_bs_o;
|
||||
reg sd_nrzi_o;
|
||||
reg append_eop;
|
||||
reg append_eop_sync1;
|
||||
reg append_eop_sync2;
|
||||
reg append_eop_sync3;
|
||||
reg append_eop_sync4;
|
||||
reg txdp, txdn;
|
||||
reg txoe_r1, txoe_r2;
|
||||
reg txoe;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Misc Logic
|
||||
//
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) TxReady_o <= 1'b0;
|
||||
else TxReady_o <= tx_ready_d & TxValid_i;
|
||||
|
||||
always @(posedge clk) ld_data <= ld_data_d;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Transmit in progress indicator
|
||||
//
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) tx_ip <= 1'b0;
|
||||
else
|
||||
if(ld_sop_d) tx_ip <= 1'b1;
|
||||
else
|
||||
if(eop_done) tx_ip <= 1'b0;
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) tx_ip_sync <= 1'b0;
|
||||
else
|
||||
if(fs_ce) tx_ip_sync <= tx_ip;
|
||||
|
||||
// data_done helps us to catch cases where TxValid drops due to
|
||||
// packet end and then gets re-asserted as a new packet starts.
|
||||
// We might not see this because we are still transmitting.
|
||||
// data_done should solve those cases ...
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) data_done <= 1'b0;
|
||||
else
|
||||
if(TxValid_i && ! tx_ip) data_done <= 1'b1;
|
||||
else
|
||||
if(!TxValid_i) data_done <= 1'b0;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Shift Register
|
||||
//
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) bit_cnt <= 3'h0;
|
||||
else
|
||||
if(!tx_ip_sync) bit_cnt <= 3'h0;
|
||||
else
|
||||
if(fs_ce && !hold) bit_cnt <= bit_cnt + 3'h1;
|
||||
|
||||
assign hold = stuff;
|
||||
|
||||
always @(posedge clk)
|
||||
if(!tx_ip_sync) sd_raw_o <= 1'b0;
|
||||
else
|
||||
case(bit_cnt) // synopsys full_case parallel_case
|
||||
3'h0: sd_raw_o <= hold_reg_d[0];
|
||||
3'h1: sd_raw_o <= hold_reg_d[1];
|
||||
3'h2: sd_raw_o <= hold_reg_d[2];
|
||||
3'h3: sd_raw_o <= hold_reg_d[3];
|
||||
3'h4: sd_raw_o <= hold_reg_d[4];
|
||||
3'h5: sd_raw_o <= hold_reg_d[5];
|
||||
3'h6: sd_raw_o <= hold_reg_d[6];
|
||||
3'h7: sd_raw_o <= hold_reg_d[7];
|
||||
endcase
|
||||
|
||||
always @(posedge clk)
|
||||
sft_done <= !hold & (bit_cnt == 3'h7);
|
||||
|
||||
always @(posedge clk)
|
||||
sft_done_r <= sft_done;
|
||||
|
||||
assign sft_done_e = sft_done & !sft_done_r;
|
||||
|
||||
// Out Data Hold Register
|
||||
always @(posedge clk)
|
||||
if(ld_sop_d) hold_reg <= 8'h80;
|
||||
else
|
||||
if(ld_data) hold_reg <= DataOut_i;
|
||||
|
||||
always @(posedge clk) hold_reg_d <= hold_reg;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bit Stuffer
|
||||
//
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) one_cnt <= 3'h0;
|
||||
else
|
||||
if(!tx_ip_sync) one_cnt <= 3'h0;
|
||||
else
|
||||
if(fs_ce)
|
||||
begin
|
||||
if(!sd_raw_o || stuff) one_cnt <= 3'h0;
|
||||
else one_cnt <= one_cnt + 3'h1;
|
||||
end
|
||||
|
||||
assign stuff = (one_cnt==3'h6);
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) sd_bs_o <= 1'h0;
|
||||
else
|
||||
if(fs_ce) sd_bs_o <= !tx_ip_sync ? 1'b0 : (stuff ? 1'b0 : sd_raw_o);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// NRZI Encoder
|
||||
//
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) sd_nrzi_o <= 1'b1;
|
||||
else
|
||||
if(!tx_ip_sync || !txoe_r1) sd_nrzi_o <= 1'b1;
|
||||
else
|
||||
if(fs_ce) sd_nrzi_o <= sd_bs_o ? sd_nrzi_o : ~sd_nrzi_o;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// EOP append logic
|
||||
//
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) append_eop <= 1'b0;
|
||||
else
|
||||
if(ld_eop_d) append_eop <= 1'b1;
|
||||
else
|
||||
if(append_eop_sync2) append_eop <= 1'b0;
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) append_eop_sync1 <= 1'b0;
|
||||
else
|
||||
if(fs_ce) append_eop_sync1 <= append_eop;
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) append_eop_sync2 <= 1'b0;
|
||||
else
|
||||
if(fs_ce) append_eop_sync2 <= append_eop_sync1;
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) append_eop_sync3 <= 1'b0;
|
||||
else
|
||||
if(fs_ce) append_eop_sync3 <= append_eop_sync2 |
|
||||
(append_eop_sync3 & !append_eop_sync4); // Make sure always 2 bit wide
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) append_eop_sync4 <= 1'b0;
|
||||
else
|
||||
if(fs_ce) append_eop_sync4 <= append_eop_sync3;
|
||||
|
||||
assign eop_done = append_eop_sync3;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Output Enable Logic
|
||||
//
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) txoe_r1 <= 1'b0;
|
||||
else
|
||||
if(fs_ce) txoe_r1 <= tx_ip_sync;
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) txoe_r2 <= 1'b0;
|
||||
else
|
||||
if(fs_ce) txoe_r2 <= txoe_r1;
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) txoe <= 1'b1;
|
||||
else
|
||||
if(fs_ce) txoe <= !(txoe_r1 | txoe_r2);
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Output Registers
|
||||
//
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) txdp <= 1'b1;
|
||||
else
|
||||
if(fs_ce) txdp <= phy_mode ?
|
||||
(!append_eop_sync3 & sd_nrzi_o) :
|
||||
sd_nrzi_o;
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) txdn <= 1'b0;
|
||||
else
|
||||
if(fs_ce) txdn <= phy_mode ?
|
||||
(!append_eop_sync3 & ~sd_nrzi_o) :
|
||||
append_eop_sync3;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Tx Statemashine
|
||||
//
|
||||
|
||||
`ifdef USB_ASYNC_REST
|
||||
always @(posedge clk or negedge rst)
|
||||
`else
|
||||
always @(posedge clk)
|
||||
`endif
|
||||
if(!rst) state <= IDLE;
|
||||
else state <= next_state;
|
||||
|
||||
always @(state or TxValid_i or data_done or sft_done_e or eop_done or fs_ce)
|
||||
begin
|
||||
next_state = state;
|
||||
tx_ready_d = 1'b0;
|
||||
|
||||
ld_sop_d = 1'b0;
|
||||
ld_data_d = 1'b0;
|
||||
ld_eop_d = 1'b0;
|
||||
|
||||
case(state) // synopsys full_case parallel_case
|
||||
IDLE:
|
||||
if(TxValid_i)
|
||||
begin
|
||||
ld_sop_d = 1'b1;
|
||||
next_state = SOP;
|
||||
end
|
||||
SOP:
|
||||
if(sft_done_e)
|
||||
begin
|
||||
tx_ready_d = 1'b1;
|
||||
ld_data_d = 1'b1;
|
||||
next_state = DATA;
|
||||
end
|
||||
DATA:
|
||||
begin
|
||||
if(!data_done && sft_done_e)
|
||||
begin
|
||||
ld_eop_d = 1'b1;
|
||||
next_state = EOP1;
|
||||
end
|
||||
|
||||
if(data_done && sft_done_e)
|
||||
begin
|
||||
tx_ready_d = 1'b1;
|
||||
ld_data_d = 1'b1;
|
||||
end
|
||||
end
|
||||
EOP1:
|
||||
if(eop_done) next_state = EOP2;
|
||||
EOP2:
|
||||
if(!eop_done && fs_ce) next_state = WAIT;
|
||||
WAIT:
|
||||
if(fs_ce) next_state = IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
3
tests/openmsp430/.gitignore
vendored
3
tests/openmsp430/.gitignore
vendored
|
@ -1,3 +0,0 @@
|
|||
fsm_info.txt
|
||||
synth.v
|
||||
synth.log
|
|
@ -1,258 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_alu.v
|
||||
//
|
||||
// *Module Description:
|
||||
// openMSP430 ALU
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 134 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
|
||||
//----------------------------------------------------------------------------
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_defines.v"
|
||||
`endif
|
||||
|
||||
module omsp_alu (
|
||||
|
||||
// OUTPUTs
|
||||
alu_out, // ALU output value
|
||||
alu_out_add, // ALU adder output value
|
||||
alu_stat, // ALU Status {V,N,Z,C}
|
||||
alu_stat_wr, // ALU Status write {V,N,Z,C}
|
||||
|
||||
// INPUTs
|
||||
dbg_halt_st, // Halt/Run status from CPU
|
||||
exec_cycle, // Instruction execution cycle
|
||||
inst_alu, // ALU control signals
|
||||
inst_bw, // Decoded Inst: byte width
|
||||
inst_jmp, // Decoded Inst: Conditional jump
|
||||
inst_so, // Single-operand arithmetic
|
||||
op_dst, // Destination operand
|
||||
op_src, // Source operand
|
||||
status // R2 Status {V,N,Z,C}
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output [15:0] alu_out; // ALU output value
|
||||
output [15:0] alu_out_add; // ALU adder output value
|
||||
output [3:0] alu_stat; // ALU Status {V,N,Z,C}
|
||||
output [3:0] alu_stat_wr; // ALU Status write {V,N,Z,C}
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input dbg_halt_st; // Halt/Run status from CPU
|
||||
input exec_cycle; // Instruction execution cycle
|
||||
input [11:0] inst_alu; // ALU control signals
|
||||
input inst_bw; // Decoded Inst: byte width
|
||||
input [7:0] inst_jmp; // Decoded Inst: Conditional jump
|
||||
input [7:0] inst_so; // Single-operand arithmetic
|
||||
input [15:0] op_dst; // Destination operand
|
||||
input [15:0] op_src; // Source operand
|
||||
input [3:0] status; // R2 Status {V,N,Z,C}
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) FUNCTIONS
|
||||
//=============================================================================
|
||||
|
||||
function [4:0] bcd_add;
|
||||
|
||||
input [3:0] X;
|
||||
input [3:0] Y;
|
||||
input C_;
|
||||
|
||||
reg [4:0] Z_;
|
||||
begin
|
||||
Z_ = {1'b0,X}+{1'b0,Y}+{4'b0,C_};
|
||||
if (Z_<5'd10) bcd_add = Z_;
|
||||
else bcd_add = Z_+5'd6;
|
||||
end
|
||||
|
||||
endfunction
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 2) INSTRUCTION FETCH/DECODE CONTROL STATE MACHINE
|
||||
//=============================================================================
|
||||
// SINGLE-OPERAND ARITHMETIC:
|
||||
//-----------------------------------------------------------------------------
|
||||
// Mnemonic S-Reg, Operation Status bits
|
||||
// D-Reg, V N Z C
|
||||
//
|
||||
// RRC dst C->MSB->...LSB->C * * * *
|
||||
// RRA dst MSB->MSB->...LSB->C 0 * * *
|
||||
// SWPB dst Swap bytes - - - -
|
||||
// SXT dst Bit7->Bit8...Bit15 0 * * *
|
||||
// PUSH src SP-2->SP, src->@SP - - - -
|
||||
// CALL dst SP-2->SP, PC+2->@SP, dst->PC - - - -
|
||||
// RETI TOS->SR, SP+2->SP, TOS->PC, SP+2->SP * * * *
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// TWO-OPERAND ARITHMETIC:
|
||||
//-----------------------------------------------------------------------------
|
||||
// Mnemonic S-Reg, Operation Status bits
|
||||
// D-Reg, V N Z C
|
||||
//
|
||||
// MOV src,dst src -> dst - - - -
|
||||
// ADD src,dst src + dst -> dst * * * *
|
||||
// ADDC src,dst src + dst + C -> dst * * * *
|
||||
// SUB src,dst dst + ~src + 1 -> dst * * * *
|
||||
// SUBC src,dst dst + ~src + C -> dst * * * *
|
||||
// CMP src,dst dst + ~src + 1 * * * *
|
||||
// DADD src,dst src + dst + C -> dst (decimaly) * * * *
|
||||
// BIT src,dst src & dst 0 * * *
|
||||
// BIC src,dst ~src & dst -> dst - - - -
|
||||
// BIS src,dst src | dst -> dst - - - -
|
||||
// XOR src,dst src ^ dst -> dst * * * *
|
||||
// AND src,dst src & dst -> dst 0 * * *
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
// * the status bit is affected
|
||||
// - the status bit is not affected
|
||||
// 0 the status bit is cleared
|
||||
// 1 the status bit is set
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Invert source for substract and compare instructions.
|
||||
wire op_src_inv_cmd = exec_cycle & (inst_alu[`ALU_SRC_INV]);
|
||||
wire [15:0] op_src_inv = {16{op_src_inv_cmd}} ^ op_src;
|
||||
|
||||
|
||||
// Mask the bit 8 for the Byte instructions for correct flags generation
|
||||
wire op_bit8_msk = ~exec_cycle | ~inst_bw;
|
||||
wire [16:0] op_src_in = {1'b0, {op_src_inv[15:8] & {8{op_bit8_msk}}}, op_src_inv[7:0]};
|
||||
wire [16:0] op_dst_in = {1'b0, {op_dst[15:8] & {8{op_bit8_msk}}}, op_dst[7:0]};
|
||||
|
||||
// Clear the source operand (= jump offset) for conditional jumps
|
||||
wire jmp_not_taken = (inst_jmp[`JL] & ~(status[3]^status[2])) |
|
||||
(inst_jmp[`JGE] & (status[3]^status[2])) |
|
||||
(inst_jmp[`JN] & ~status[2]) |
|
||||
(inst_jmp[`JC] & ~status[0]) |
|
||||
(inst_jmp[`JNC] & status[0]) |
|
||||
(inst_jmp[`JEQ] & ~status[1]) |
|
||||
(inst_jmp[`JNE] & status[1]);
|
||||
wire [16:0] op_src_in_jmp = op_src_in & {17{~jmp_not_taken}};
|
||||
|
||||
// Adder / AND / OR / XOR
|
||||
wire [16:0] alu_add = op_src_in_jmp + op_dst_in;
|
||||
wire [16:0] alu_and = op_src_in & op_dst_in;
|
||||
wire [16:0] alu_or = op_src_in | op_dst_in;
|
||||
wire [16:0] alu_xor = op_src_in ^ op_dst_in;
|
||||
|
||||
|
||||
// Incrementer
|
||||
wire alu_inc = exec_cycle & ((inst_alu[`ALU_INC_C] & status[0]) |
|
||||
inst_alu[`ALU_INC]);
|
||||
wire [16:0] alu_add_inc = alu_add + {16'h0000, alu_inc};
|
||||
|
||||
|
||||
|
||||
// Decimal adder (DADD)
|
||||
wire [4:0] alu_dadd0 = bcd_add(op_src_in[3:0], op_dst_in[3:0], status[0]);
|
||||
wire [4:0] alu_dadd1 = bcd_add(op_src_in[7:4], op_dst_in[7:4], alu_dadd0[4]);
|
||||
wire [4:0] alu_dadd2 = bcd_add(op_src_in[11:8], op_dst_in[11:8], alu_dadd1[4]);
|
||||
wire [4:0] alu_dadd3 = bcd_add(op_src_in[15:12], op_dst_in[15:12],alu_dadd2[4]);
|
||||
wire [16:0] alu_dadd = {alu_dadd3, alu_dadd2[3:0], alu_dadd1[3:0], alu_dadd0[3:0]};
|
||||
|
||||
|
||||
// Shifter for rotate instructions (RRC & RRA)
|
||||
wire alu_shift_msb = inst_so[`RRC] ? status[0] :
|
||||
inst_bw ? op_src[7] : op_src[15];
|
||||
wire alu_shift_7 = inst_bw ? alu_shift_msb : op_src[8];
|
||||
wire [16:0] alu_shift = {1'b0, alu_shift_msb, op_src[15:9], alu_shift_7, op_src[7:1]};
|
||||
|
||||
|
||||
// Swap bytes / Extend Sign
|
||||
wire [16:0] alu_swpb = {1'b0, op_src[7:0],op_src[15:8]};
|
||||
wire [16:0] alu_sxt = {1'b0, {8{op_src[7]}},op_src[7:0]};
|
||||
|
||||
|
||||
// Combine short paths toghether to simplify final ALU mux
|
||||
wire alu_short_thro = ~(inst_alu[`ALU_AND] |
|
||||
inst_alu[`ALU_OR] |
|
||||
inst_alu[`ALU_XOR] |
|
||||
inst_alu[`ALU_SHIFT] |
|
||||
inst_so[`SWPB] |
|
||||
inst_so[`SXT]);
|
||||
|
||||
wire [16:0] alu_short = ({17{inst_alu[`ALU_AND]}} & alu_and) |
|
||||
({17{inst_alu[`ALU_OR]}} & alu_or) |
|
||||
({17{inst_alu[`ALU_XOR]}} & alu_xor) |
|
||||
({17{inst_alu[`ALU_SHIFT]}} & alu_shift) |
|
||||
({17{inst_so[`SWPB]}} & alu_swpb) |
|
||||
({17{inst_so[`SXT]}} & alu_sxt) |
|
||||
({17{alu_short_thro}} & op_src_in);
|
||||
|
||||
|
||||
// ALU output mux
|
||||
wire [16:0] alu_out_nxt = (inst_so[`IRQ] | dbg_halt_st |
|
||||
inst_alu[`ALU_ADD]) ? alu_add_inc :
|
||||
inst_alu[`ALU_DADD] ? alu_dadd : alu_short;
|
||||
|
||||
assign alu_out = alu_out_nxt[15:0];
|
||||
assign alu_out_add = alu_add[15:0];
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// STATUS FLAG GENERATION
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
wire V_xor = inst_bw ? (op_src_in[7] & op_dst_in[7]) :
|
||||
(op_src_in[15] & op_dst_in[15]);
|
||||
|
||||
wire V = inst_bw ? ((~op_src_in[7] & ~op_dst_in[7] & alu_out[7]) |
|
||||
( op_src_in[7] & op_dst_in[7] & ~alu_out[7])) :
|
||||
((~op_src_in[15] & ~op_dst_in[15] & alu_out[15]) |
|
||||
( op_src_in[15] & op_dst_in[15] & ~alu_out[15]));
|
||||
|
||||
wire N = inst_bw ? alu_out[7] : alu_out[15];
|
||||
wire Z = inst_bw ? (alu_out[7:0]==0) : (alu_out==0);
|
||||
wire C = inst_bw ? alu_out[8] : alu_out_nxt[16];
|
||||
|
||||
assign alu_stat = inst_alu[`ALU_SHIFT] ? {1'b0, N,Z,op_src_in[0]} :
|
||||
inst_alu[`ALU_STAT_7] ? {1'b0, N,Z,~Z} :
|
||||
inst_alu[`ALU_XOR] ? {V_xor,N,Z,~Z} : {V,N,Z,C};
|
||||
|
||||
assign alu_stat_wr = (inst_alu[`ALU_STAT_F] & exec_cycle) ? 4'b1111 : 4'b0000;
|
||||
|
||||
|
||||
endmodule // omsp_alu
|
||||
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_undefines.v"
|
||||
`endif
|
|
@ -1,89 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_and_gate.v
|
||||
//
|
||||
// *Module Description:
|
||||
// Generic AND gate cell for the openMSP430
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 103 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
module omsp_and_gate (
|
||||
|
||||
// OUTPUTs
|
||||
y, // AND gate output
|
||||
|
||||
// INPUTs
|
||||
a, // AND gate input A
|
||||
b // AND gate input B
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output y; // AND gate output
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input a; // AND gate input A
|
||||
input b; // AND gate input B
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) SOME COMMENTS ON THIS MODULE
|
||||
//=============================================================================
|
||||
//
|
||||
// In its ASIC version, some combinatorial pathes of the openMSP430 are
|
||||
// sensitive to glitches, in particular the ones generating the wakeup
|
||||
// signals.
|
||||
// To prevent synthesis from optmizing combinatorial clouds into glitchy
|
||||
// logic, this AND gate module has been instanciated in the critical places.
|
||||
//
|
||||
// Make sure that synthesis doesn't ungroup this module. As an alternative,
|
||||
// a standard cell from the library could also be directly instanciated here
|
||||
// (don't forget the "dont_touch" attribute)
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
// 2) AND GATE
|
||||
//=============================================================================
|
||||
|
||||
assign y = a & b;
|
||||
|
||||
|
||||
endmodule // omsp_and_gate
|
||||
|
||||
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_clock_gate.v
|
||||
//
|
||||
// *Module Description:
|
||||
// Generic clock gate cell for the openMSP430
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 103 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
module omsp_clock_gate (
|
||||
|
||||
// OUTPUTs
|
||||
gclk, // Gated clock
|
||||
|
||||
// INPUTs
|
||||
clk, // Clock
|
||||
enable, // Clock enable
|
||||
scan_enable // Scan enable (active during scan shifting)
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output gclk; // Gated clock
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input clk; // Clock
|
||||
input enable; // Clock enable
|
||||
input scan_enable; // Scan enable (active during scan shifting)
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// CLOCK GATE: LATCH + AND
|
||||
//=============================================================================
|
||||
|
||||
// Enable clock gate during scan shift
|
||||
// (the gate itself is checked with the scan capture cycle)
|
||||
wire enable_in = (enable | scan_enable);
|
||||
|
||||
// LATCH the enable signal
|
||||
reg enable_latch;
|
||||
always @(clk or enable_in)
|
||||
if (~clk)
|
||||
enable_latch <= enable_in;
|
||||
|
||||
// AND gate
|
||||
assign gclk = (clk & enable_latch);
|
||||
|
||||
|
||||
endmodule // omsp_clock_gate
|
||||
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,192 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_clock_mux.v
|
||||
//
|
||||
// *Module Description:
|
||||
// Standard clock mux for the openMSP430
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 103 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
module omsp_clock_mux (
|
||||
|
||||
// OUTPUTs
|
||||
clk_out, // Clock output
|
||||
|
||||
// INPUTs
|
||||
clk_in0, // Clock input 0
|
||||
clk_in1, // Clock input 1
|
||||
reset, // Reset
|
||||
scan_mode, // Scan mode (clk_in0 is selected in scan mode)
|
||||
select // Clock selection
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output clk_out; // Clock output
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input clk_in0; // Clock input 0
|
||||
input clk_in1; // Clock input 1
|
||||
input reset; // Reset
|
||||
input scan_mode; // Scan mode (clk_in0 is selected in scan mode)
|
||||
input select; // Clock selection
|
||||
|
||||
|
||||
//===========================================================================================================================//
|
||||
// 1) CLOCK MUX //
|
||||
//===========================================================================================================================//
|
||||
// //
|
||||
// The following (glitch free) clock mux is implemented as following: //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
// +-----. +--------+ +--------+ //
|
||||
// select >>----+-------------O| \ | | | | +-----. //
|
||||
// | | |---| D Q |---| D Q |--+-------| \ //
|
||||
// | +-------O| / | | | | | | |O-+ //
|
||||
// | | +-----' | | | | | +--O| / | //
|
||||
// | | | /\ | | /\ | | | +-----' | //
|
||||
// | | +--+--+--+ +--+--+--+ | | | //
|
||||
// | | O | | | | //
|
||||
// | | | | | | | +-----. //
|
||||
// clk_in0 >>----------------------------------+------------+-----------+ +--| \ //
|
||||
// | | | | |----<< clk_out //
|
||||
// | | +---------------------------------------+ +--| / //
|
||||
// | | | | +-----' //
|
||||
// | +---------------------------------------------+ | //
|
||||
// | | | | //
|
||||
// | | +-----. +--------+ +--------+ | | //
|
||||
// | +-O| \ | | | | | +-----. | //
|
||||
// | | |---| D Q |---| D Q |--+-------| \ | //
|
||||
// +--------------| / | | | | | |O-+ //
|
||||
// +-----' | | | | +--O| / //
|
||||
// | /\ | | /\ | | +-----' //
|
||||
// +--+--+--+ +--+--+--+ | //
|
||||
// O | | //
|
||||
// | | | //
|
||||
// clk_in1 >>----------------------------------+------------+-----------+ //
|
||||
// //
|
||||
// //
|
||||
//===========================================================================================================================//
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Wire declarations
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
wire in0_select;
|
||||
reg in0_select_s;
|
||||
reg in0_select_ss;
|
||||
wire in0_enable;
|
||||
|
||||
wire in1_select;
|
||||
reg in1_select_s;
|
||||
reg in1_select_ss;
|
||||
wire in1_enable;
|
||||
|
||||
wire clk_in0_inv;
|
||||
wire clk_in1_inv;
|
||||
wire gated_clk_in0;
|
||||
wire gated_clk_in1;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CLK_IN0 Selection
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
assign in0_select = ~select & ~in1_select_ss;
|
||||
|
||||
always @ (posedge clk_in0_inv or posedge reset)
|
||||
if (reset) in0_select_s <= 1'b1;
|
||||
else in0_select_s <= in0_select;
|
||||
|
||||
always @ (posedge clk_in0 or posedge reset)
|
||||
if (reset) in0_select_ss <= 1'b1;
|
||||
else in0_select_ss <= in0_select_s;
|
||||
|
||||
assign in0_enable = in0_select_ss | scan_mode;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// CLK_IN1 Selection
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
assign in1_select = select & ~in0_select_ss;
|
||||
|
||||
always @ (posedge clk_in1_inv or posedge reset)
|
||||
if (reset) in1_select_s <= 1'b0;
|
||||
else in1_select_s <= in1_select;
|
||||
|
||||
always @ (posedge clk_in1 or posedge reset)
|
||||
if (reset) in1_select_ss <= 1'b0;
|
||||
else in1_select_ss <= in1_select_s;
|
||||
|
||||
assign in1_enable = in1_select_ss & ~scan_mode;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Clock MUX
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// IMPORTANT NOTE:
|
||||
// Because the clock network is a critical part of the design,
|
||||
// the following combinatorial logic should be replaced with
|
||||
// direct instanciation of standard cells from target library.
|
||||
// Don't forget the "dont_touch" attribute to make sure
|
||||
// synthesis won't mess it up.
|
||||
//
|
||||
|
||||
// Replace with standard cell INVERTER
|
||||
assign clk_in0_inv = ~clk_in0;
|
||||
assign clk_in1_inv = ~clk_in1;
|
||||
|
||||
|
||||
// Replace with standard cell NAND2
|
||||
assign gated_clk_in0 = ~(clk_in0_inv & in0_enable);
|
||||
assign gated_clk_in1 = ~(clk_in1_inv & in1_enable);
|
||||
|
||||
|
||||
// Replace with standard cell AND2
|
||||
assign clk_out = (gated_clk_in0 & gated_clk_in1);
|
||||
|
||||
|
||||
|
||||
endmodule // omsp_clock_gate
|
||||
|
||||
|
||||
|
|
@ -1,827 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_dbg.v
|
||||
//
|
||||
// *Module Description:
|
||||
// Debug interface
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 149 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2012-07-19 22:21:12 +0200 (Thu, 19 Jul 2012) $
|
||||
//----------------------------------------------------------------------------
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_defines.v"
|
||||
`endif
|
||||
|
||||
module omsp_dbg (
|
||||
|
||||
// OUTPUTs
|
||||
dbg_freeze, // Freeze peripherals
|
||||
dbg_halt_cmd, // Halt CPU command
|
||||
dbg_mem_addr, // Debug address for rd/wr access
|
||||
dbg_mem_dout, // Debug unit data output
|
||||
dbg_mem_en, // Debug unit memory enable
|
||||
dbg_mem_wr, // Debug unit memory write
|
||||
dbg_reg_wr, // Debug unit CPU register write
|
||||
dbg_cpu_reset, // Reset CPU from debug interface
|
||||
dbg_uart_txd, // Debug interface: UART TXD
|
||||
|
||||
// INPUTs
|
||||
cpu_en_s, // Enable CPU code execution (synchronous)
|
||||
cpu_id, // CPU ID
|
||||
dbg_clk, // Debug unit clock
|
||||
dbg_en_s, // Debug interface enable (synchronous)
|
||||
dbg_halt_st, // Halt/Run status from CPU
|
||||
dbg_mem_din, // Debug unit Memory data input
|
||||
dbg_reg_din, // Debug unit CPU register data input
|
||||
dbg_rst, // Debug unit reset
|
||||
dbg_uart_rxd, // Debug interface: UART RXD (asynchronous)
|
||||
decode_noirq, // Frontend decode instruction
|
||||
eu_mab, // Execution-Unit Memory address bus
|
||||
eu_mb_en, // Execution-Unit Memory bus enable
|
||||
eu_mb_wr, // Execution-Unit Memory bus write transfer
|
||||
eu_mdb_in, // Memory data bus input
|
||||
eu_mdb_out, // Memory data bus output
|
||||
exec_done, // Execution completed
|
||||
fe_mb_en, // Frontend Memory bus enable
|
||||
fe_mdb_in, // Frontend Memory data bus input
|
||||
pc, // Program counter
|
||||
puc_pnd_set // PUC pending set for the serial debug interface
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output dbg_freeze; // Freeze peripherals
|
||||
output dbg_halt_cmd; // Halt CPU command
|
||||
output [15:0] dbg_mem_addr; // Debug address for rd/wr access
|
||||
output [15:0] dbg_mem_dout; // Debug unit data output
|
||||
output dbg_mem_en; // Debug unit memory enable
|
||||
output [1:0] dbg_mem_wr; // Debug unit memory write
|
||||
output dbg_reg_wr; // Debug unit CPU register write
|
||||
output dbg_cpu_reset; // Reset CPU from debug interface
|
||||
output dbg_uart_txd; // Debug interface: UART TXD
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input cpu_en_s; // Enable CPU code execution (synchronous)
|
||||
input [31:0] cpu_id; // CPU ID
|
||||
input dbg_clk; // Debug unit clock
|
||||
input dbg_en_s; // Debug interface enable (synchronous)
|
||||
input dbg_halt_st; // Halt/Run status from CPU
|
||||
input [15:0] dbg_mem_din; // Debug unit Memory data input
|
||||
input [15:0] dbg_reg_din; // Debug unit CPU register data input
|
||||
input dbg_rst; // Debug unit reset
|
||||
input dbg_uart_rxd; // Debug interface: UART RXD (asynchronous)
|
||||
input decode_noirq; // Frontend decode instruction
|
||||
input [15:0] eu_mab; // Execution-Unit Memory address bus
|
||||
input eu_mb_en; // Execution-Unit Memory bus enable
|
||||
input [1:0] eu_mb_wr; // Execution-Unit Memory bus write transfer
|
||||
input [15:0] eu_mdb_in; // Memory data bus input
|
||||
input [15:0] eu_mdb_out; // Memory data bus output
|
||||
input exec_done; // Execution completed
|
||||
input fe_mb_en; // Frontend Memory bus enable
|
||||
input [15:0] fe_mdb_in; // Frontend Memory data bus input
|
||||
input [15:0] pc; // Program counter
|
||||
input puc_pnd_set; // PUC pending set for the serial debug interface
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) WIRE & PARAMETER DECLARATION
|
||||
//=============================================================================
|
||||
|
||||
// Diverse wires and registers
|
||||
wire [5:0] dbg_addr;
|
||||
wire [15:0] dbg_din;
|
||||
wire dbg_wr;
|
||||
reg mem_burst;
|
||||
wire dbg_reg_rd;
|
||||
wire dbg_mem_rd;
|
||||
reg dbg_mem_rd_dly;
|
||||
wire dbg_swbrk;
|
||||
wire dbg_rd;
|
||||
reg dbg_rd_rdy;
|
||||
wire mem_burst_rd;
|
||||
wire mem_burst_wr;
|
||||
wire brk0_halt;
|
||||
wire brk0_pnd;
|
||||
wire [15:0] brk0_dout;
|
||||
wire brk1_halt;
|
||||
wire brk1_pnd;
|
||||
wire [15:0] brk1_dout;
|
||||
wire brk2_halt;
|
||||
wire brk2_pnd;
|
||||
wire [15:0] brk2_dout;
|
||||
wire brk3_halt;
|
||||
wire brk3_pnd;
|
||||
wire [15:0] brk3_dout;
|
||||
|
||||
// Number of registers
|
||||
parameter NR_REG = 24;
|
||||
|
||||
// Register addresses
|
||||
parameter CPU_ID_LO = 6'h00;
|
||||
parameter CPU_ID_HI = 6'h01;
|
||||
parameter CPU_CTL = 6'h02;
|
||||
parameter CPU_STAT = 6'h03;
|
||||
parameter MEM_CTL = 6'h04;
|
||||
parameter MEM_ADDR = 6'h05;
|
||||
parameter MEM_DATA = 6'h06;
|
||||
parameter MEM_CNT = 6'h07;
|
||||
`ifdef DBG_HWBRK_0
|
||||
parameter BRK0_CTL = 6'h08;
|
||||
parameter BRK0_STAT = 6'h09;
|
||||
parameter BRK0_ADDR0 = 6'h0A;
|
||||
parameter BRK0_ADDR1 = 6'h0B;
|
||||
`endif
|
||||
`ifdef DBG_HWBRK_1
|
||||
parameter BRK1_CTL = 6'h0C;
|
||||
parameter BRK1_STAT = 6'h0D;
|
||||
parameter BRK1_ADDR0 = 6'h0E;
|
||||
parameter BRK1_ADDR1 = 6'h0F;
|
||||
`endif
|
||||
`ifdef DBG_HWBRK_2
|
||||
parameter BRK2_CTL = 6'h10;
|
||||
parameter BRK2_STAT = 6'h11;
|
||||
parameter BRK2_ADDR0 = 6'h12;
|
||||
parameter BRK2_ADDR1 = 6'h13;
|
||||
`endif
|
||||
`ifdef DBG_HWBRK_3
|
||||
parameter BRK3_CTL = 6'h14;
|
||||
parameter BRK3_STAT = 6'h15;
|
||||
parameter BRK3_ADDR0 = 6'h16;
|
||||
parameter BRK3_ADDR1 = 6'h17;
|
||||
`endif
|
||||
|
||||
// Register one-hot decoder
|
||||
parameter BASE_D = {{NR_REG-1{1'b0}}, 1'b1};
|
||||
parameter CPU_ID_LO_D = (BASE_D << CPU_ID_LO);
|
||||
parameter CPU_ID_HI_D = (BASE_D << CPU_ID_HI);
|
||||
parameter CPU_CTL_D = (BASE_D << CPU_CTL);
|
||||
parameter CPU_STAT_D = (BASE_D << CPU_STAT);
|
||||
parameter MEM_CTL_D = (BASE_D << MEM_CTL);
|
||||
parameter MEM_ADDR_D = (BASE_D << MEM_ADDR);
|
||||
parameter MEM_DATA_D = (BASE_D << MEM_DATA);
|
||||
parameter MEM_CNT_D = (BASE_D << MEM_CNT);
|
||||
`ifdef DBG_HWBRK_0
|
||||
parameter BRK0_CTL_D = (BASE_D << BRK0_CTL);
|
||||
parameter BRK0_STAT_D = (BASE_D << BRK0_STAT);
|
||||
parameter BRK0_ADDR0_D = (BASE_D << BRK0_ADDR0);
|
||||
parameter BRK0_ADDR1_D = (BASE_D << BRK0_ADDR1);
|
||||
`endif
|
||||
`ifdef DBG_HWBRK_1
|
||||
parameter BRK1_CTL_D = (BASE_D << BRK1_CTL);
|
||||
parameter BRK1_STAT_D = (BASE_D << BRK1_STAT);
|
||||
parameter BRK1_ADDR0_D = (BASE_D << BRK1_ADDR0);
|
||||
parameter BRK1_ADDR1_D = (BASE_D << BRK1_ADDR1);
|
||||
`endif
|
||||
`ifdef DBG_HWBRK_2
|
||||
parameter BRK2_CTL_D = (BASE_D << BRK2_CTL);
|
||||
parameter BRK2_STAT_D = (BASE_D << BRK2_STAT);
|
||||
parameter BRK2_ADDR0_D = (BASE_D << BRK2_ADDR0);
|
||||
parameter BRK2_ADDR1_D = (BASE_D << BRK2_ADDR1);
|
||||
`endif
|
||||
`ifdef DBG_HWBRK_3
|
||||
parameter BRK3_CTL_D = (BASE_D << BRK3_CTL);
|
||||
parameter BRK3_STAT_D = (BASE_D << BRK3_STAT);
|
||||
parameter BRK3_ADDR0_D = (BASE_D << BRK3_ADDR0);
|
||||
parameter BRK3_ADDR1_D = (BASE_D << BRK3_ADDR1);
|
||||
`endif
|
||||
|
||||
|
||||
//============================================================================
|
||||
// 2) REGISTER DECODER
|
||||
//============================================================================
|
||||
|
||||
// Select Data register during a burst
|
||||
wire [5:0] dbg_addr_in = mem_burst ? MEM_DATA : dbg_addr;
|
||||
|
||||
// Register address decode
|
||||
reg [NR_REG-1:0] reg_dec;
|
||||
always @(dbg_addr_in)
|
||||
case (dbg_addr_in)
|
||||
CPU_ID_LO : reg_dec = CPU_ID_LO_D;
|
||||
CPU_ID_HI : reg_dec = CPU_ID_HI_D;
|
||||
CPU_CTL : reg_dec = CPU_CTL_D;
|
||||
CPU_STAT : reg_dec = CPU_STAT_D;
|
||||
MEM_CTL : reg_dec = MEM_CTL_D;
|
||||
MEM_ADDR : reg_dec = MEM_ADDR_D;
|
||||
MEM_DATA : reg_dec = MEM_DATA_D;
|
||||
MEM_CNT : reg_dec = MEM_CNT_D;
|
||||
`ifdef DBG_HWBRK_0
|
||||
BRK0_CTL : reg_dec = BRK0_CTL_D;
|
||||
BRK0_STAT : reg_dec = BRK0_STAT_D;
|
||||
BRK0_ADDR0: reg_dec = BRK0_ADDR0_D;
|
||||
BRK0_ADDR1: reg_dec = BRK0_ADDR1_D;
|
||||
`endif
|
||||
`ifdef DBG_HWBRK_1
|
||||
BRK1_CTL : reg_dec = BRK1_CTL_D;
|
||||
BRK1_STAT : reg_dec = BRK1_STAT_D;
|
||||
BRK1_ADDR0: reg_dec = BRK1_ADDR0_D;
|
||||
BRK1_ADDR1: reg_dec = BRK1_ADDR1_D;
|
||||
`endif
|
||||
`ifdef DBG_HWBRK_2
|
||||
BRK2_CTL : reg_dec = BRK2_CTL_D;
|
||||
BRK2_STAT : reg_dec = BRK2_STAT_D;
|
||||
BRK2_ADDR0: reg_dec = BRK2_ADDR0_D;
|
||||
BRK2_ADDR1: reg_dec = BRK2_ADDR1_D;
|
||||
`endif
|
||||
`ifdef DBG_HWBRK_3
|
||||
BRK3_CTL : reg_dec = BRK3_CTL_D;
|
||||
BRK3_STAT : reg_dec = BRK3_STAT_D;
|
||||
BRK3_ADDR0: reg_dec = BRK3_ADDR0_D;
|
||||
BRK3_ADDR1: reg_dec = BRK3_ADDR1_D;
|
||||
`endif
|
||||
// pragma coverage off
|
||||
default: reg_dec = {NR_REG{1'b0}};
|
||||
// pragma coverage on
|
||||
endcase
|
||||
|
||||
// Read/Write probes
|
||||
wire reg_write = dbg_wr;
|
||||
wire reg_read = 1'b1;
|
||||
|
||||
// Read/Write vectors
|
||||
wire [NR_REG-1:0] reg_wr = reg_dec & {NR_REG{reg_write}};
|
||||
wire [NR_REG-1:0] reg_rd = reg_dec & {NR_REG{reg_read}};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 3) REGISTER: CORE INTERFACE
|
||||
//=============================================================================
|
||||
|
||||
// CPU_ID Register
|
||||
//-----------------
|
||||
// -------------------------------------------------------------------
|
||||
// CPU_ID_LO: | 15 14 13 12 11 10 9 | 8 7 6 5 4 | 3 | 2 1 0 |
|
||||
// |----------------------------+-----------------+------+-------------|
|
||||
// | PER_SPACE | USER_VERSION | ASIC | CPU_VERSION |
|
||||
// --------------------------------------------------------------------
|
||||
// CPU_ID_HI: | 15 14 13 12 11 10 | 9 8 7 6 5 4 3 2 1 | 0 |
|
||||
// |----------------------------+-------------------------------+------|
|
||||
// | PMEM_SIZE | DMEM_SIZE | MPY |
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// This register is assigned in the SFR module
|
||||
|
||||
|
||||
// CPU_CTL Register
|
||||
//-----------------------------------------------------------------------------
|
||||
// 7 6 5 4 3 2 1 0
|
||||
// Reserved CPU_RST RST_BRK_EN FRZ_BRK_EN SW_BRK_EN ISTEP RUN HALT
|
||||
//-----------------------------------------------------------------------------
|
||||
reg [6:3] cpu_ctl;
|
||||
|
||||
wire cpu_ctl_wr = reg_wr[CPU_CTL];
|
||||
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
`ifdef DBG_RST_BRK_EN
|
||||
if (dbg_rst) cpu_ctl <= 4'h6;
|
||||
`else
|
||||
if (dbg_rst) cpu_ctl <= 4'h2;
|
||||
`endif
|
||||
else if (cpu_ctl_wr) cpu_ctl <= dbg_din[6:3];
|
||||
|
||||
wire [7:0] cpu_ctl_full = {1'b0, cpu_ctl, 3'b000};
|
||||
|
||||
wire halt_cpu = cpu_ctl_wr & dbg_din[`HALT] & ~dbg_halt_st;
|
||||
wire run_cpu = cpu_ctl_wr & dbg_din[`RUN] & dbg_halt_st;
|
||||
wire istep = cpu_ctl_wr & dbg_din[`ISTEP] & dbg_halt_st;
|
||||
|
||||
|
||||
// CPU_STAT Register
|
||||
//------------------------------------------------------------------------------------
|
||||
// 7 6 5 4 3 2 1 0
|
||||
// HWBRK3_PND HWBRK2_PND HWBRK1_PND HWBRK0_PND SWBRK_PND PUC_PND Res. HALT_RUN
|
||||
//------------------------------------------------------------------------------------
|
||||
reg [3:2] cpu_stat;
|
||||
|
||||
wire cpu_stat_wr = reg_wr[CPU_STAT];
|
||||
wire [3:2] cpu_stat_set = {dbg_swbrk, puc_pnd_set};
|
||||
wire [3:2] cpu_stat_clr = ~dbg_din[3:2];
|
||||
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) cpu_stat <= 2'b00;
|
||||
else if (cpu_stat_wr) cpu_stat <= ((cpu_stat & cpu_stat_clr) | cpu_stat_set);
|
||||
else cpu_stat <= (cpu_stat | cpu_stat_set);
|
||||
|
||||
wire [7:0] cpu_stat_full = {brk3_pnd, brk2_pnd, brk1_pnd, brk0_pnd,
|
||||
cpu_stat, 1'b0, dbg_halt_st};
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 4) REGISTER: MEMORY INTERFACE
|
||||
//=============================================================================
|
||||
|
||||
// MEM_CTL Register
|
||||
//-----------------------------------------------------------------------------
|
||||
// 7 6 5 4 3 2 1 0
|
||||
// Reserved B/W MEM/REG RD/WR START
|
||||
//
|
||||
// START : - 0 : Do nothing.
|
||||
// - 1 : Initiate memory transfer.
|
||||
//
|
||||
// RD/WR : - 0 : Read access.
|
||||
// - 1 : Write access.
|
||||
//
|
||||
// MEM/REG: - 0 : Memory access.
|
||||
// - 1 : CPU Register access.
|
||||
//
|
||||
// B/W : - 0 : 16 bit access.
|
||||
// - 1 : 8 bit access (not valid for CPU Registers).
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
reg [3:1] mem_ctl;
|
||||
|
||||
wire mem_ctl_wr = reg_wr[MEM_CTL];
|
||||
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) mem_ctl <= 3'h0;
|
||||
else if (mem_ctl_wr) mem_ctl <= dbg_din[3:1];
|
||||
|
||||
wire [7:0] mem_ctl_full = {4'b0000, mem_ctl, 1'b0};
|
||||
|
||||
reg mem_start;
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) mem_start <= 1'b0;
|
||||
else mem_start <= mem_ctl_wr & dbg_din[0];
|
||||
|
||||
wire mem_bw = mem_ctl[3];
|
||||
|
||||
// MEM_DATA Register
|
||||
//------------------
|
||||
reg [15:0] mem_data;
|
||||
reg [15:0] mem_addr;
|
||||
wire mem_access;
|
||||
|
||||
wire mem_data_wr = reg_wr[MEM_DATA];
|
||||
|
||||
wire [15:0] dbg_mem_din_bw = ~mem_bw ? dbg_mem_din :
|
||||
mem_addr[0] ? {8'h00, dbg_mem_din[15:8]} :
|
||||
{8'h00, dbg_mem_din[7:0]};
|
||||
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) mem_data <= 16'h0000;
|
||||
else if (mem_data_wr) mem_data <= dbg_din;
|
||||
else if (dbg_reg_rd) mem_data <= dbg_reg_din;
|
||||
else if (dbg_mem_rd_dly) mem_data <= dbg_mem_din_bw;
|
||||
|
||||
|
||||
// MEM_ADDR Register
|
||||
//------------------
|
||||
reg [15:0] mem_cnt;
|
||||
|
||||
wire mem_addr_wr = reg_wr[MEM_ADDR];
|
||||
wire dbg_mem_acc = (|dbg_mem_wr | (dbg_rd_rdy & ~mem_ctl[2]));
|
||||
wire dbg_reg_acc = ( dbg_reg_wr | (dbg_rd_rdy & mem_ctl[2]));
|
||||
|
||||
wire [15:0] mem_addr_inc = (mem_cnt==16'h0000) ? 16'h0000 :
|
||||
(dbg_mem_acc & ~mem_bw) ? 16'h0002 :
|
||||
(dbg_mem_acc | dbg_reg_acc) ? 16'h0001 : 16'h0000;
|
||||
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) mem_addr <= 16'h0000;
|
||||
else if (mem_addr_wr) mem_addr <= dbg_din;
|
||||
else mem_addr <= mem_addr + mem_addr_inc;
|
||||
|
||||
// MEM_CNT Register
|
||||
//------------------
|
||||
|
||||
wire mem_cnt_wr = reg_wr[MEM_CNT];
|
||||
|
||||
wire [15:0] mem_cnt_dec = (mem_cnt==16'h0000) ? 16'h0000 :
|
||||
(mem_burst & (dbg_mem_acc | dbg_reg_acc)) ? 16'hffff : 16'h0000;
|
||||
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) mem_cnt <= 16'h0000;
|
||||
else if (mem_cnt_wr) mem_cnt <= dbg_din;
|
||||
else mem_cnt <= mem_cnt + mem_cnt_dec;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 5) BREAKPOINTS / WATCHPOINTS
|
||||
//=============================================================================
|
||||
|
||||
`ifdef DBG_HWBRK_0
|
||||
// Hardware Breakpoint/Watchpoint Register read select
|
||||
wire [3:0] brk0_reg_rd = {reg_rd[BRK0_ADDR1],
|
||||
reg_rd[BRK0_ADDR0],
|
||||
reg_rd[BRK0_STAT],
|
||||
reg_rd[BRK0_CTL]};
|
||||
|
||||
// Hardware Breakpoint/Watchpoint Register write select
|
||||
wire [3:0] brk0_reg_wr = {reg_wr[BRK0_ADDR1],
|
||||
reg_wr[BRK0_ADDR0],
|
||||
reg_wr[BRK0_STAT],
|
||||
reg_wr[BRK0_CTL]};
|
||||
|
||||
omsp_dbg_hwbrk dbg_hwbr_0 (
|
||||
|
||||
// OUTPUTs
|
||||
.brk_halt (brk0_halt), // Hardware breakpoint command
|
||||
.brk_pnd (brk0_pnd), // Hardware break/watch-point pending
|
||||
.brk_dout (brk0_dout), // Hardware break/watch-point register data input
|
||||
|
||||
// INPUTs
|
||||
.brk_reg_rd (brk0_reg_rd), // Hardware break/watch-point register read select
|
||||
.brk_reg_wr (brk0_reg_wr), // Hardware break/watch-point register write select
|
||||
.dbg_clk (dbg_clk), // Debug unit clock
|
||||
.dbg_din (dbg_din), // Debug register data input
|
||||
.dbg_rst (dbg_rst), // Debug unit reset
|
||||
.eu_mab (eu_mab), // Execution-Unit Memory address bus
|
||||
.eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
|
||||
.eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
|
||||
.eu_mdb_in (eu_mdb_in), // Memory data bus input
|
||||
.eu_mdb_out (eu_mdb_out), // Memory data bus output
|
||||
.exec_done (exec_done), // Execution completed
|
||||
.fe_mb_en (fe_mb_en), // Frontend Memory bus enable
|
||||
.pc (pc) // Program counter
|
||||
);
|
||||
|
||||
`else
|
||||
assign brk0_halt = 1'b0;
|
||||
assign brk0_pnd = 1'b0;
|
||||
assign brk0_dout = 16'h0000;
|
||||
`endif
|
||||
|
||||
`ifdef DBG_HWBRK_1
|
||||
// Hardware Breakpoint/Watchpoint Register read select
|
||||
wire [3:0] brk1_reg_rd = {reg_rd[BRK1_ADDR1],
|
||||
reg_rd[BRK1_ADDR0],
|
||||
reg_rd[BRK1_STAT],
|
||||
reg_rd[BRK1_CTL]};
|
||||
|
||||
// Hardware Breakpoint/Watchpoint Register write select
|
||||
wire [3:0] brk1_reg_wr = {reg_wr[BRK1_ADDR1],
|
||||
reg_wr[BRK1_ADDR0],
|
||||
reg_wr[BRK1_STAT],
|
||||
reg_wr[BRK1_CTL]};
|
||||
|
||||
omsp_dbg_hwbrk dbg_hwbr_1 (
|
||||
|
||||
// OUTPUTs
|
||||
.brk_halt (brk1_halt), // Hardware breakpoint command
|
||||
.brk_pnd (brk1_pnd), // Hardware break/watch-point pending
|
||||
.brk_dout (brk1_dout), // Hardware break/watch-point register data input
|
||||
|
||||
// INPUTs
|
||||
.brk_reg_rd (brk1_reg_rd), // Hardware break/watch-point register read select
|
||||
.brk_reg_wr (brk1_reg_wr), // Hardware break/watch-point register write select
|
||||
.dbg_clk (dbg_clk), // Debug unit clock
|
||||
.dbg_din (dbg_din), // Debug register data input
|
||||
.dbg_rst (dbg_rst), // Debug unit reset
|
||||
.eu_mab (eu_mab), // Execution-Unit Memory address bus
|
||||
.eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
|
||||
.eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
|
||||
.eu_mdb_in (eu_mdb_in), // Memory data bus input
|
||||
.eu_mdb_out (eu_mdb_out), // Memory data bus output
|
||||
.exec_done (exec_done), // Execution completed
|
||||
.fe_mb_en (fe_mb_en), // Frontend Memory bus enable
|
||||
.pc (pc) // Program counter
|
||||
);
|
||||
|
||||
`else
|
||||
assign brk1_halt = 1'b0;
|
||||
assign brk1_pnd = 1'b0;
|
||||
assign brk1_dout = 16'h0000;
|
||||
`endif
|
||||
|
||||
`ifdef DBG_HWBRK_2
|
||||
// Hardware Breakpoint/Watchpoint Register read select
|
||||
wire [3:0] brk2_reg_rd = {reg_rd[BRK2_ADDR1],
|
||||
reg_rd[BRK2_ADDR0],
|
||||
reg_rd[BRK2_STAT],
|
||||
reg_rd[BRK2_CTL]};
|
||||
|
||||
// Hardware Breakpoint/Watchpoint Register write select
|
||||
wire [3:0] brk2_reg_wr = {reg_wr[BRK2_ADDR1],
|
||||
reg_wr[BRK2_ADDR0],
|
||||
reg_wr[BRK2_STAT],
|
||||
reg_wr[BRK2_CTL]};
|
||||
|
||||
omsp_dbg_hwbrk dbg_hwbr_2 (
|
||||
|
||||
// OUTPUTs
|
||||
.brk_halt (brk2_halt), // Hardware breakpoint command
|
||||
.brk_pnd (brk2_pnd), // Hardware break/watch-point pending
|
||||
.brk_dout (brk2_dout), // Hardware break/watch-point register data input
|
||||
|
||||
// INPUTs
|
||||
.brk_reg_rd (brk2_reg_rd), // Hardware break/watch-point register read select
|
||||
.brk_reg_wr (brk2_reg_wr), // Hardware break/watch-point register write select
|
||||
.dbg_clk (dbg_clk), // Debug unit clock
|
||||
.dbg_din (dbg_din), // Debug register data input
|
||||
.dbg_rst (dbg_rst), // Debug unit reset
|
||||
.eu_mab (eu_mab), // Execution-Unit Memory address bus
|
||||
.eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
|
||||
.eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
|
||||
.eu_mdb_in (eu_mdb_in), // Memory data bus input
|
||||
.eu_mdb_out (eu_mdb_out), // Memory data bus output
|
||||
.exec_done (exec_done), // Execution completed
|
||||
.fe_mb_en (fe_mb_en), // Frontend Memory bus enable
|
||||
.pc (pc) // Program counter
|
||||
);
|
||||
|
||||
`else
|
||||
assign brk2_halt = 1'b0;
|
||||
assign brk2_pnd = 1'b0;
|
||||
assign brk2_dout = 16'h0000;
|
||||
`endif
|
||||
|
||||
`ifdef DBG_HWBRK_3
|
||||
// Hardware Breakpoint/Watchpoint Register read select
|
||||
wire [3:0] brk3_reg_rd = {reg_rd[BRK3_ADDR1],
|
||||
reg_rd[BRK3_ADDR0],
|
||||
reg_rd[BRK3_STAT],
|
||||
reg_rd[BRK3_CTL]};
|
||||
|
||||
// Hardware Breakpoint/Watchpoint Register write select
|
||||
wire [3:0] brk3_reg_wr = {reg_wr[BRK3_ADDR1],
|
||||
reg_wr[BRK3_ADDR0],
|
||||
reg_wr[BRK3_STAT],
|
||||
reg_wr[BRK3_CTL]};
|
||||
|
||||
omsp_dbg_hwbrk dbg_hwbr_3 (
|
||||
|
||||
// OUTPUTs
|
||||
.brk_halt (brk3_halt), // Hardware breakpoint command
|
||||
.brk_pnd (brk3_pnd), // Hardware break/watch-point pending
|
||||
.brk_dout (brk3_dout), // Hardware break/watch-point register data input
|
||||
|
||||
// INPUTs
|
||||
.brk_reg_rd (brk3_reg_rd), // Hardware break/watch-point register read select
|
||||
.brk_reg_wr (brk3_reg_wr), // Hardware break/watch-point register write select
|
||||
.dbg_clk (dbg_clk), // Debug unit clock
|
||||
.dbg_din (dbg_din), // Debug register data input
|
||||
.dbg_rst (dbg_rst), // Debug unit reset
|
||||
.eu_mab (eu_mab), // Execution-Unit Memory address bus
|
||||
.eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
|
||||
.eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
|
||||
.eu_mdb_in (eu_mdb_in), // Memory data bus input
|
||||
.eu_mdb_out (eu_mdb_out), // Memory data bus output
|
||||
.exec_done (exec_done), // Execution completed
|
||||
.fe_mb_en (fe_mb_en), // Frontend Memory bus enable
|
||||
.pc (pc) // Program counter
|
||||
);
|
||||
|
||||
`else
|
||||
assign brk3_halt = 1'b0;
|
||||
assign brk3_pnd = 1'b0;
|
||||
assign brk3_dout = 16'h0000;
|
||||
`endif
|
||||
|
||||
|
||||
//============================================================================
|
||||
// 6) DATA OUTPUT GENERATION
|
||||
//============================================================================
|
||||
|
||||
wire [15:0] cpu_id_lo_rd = cpu_id[15:0] & {16{reg_rd[CPU_ID_LO]}};
|
||||
wire [15:0] cpu_id_hi_rd = cpu_id[31:16] & {16{reg_rd[CPU_ID_HI]}};
|
||||
wire [15:0] cpu_ctl_rd = {8'h00, cpu_ctl_full} & {16{reg_rd[CPU_CTL]}};
|
||||
wire [15:0] cpu_stat_rd = {8'h00, cpu_stat_full} & {16{reg_rd[CPU_STAT]}};
|
||||
wire [15:0] mem_ctl_rd = {8'h00, mem_ctl_full} & {16{reg_rd[MEM_CTL]}};
|
||||
wire [15:0] mem_data_rd = mem_data & {16{reg_rd[MEM_DATA]}};
|
||||
wire [15:0] mem_addr_rd = mem_addr & {16{reg_rd[MEM_ADDR]}};
|
||||
wire [15:0] mem_cnt_rd = mem_cnt & {16{reg_rd[MEM_CNT]}};
|
||||
|
||||
wire [15:0] dbg_dout = cpu_id_lo_rd |
|
||||
cpu_id_hi_rd |
|
||||
cpu_ctl_rd |
|
||||
cpu_stat_rd |
|
||||
mem_ctl_rd |
|
||||
mem_data_rd |
|
||||
mem_addr_rd |
|
||||
mem_cnt_rd |
|
||||
brk0_dout |
|
||||
brk1_dout |
|
||||
brk2_dout |
|
||||
brk3_dout;
|
||||
|
||||
// Tell UART/JTAG interface that the data is ready to be read
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) dbg_rd_rdy <= 1'b0;
|
||||
else if (mem_burst | mem_burst_rd) dbg_rd_rdy <= (dbg_reg_rd | dbg_mem_rd_dly);
|
||||
else dbg_rd_rdy <= dbg_rd;
|
||||
|
||||
|
||||
//============================================================================
|
||||
// 7) CPU CONTROL
|
||||
//============================================================================
|
||||
|
||||
// Reset CPU
|
||||
//--------------------------
|
||||
wire dbg_cpu_reset = cpu_ctl[`CPU_RST];
|
||||
|
||||
|
||||
// Break after reset
|
||||
//--------------------------
|
||||
wire halt_rst = cpu_ctl[`RST_BRK_EN] & dbg_en_s & puc_pnd_set;
|
||||
|
||||
|
||||
// Freeze peripherals
|
||||
//--------------------------
|
||||
wire dbg_freeze = dbg_halt_st & (cpu_ctl[`FRZ_BRK_EN] | ~cpu_en_s);
|
||||
|
||||
|
||||
// Software break
|
||||
//--------------------------
|
||||
assign dbg_swbrk = (fe_mdb_in==`DBG_SWBRK_OP) & decode_noirq & cpu_ctl[`SW_BRK_EN];
|
||||
|
||||
|
||||
// Single step
|
||||
//--------------------------
|
||||
reg [1:0] inc_step;
|
||||
always @(posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) inc_step <= 2'b00;
|
||||
else if (istep) inc_step <= 2'b11;
|
||||
else inc_step <= {inc_step[0], 1'b0};
|
||||
|
||||
|
||||
// Run / Halt
|
||||
//--------------------------
|
||||
reg halt_flag;
|
||||
|
||||
wire mem_halt_cpu;
|
||||
wire mem_run_cpu;
|
||||
|
||||
wire halt_flag_clr = run_cpu | mem_run_cpu;
|
||||
wire halt_flag_set = halt_cpu | halt_rst | dbg_swbrk | mem_halt_cpu |
|
||||
brk0_halt | brk1_halt | brk2_halt | brk3_halt;
|
||||
|
||||
always @(posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) halt_flag <= 1'b0;
|
||||
else if (halt_flag_clr) halt_flag <= 1'b0;
|
||||
else if (halt_flag_set) halt_flag <= 1'b1;
|
||||
|
||||
wire dbg_halt_cmd = (halt_flag | halt_flag_set) & ~inc_step[1];
|
||||
|
||||
|
||||
//============================================================================
|
||||
// 8) MEMORY CONTROL
|
||||
//============================================================================
|
||||
|
||||
// Control Memory bursts
|
||||
//------------------------------
|
||||
|
||||
wire mem_burst_start = (mem_start & |mem_cnt);
|
||||
wire mem_burst_end = ((dbg_wr | dbg_rd_rdy) & ~|mem_cnt);
|
||||
|
||||
// Detect when burst is on going
|
||||
always @(posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) mem_burst <= 1'b0;
|
||||
else if (mem_burst_start) mem_burst <= 1'b1;
|
||||
else if (mem_burst_end) mem_burst <= 1'b0;
|
||||
|
||||
// Control signals for UART/JTAG interface
|
||||
assign mem_burst_rd = (mem_burst_start & ~mem_ctl[1]);
|
||||
assign mem_burst_wr = (mem_burst_start & mem_ctl[1]);
|
||||
|
||||
// Trigger CPU Register or memory access during a burst
|
||||
reg mem_startb;
|
||||
always @(posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) mem_startb <= 1'b0;
|
||||
else mem_startb <= (mem_burst & (dbg_wr | dbg_rd)) | mem_burst_rd;
|
||||
|
||||
// Combine single and burst memory start of sequence
|
||||
wire mem_seq_start = ((mem_start & ~|mem_cnt) | mem_startb);
|
||||
|
||||
|
||||
// Memory access state machine
|
||||
//------------------------------
|
||||
reg [1:0] mem_state;
|
||||
reg [1:0] mem_state_nxt;
|
||||
|
||||
// State machine definition
|
||||
parameter M_IDLE = 2'h0;
|
||||
parameter M_SET_BRK = 2'h1;
|
||||
parameter M_ACCESS_BRK = 2'h2;
|
||||
parameter M_ACCESS = 2'h3;
|
||||
|
||||
// State transition
|
||||
always @(mem_state or mem_seq_start or dbg_halt_st)
|
||||
case (mem_state)
|
||||
M_IDLE : mem_state_nxt = ~mem_seq_start ? M_IDLE :
|
||||
dbg_halt_st ? M_ACCESS : M_SET_BRK;
|
||||
M_SET_BRK : mem_state_nxt = dbg_halt_st ? M_ACCESS_BRK : M_SET_BRK;
|
||||
M_ACCESS_BRK : mem_state_nxt = M_IDLE;
|
||||
M_ACCESS : mem_state_nxt = M_IDLE;
|
||||
// pragma coverage off
|
||||
default : mem_state_nxt = M_IDLE;
|
||||
// pragma coverage on
|
||||
endcase
|
||||
|
||||
// State machine
|
||||
always @(posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) mem_state <= M_IDLE;
|
||||
else mem_state <= mem_state_nxt;
|
||||
|
||||
// Utility signals
|
||||
assign mem_halt_cpu = (mem_state==M_IDLE) & (mem_state_nxt==M_SET_BRK);
|
||||
assign mem_run_cpu = (mem_state==M_ACCESS_BRK) & (mem_state_nxt==M_IDLE);
|
||||
assign mem_access = (mem_state==M_ACCESS) | (mem_state==M_ACCESS_BRK);
|
||||
|
||||
|
||||
// Interface to CPU Registers and Memory bacbkone
|
||||
//------------------------------------------------
|
||||
assign dbg_mem_addr = mem_addr;
|
||||
assign dbg_mem_dout = ~mem_bw ? mem_data :
|
||||
mem_addr[0] ? {mem_data[7:0], 8'h00} :
|
||||
{8'h00, mem_data[7:0]};
|
||||
|
||||
assign dbg_reg_wr = mem_access & mem_ctl[1] & mem_ctl[2];
|
||||
assign dbg_reg_rd = mem_access & ~mem_ctl[1] & mem_ctl[2];
|
||||
|
||||
assign dbg_mem_en = mem_access & ~mem_ctl[2];
|
||||
assign dbg_mem_rd = dbg_mem_en & ~mem_ctl[1];
|
||||
|
||||
wire [1:0] dbg_mem_wr_msk = ~mem_bw ? 2'b11 :
|
||||
mem_addr[0] ? 2'b10 : 2'b01;
|
||||
assign dbg_mem_wr = {2{dbg_mem_en & mem_ctl[1]}} & dbg_mem_wr_msk;
|
||||
|
||||
|
||||
// It takes one additional cycle to read from Memory as from registers
|
||||
always @(posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) dbg_mem_rd_dly <= 1'b0;
|
||||
else dbg_mem_rd_dly <= dbg_mem_rd;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 9) UART COMMUNICATION
|
||||
//=============================================================================
|
||||
`ifdef DBG_UART
|
||||
omsp_dbg_uart dbg_uart_0 (
|
||||
|
||||
// OUTPUTs
|
||||
.dbg_addr (dbg_addr), // Debug register address
|
||||
.dbg_din (dbg_din), // Debug register data input
|
||||
.dbg_rd (dbg_rd), // Debug register data read
|
||||
.dbg_uart_txd (dbg_uart_txd), // Debug interface: UART TXD
|
||||
.dbg_wr (dbg_wr), // Debug register data write
|
||||
|
||||
// INPUTs
|
||||
.dbg_clk (dbg_clk), // Debug unit clock
|
||||
.dbg_dout (dbg_dout), // Debug register data output
|
||||
.dbg_rd_rdy (dbg_rd_rdy), // Debug register data is ready for read
|
||||
.dbg_rst (dbg_rst), // Debug unit reset
|
||||
.dbg_uart_rxd (dbg_uart_rxd), // Debug interface: UART RXD
|
||||
.mem_burst (mem_burst), // Burst on going
|
||||
.mem_burst_end(mem_burst_end), // End TX/RX burst
|
||||
.mem_burst_rd (mem_burst_rd), // Start TX burst
|
||||
.mem_burst_wr (mem_burst_wr), // Start RX burst
|
||||
.mem_bw (mem_bw) // Burst byte width
|
||||
);
|
||||
|
||||
`else
|
||||
assign dbg_addr = 6'h00;
|
||||
assign dbg_din = 16'h0000;
|
||||
assign dbg_rd = 1'b0;
|
||||
assign dbg_uart_txd = 1'b0;
|
||||
assign dbg_wr = 1'b0;
|
||||
`endif
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 10) JTAG COMMUNICATION
|
||||
//=============================================================================
|
||||
`ifdef DBG_JTAG
|
||||
JTAG INTERFACE IS NOT SUPPORTED YET
|
||||
`else
|
||||
`endif
|
||||
|
||||
endmodule // dbg
|
||||
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_undefines.v"
|
||||
`endif
|
|
@ -1,282 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_dbg_hwbrk.v
|
||||
//
|
||||
// *Module Description:
|
||||
// Hardware Breakpoint / Watchpoint module
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 117 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2011-06-23 21:30:51 +0200 (Thu, 23 Jun 2011) $
|
||||
//----------------------------------------------------------------------------
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_defines.v"
|
||||
`endif
|
||||
|
||||
module omsp_dbg_hwbrk (
|
||||
|
||||
// OUTPUTs
|
||||
brk_halt, // Hardware breakpoint command
|
||||
brk_pnd, // Hardware break/watch-point pending
|
||||
brk_dout, // Hardware break/watch-point register data input
|
||||
|
||||
// INPUTs
|
||||
brk_reg_rd, // Hardware break/watch-point register read select
|
||||
brk_reg_wr, // Hardware break/watch-point register write select
|
||||
dbg_clk, // Debug unit clock
|
||||
dbg_din, // Debug register data input
|
||||
dbg_rst, // Debug unit reset
|
||||
eu_mab, // Execution-Unit Memory address bus
|
||||
eu_mb_en, // Execution-Unit Memory bus enable
|
||||
eu_mb_wr, // Execution-Unit Memory bus write transfer
|
||||
eu_mdb_in, // Memory data bus input
|
||||
eu_mdb_out, // Memory data bus output
|
||||
exec_done, // Execution completed
|
||||
fe_mb_en, // Frontend Memory bus enable
|
||||
pc // Program counter
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output brk_halt; // Hardware breakpoint command
|
||||
output brk_pnd; // Hardware break/watch-point pending
|
||||
output [15:0] brk_dout; // Hardware break/watch-point register data input
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input [3:0] brk_reg_rd; // Hardware break/watch-point register read select
|
||||
input [3:0] brk_reg_wr; // Hardware break/watch-point register write select
|
||||
input dbg_clk; // Debug unit clock
|
||||
input [15:0] dbg_din; // Debug register data input
|
||||
input dbg_rst; // Debug unit reset
|
||||
input [15:0] eu_mab; // Execution-Unit Memory address bus
|
||||
input eu_mb_en; // Execution-Unit Memory bus enable
|
||||
input [1:0] eu_mb_wr; // Execution-Unit Memory bus write transfer
|
||||
input [15:0] eu_mdb_in; // Memory data bus input
|
||||
input [15:0] eu_mdb_out; // Memory data bus output
|
||||
input exec_done; // Execution completed
|
||||
input fe_mb_en; // Frontend Memory bus enable
|
||||
input [15:0] pc; // Program counter
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) WIRE & PARAMETER DECLARATION
|
||||
//=============================================================================
|
||||
|
||||
wire range_wr_set;
|
||||
wire range_rd_set;
|
||||
wire addr1_wr_set;
|
||||
wire addr1_rd_set;
|
||||
wire addr0_wr_set;
|
||||
wire addr0_rd_set;
|
||||
|
||||
|
||||
parameter BRK_CTL = 0,
|
||||
BRK_STAT = 1,
|
||||
BRK_ADDR0 = 2,
|
||||
BRK_ADDR1 = 3;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 2) CONFIGURATION REGISTERS
|
||||
//=============================================================================
|
||||
|
||||
// BRK_CTL Register
|
||||
//-----------------------------------------------------------------------------
|
||||
// 7 6 5 4 3 2 1 0
|
||||
// Reserved RANGE_MODE INST_EN BREAK_EN ACCESS_MODE
|
||||
//
|
||||
// ACCESS_MODE: - 00 : Disabled
|
||||
// - 01 : Detect read access
|
||||
// - 10 : Detect write access
|
||||
// - 11 : Detect read/write access
|
||||
// NOTE: '10' & '11' modes are not supported on the instruction flow
|
||||
//
|
||||
// BREAK_EN: - 0 : Watchmode enable
|
||||
// - 1 : Break enable
|
||||
//
|
||||
// INST_EN: - 0 : Checks are done on the execution unit (data flow)
|
||||
// - 1 : Checks are done on the frontend (instruction flow)
|
||||
//
|
||||
// RANGE_MODE: - 0 : Address match on BRK_ADDR0 or BRK_ADDR1
|
||||
// - 1 : Address match on BRK_ADDR0->BRK_ADDR1 range
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
reg [4:0] brk_ctl;
|
||||
|
||||
wire brk_ctl_wr = brk_reg_wr[BRK_CTL];
|
||||
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) brk_ctl <= 5'h00;
|
||||
else if (brk_ctl_wr) brk_ctl <= {`HWBRK_RANGE & dbg_din[4], dbg_din[3:0]};
|
||||
|
||||
wire [7:0] brk_ctl_full = {3'b000, brk_ctl};
|
||||
|
||||
|
||||
// BRK_STAT Register
|
||||
//-----------------------------------------------------------------------------
|
||||
// 7 6 5 4 3 2 1 0
|
||||
// Reserved RANGE_WR RANGE_RD ADDR1_WR ADDR1_RD ADDR0_WR ADDR0_RD
|
||||
//-----------------------------------------------------------------------------
|
||||
reg [5:0] brk_stat;
|
||||
|
||||
wire brk_stat_wr = brk_reg_wr[BRK_STAT];
|
||||
wire [5:0] brk_stat_set = {range_wr_set & `HWBRK_RANGE,
|
||||
range_rd_set & `HWBRK_RANGE,
|
||||
addr1_wr_set, addr1_rd_set,
|
||||
addr0_wr_set, addr0_rd_set};
|
||||
wire [5:0] brk_stat_clr = ~dbg_din[5:0];
|
||||
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) brk_stat <= 6'h00;
|
||||
else if (brk_stat_wr) brk_stat <= ((brk_stat & brk_stat_clr) | brk_stat_set);
|
||||
else brk_stat <= (brk_stat | brk_stat_set);
|
||||
|
||||
wire [7:0] brk_stat_full = {2'b00, brk_stat};
|
||||
wire brk_pnd = |brk_stat;
|
||||
|
||||
|
||||
// BRK_ADDR0 Register
|
||||
//-----------------------------------------------------------------------------
|
||||
reg [15:0] brk_addr0;
|
||||
|
||||
wire brk_addr0_wr = brk_reg_wr[BRK_ADDR0];
|
||||
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) brk_addr0 <= 16'h0000;
|
||||
else if (brk_addr0_wr) brk_addr0 <= dbg_din;
|
||||
|
||||
|
||||
// BRK_ADDR1/DATA0 Register
|
||||
//-----------------------------------------------------------------------------
|
||||
reg [15:0] brk_addr1;
|
||||
|
||||
wire brk_addr1_wr = brk_reg_wr[BRK_ADDR1];
|
||||
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) brk_addr1 <= 16'h0000;
|
||||
else if (brk_addr1_wr) brk_addr1 <= dbg_din;
|
||||
|
||||
|
||||
//============================================================================
|
||||
// 3) DATA OUTPUT GENERATION
|
||||
//============================================================================
|
||||
|
||||
wire [15:0] brk_ctl_rd = {8'h00, brk_ctl_full} & {16{brk_reg_rd[BRK_CTL]}};
|
||||
wire [15:0] brk_stat_rd = {8'h00, brk_stat_full} & {16{brk_reg_rd[BRK_STAT]}};
|
||||
wire [15:0] brk_addr0_rd = brk_addr0 & {16{brk_reg_rd[BRK_ADDR0]}};
|
||||
wire [15:0] brk_addr1_rd = brk_addr1 & {16{brk_reg_rd[BRK_ADDR1]}};
|
||||
|
||||
wire [15:0] brk_dout = brk_ctl_rd |
|
||||
brk_stat_rd |
|
||||
brk_addr0_rd |
|
||||
brk_addr1_rd;
|
||||
|
||||
|
||||
//============================================================================
|
||||
// 4) BREAKPOINT / WATCHPOINT GENERATION
|
||||
//============================================================================
|
||||
|
||||
// Comparators
|
||||
//---------------------------
|
||||
// Note: here the comparison logic is instanciated several times in order
|
||||
// to improve the timings, at the cost of a bit more area.
|
||||
|
||||
wire equ_d_addr0 = eu_mb_en & (eu_mab==brk_addr0) & ~brk_ctl[`BRK_RANGE];
|
||||
wire equ_d_addr1 = eu_mb_en & (eu_mab==brk_addr1) & ~brk_ctl[`BRK_RANGE];
|
||||
wire equ_d_range = eu_mb_en & ((eu_mab>=brk_addr0) & (eu_mab<=brk_addr1)) &
|
||||
brk_ctl[`BRK_RANGE] & `HWBRK_RANGE;
|
||||
|
||||
reg fe_mb_en_buf;
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) fe_mb_en_buf <= 1'b0;
|
||||
else fe_mb_en_buf <= fe_mb_en;
|
||||
|
||||
wire equ_i_addr0 = fe_mb_en_buf & (pc==brk_addr0) & ~brk_ctl[`BRK_RANGE];
|
||||
wire equ_i_addr1 = fe_mb_en_buf & (pc==brk_addr1) & ~brk_ctl[`BRK_RANGE];
|
||||
wire equ_i_range = fe_mb_en_buf & ((pc>=brk_addr0) & (pc<=brk_addr1)) &
|
||||
brk_ctl[`BRK_RANGE] & `HWBRK_RANGE;
|
||||
|
||||
|
||||
// Detect accesses
|
||||
//---------------------------
|
||||
|
||||
// Detect Instruction read access
|
||||
wire i_addr0_rd = equ_i_addr0 & brk_ctl[`BRK_I_EN];
|
||||
wire i_addr1_rd = equ_i_addr1 & brk_ctl[`BRK_I_EN];
|
||||
wire i_range_rd = equ_i_range & brk_ctl[`BRK_I_EN];
|
||||
|
||||
// Detect Execution-Unit write access
|
||||
wire d_addr0_wr = equ_d_addr0 & ~brk_ctl[`BRK_I_EN] & |eu_mb_wr;
|
||||
wire d_addr1_wr = equ_d_addr1 & ~brk_ctl[`BRK_I_EN] & |eu_mb_wr;
|
||||
wire d_range_wr = equ_d_range & ~brk_ctl[`BRK_I_EN] & |eu_mb_wr;
|
||||
|
||||
// Detect DATA read access
|
||||
// Whenever an "ADD r9. &0x200" instruction is executed, &0x200 will be read
|
||||
// before being written back. In that case, the read flag should not be set.
|
||||
// In general, We should here make sure no write access occures during the
|
||||
// same instruction cycle before setting the read flag.
|
||||
reg [2:0] d_rd_trig;
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) d_rd_trig <= 3'h0;
|
||||
else if (exec_done) d_rd_trig <= 3'h0;
|
||||
else d_rd_trig <= {equ_d_range & ~brk_ctl[`BRK_I_EN] & ~|eu_mb_wr,
|
||||
equ_d_addr1 & ~brk_ctl[`BRK_I_EN] & ~|eu_mb_wr,
|
||||
equ_d_addr0 & ~brk_ctl[`BRK_I_EN] & ~|eu_mb_wr};
|
||||
|
||||
wire d_addr0_rd = d_rd_trig[0] & exec_done & ~d_addr0_wr;
|
||||
wire d_addr1_rd = d_rd_trig[1] & exec_done & ~d_addr1_wr;
|
||||
wire d_range_rd = d_rd_trig[2] & exec_done & ~d_range_wr;
|
||||
|
||||
|
||||
// Set flags
|
||||
assign addr0_rd_set = brk_ctl[`BRK_MODE_RD] & (d_addr0_rd | i_addr0_rd);
|
||||
assign addr0_wr_set = brk_ctl[`BRK_MODE_WR] & d_addr0_wr;
|
||||
assign addr1_rd_set = brk_ctl[`BRK_MODE_RD] & (d_addr1_rd | i_addr1_rd);
|
||||
assign addr1_wr_set = brk_ctl[`BRK_MODE_WR] & d_addr1_wr;
|
||||
assign range_rd_set = brk_ctl[`BRK_MODE_RD] & (d_range_rd | i_range_rd);
|
||||
assign range_wr_set = brk_ctl[`BRK_MODE_WR] & d_range_wr;
|
||||
|
||||
|
||||
// Break CPU
|
||||
assign brk_halt = brk_ctl[`BRK_EN] & |brk_stat_set;
|
||||
|
||||
|
||||
endmodule // omsp_dbg_hwbrk
|
||||
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_undefines.v"
|
||||
`endif
|
|
@ -1,298 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_dbg_uart.v
|
||||
//
|
||||
// *Module Description:
|
||||
// Debug UART communication interface (8N1, Half-duplex)
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 134 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
|
||||
//----------------------------------------------------------------------------
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_defines.v"
|
||||
`endif
|
||||
|
||||
module omsp_dbg_uart (
|
||||
|
||||
// OUTPUTs
|
||||
dbg_addr, // Debug register address
|
||||
dbg_din, // Debug register data input
|
||||
dbg_rd, // Debug register data read
|
||||
dbg_uart_txd, // Debug interface: UART TXD
|
||||
dbg_wr, // Debug register data write
|
||||
|
||||
// INPUTs
|
||||
dbg_clk, // Debug unit clock
|
||||
dbg_dout, // Debug register data output
|
||||
dbg_rd_rdy, // Debug register data is ready for read
|
||||
dbg_rst, // Debug unit reset
|
||||
dbg_uart_rxd, // Debug interface: UART RXD
|
||||
mem_burst, // Burst on going
|
||||
mem_burst_end, // End TX/RX burst
|
||||
mem_burst_rd, // Start TX burst
|
||||
mem_burst_wr, // Start RX burst
|
||||
mem_bw // Burst byte width
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output [5:0] dbg_addr; // Debug register address
|
||||
output [15:0] dbg_din; // Debug register data input
|
||||
output dbg_rd; // Debug register data read
|
||||
output dbg_uart_txd; // Debug interface: UART TXD
|
||||
output dbg_wr; // Debug register data write
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input dbg_clk; // Debug unit clock
|
||||
input [15:0] dbg_dout; // Debug register data output
|
||||
input dbg_rd_rdy; // Debug register data is ready for read
|
||||
input dbg_rst; // Debug unit reset
|
||||
input dbg_uart_rxd; // Debug interface: UART RXD
|
||||
input mem_burst; // Burst on going
|
||||
input mem_burst_end; // End TX/RX burst
|
||||
input mem_burst_rd; // Start TX burst
|
||||
input mem_burst_wr; // Start RX burst
|
||||
input mem_bw; // Burst byte width
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) UART RECEIVE LINE SYNCHRONIZTION & FILTERING
|
||||
//=============================================================================
|
||||
|
||||
// Synchronize RXD input
|
||||
//--------------------------------
|
||||
`ifdef SYNC_DBG_UART_RXD
|
||||
|
||||
wire uart_rxd_n;
|
||||
|
||||
omsp_sync_cell sync_cell_uart_rxd (
|
||||
.data_out (uart_rxd_n),
|
||||
.data_in (~dbg_uart_rxd),
|
||||
.clk (dbg_clk),
|
||||
.rst (dbg_rst)
|
||||
);
|
||||
wire uart_rxd = ~uart_rxd_n;
|
||||
`else
|
||||
wire uart_rxd = dbg_uart_rxd;
|
||||
`endif
|
||||
|
||||
// RXD input buffer
|
||||
//--------------------------------
|
||||
reg [1:0] rxd_buf;
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) rxd_buf <= 2'h3;
|
||||
else rxd_buf <= {rxd_buf[0], uart_rxd};
|
||||
|
||||
// Majority decision
|
||||
//------------------------
|
||||
reg rxd_maj;
|
||||
|
||||
wire rxd_maj_nxt = (uart_rxd & rxd_buf[0]) |
|
||||
(uart_rxd & rxd_buf[1]) |
|
||||
(rxd_buf[0] & rxd_buf[1]);
|
||||
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) rxd_maj <= 1'b1;
|
||||
else rxd_maj <= rxd_maj_nxt;
|
||||
|
||||
wire rxd_s = rxd_maj;
|
||||
wire rxd_fe = rxd_maj & ~rxd_maj_nxt;
|
||||
wire rxd_re = ~rxd_maj & rxd_maj_nxt;
|
||||
wire rxd_edge = rxd_maj ^ rxd_maj_nxt;
|
||||
|
||||
//=============================================================================
|
||||
// 2) UART STATE MACHINE
|
||||
//=============================================================================
|
||||
|
||||
// Receive state
|
||||
//------------------------
|
||||
reg [2:0] uart_state;
|
||||
reg [2:0] uart_state_nxt;
|
||||
|
||||
wire sync_done;
|
||||
wire xfer_done;
|
||||
reg [19:0] xfer_buf;
|
||||
wire [19:0] xfer_buf_nxt;
|
||||
|
||||
// State machine definition
|
||||
parameter RX_SYNC = 3'h0;
|
||||
parameter RX_CMD = 3'h1;
|
||||
parameter RX_DATA1 = 3'h2;
|
||||
parameter RX_DATA2 = 3'h3;
|
||||
parameter TX_DATA1 = 3'h4;
|
||||
parameter TX_DATA2 = 3'h5;
|
||||
|
||||
// State transition
|
||||
always @(uart_state or xfer_buf_nxt or mem_burst or mem_burst_wr or mem_burst_rd or mem_burst_end or mem_bw)
|
||||
case (uart_state)
|
||||
RX_SYNC : uart_state_nxt = RX_CMD;
|
||||
RX_CMD : uart_state_nxt = mem_burst_wr ?
|
||||
(mem_bw ? RX_DATA2 : RX_DATA1) :
|
||||
mem_burst_rd ?
|
||||
(mem_bw ? TX_DATA2 : TX_DATA1) :
|
||||
(xfer_buf_nxt[`DBG_UART_WR] ?
|
||||
(xfer_buf_nxt[`DBG_UART_BW] ? RX_DATA2 : RX_DATA1) :
|
||||
(xfer_buf_nxt[`DBG_UART_BW] ? TX_DATA2 : TX_DATA1));
|
||||
RX_DATA1 : uart_state_nxt = RX_DATA2;
|
||||
RX_DATA2 : uart_state_nxt = (mem_burst & ~mem_burst_end) ?
|
||||
(mem_bw ? RX_DATA2 : RX_DATA1) :
|
||||
RX_CMD;
|
||||
TX_DATA1 : uart_state_nxt = TX_DATA2;
|
||||
TX_DATA2 : uart_state_nxt = (mem_burst & ~mem_burst_end) ?
|
||||
(mem_bw ? TX_DATA2 : TX_DATA1) :
|
||||
RX_CMD;
|
||||
// pragma coverage off
|
||||
default : uart_state_nxt = RX_CMD;
|
||||
// pragma coverage on
|
||||
endcase
|
||||
|
||||
// State machine
|
||||
always @(posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) uart_state <= RX_SYNC;
|
||||
else if (xfer_done | sync_done |
|
||||
mem_burst_wr | mem_burst_rd) uart_state <= uart_state_nxt;
|
||||
|
||||
// Utility signals
|
||||
wire cmd_valid = (uart_state==RX_CMD) & xfer_done;
|
||||
wire rx_active = (uart_state==RX_DATA1) | (uart_state==RX_DATA2) | (uart_state==RX_CMD);
|
||||
wire tx_active = (uart_state==TX_DATA1) | (uart_state==TX_DATA2);
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 3) UART SYNCHRONIZATION
|
||||
//=============================================================================
|
||||
// After DBG_RST, the host needs to fist send a synchronization character (0x80)
|
||||
// If this feature doesn't work properly, it is possible to disable it by
|
||||
// commenting the DBG_UART_AUTO_SYNC define in the openMSP430.inc file.
|
||||
|
||||
reg sync_busy;
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) sync_busy <= 1'b0;
|
||||
else if ((uart_state==RX_SYNC) & rxd_fe) sync_busy <= 1'b1;
|
||||
else if ((uart_state==RX_SYNC) & rxd_re) sync_busy <= 1'b0;
|
||||
|
||||
assign sync_done = (uart_state==RX_SYNC) & rxd_re & sync_busy;
|
||||
|
||||
`ifdef DBG_UART_AUTO_SYNC
|
||||
|
||||
reg [`DBG_UART_XFER_CNT_W+2:0] sync_cnt;
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) sync_cnt <= {{`DBG_UART_XFER_CNT_W{1'b1}}, 3'b000};
|
||||
else if (sync_busy | (~sync_busy & sync_cnt[2])) sync_cnt <= sync_cnt+{{`DBG_UART_XFER_CNT_W+2{1'b0}}, 1'b1};
|
||||
|
||||
wire [`DBG_UART_XFER_CNT_W-1:0] bit_cnt_max = sync_cnt[`DBG_UART_XFER_CNT_W+2:3];
|
||||
`else
|
||||
wire [`DBG_UART_XFER_CNT_W-1:0] bit_cnt_max = `DBG_UART_CNT;
|
||||
`endif
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 4) UART RECEIVE / TRANSMIT
|
||||
//=============================================================================
|
||||
|
||||
// Transfer counter
|
||||
//------------------------
|
||||
reg [3:0] xfer_bit;
|
||||
reg [`DBG_UART_XFER_CNT_W-1:0] xfer_cnt;
|
||||
|
||||
wire txd_start = dbg_rd_rdy | (xfer_done & (uart_state==TX_DATA1));
|
||||
wire rxd_start = (xfer_bit==4'h0) & rxd_fe & ((uart_state!=RX_SYNC));
|
||||
wire xfer_bit_inc = (xfer_bit!=4'h0) & (xfer_cnt=={`DBG_UART_XFER_CNT_W{1'b0}});
|
||||
assign xfer_done = rx_active ? (xfer_bit==4'ha) : (xfer_bit==4'hb);
|
||||
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) xfer_bit <= 4'h0;
|
||||
else if (txd_start | rxd_start) xfer_bit <= 4'h1;
|
||||
else if (xfer_done) xfer_bit <= 4'h0;
|
||||
else if (xfer_bit_inc) xfer_bit <= xfer_bit+4'h1;
|
||||
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) xfer_cnt <= {`DBG_UART_XFER_CNT_W{1'b0}};
|
||||
else if (rx_active & rxd_edge) xfer_cnt <= {1'b0, bit_cnt_max[`DBG_UART_XFER_CNT_W-1:1]};
|
||||
else if (txd_start | xfer_bit_inc) xfer_cnt <= bit_cnt_max;
|
||||
else if (|xfer_cnt) xfer_cnt <= xfer_cnt+{`DBG_UART_XFER_CNT_W{1'b1}};
|
||||
|
||||
|
||||
// Receive/Transmit buffer
|
||||
//-------------------------
|
||||
assign xfer_buf_nxt = {rxd_s, xfer_buf[19:1]};
|
||||
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) xfer_buf <= 20'h00000;
|
||||
else if (dbg_rd_rdy) xfer_buf <= {1'b1, dbg_dout[15:8], 2'b01, dbg_dout[7:0], 1'b0};
|
||||
else if (xfer_bit_inc) xfer_buf <= xfer_buf_nxt;
|
||||
|
||||
|
||||
// Generate TXD output
|
||||
//------------------------
|
||||
reg dbg_uart_txd;
|
||||
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) dbg_uart_txd <= 1'b1;
|
||||
else if (xfer_bit_inc & tx_active) dbg_uart_txd <= xfer_buf[0];
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 5) INTERFACE TO DEBUG REGISTERS
|
||||
//=============================================================================
|
||||
|
||||
reg [5:0] dbg_addr;
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) dbg_addr <= 6'h00;
|
||||
else if (cmd_valid) dbg_addr <= xfer_buf_nxt[`DBG_UART_ADDR];
|
||||
|
||||
reg dbg_bw;
|
||||
always @ (posedge dbg_clk or posedge dbg_rst)
|
||||
if (dbg_rst) dbg_bw <= 1'b0;
|
||||
else if (cmd_valid) dbg_bw <= xfer_buf_nxt[`DBG_UART_BW];
|
||||
|
||||
wire dbg_din_bw = mem_burst ? mem_bw : dbg_bw;
|
||||
|
||||
wire [15:0] dbg_din = dbg_din_bw ? {8'h00, xfer_buf_nxt[18:11]} :
|
||||
{xfer_buf_nxt[18:11], xfer_buf_nxt[9:2]};
|
||||
wire dbg_wr = (xfer_done & (uart_state==RX_DATA2));
|
||||
wire dbg_rd = mem_burst ? (xfer_done & (uart_state==TX_DATA2)) :
|
||||
(cmd_valid & ~xfer_buf_nxt[`DBG_UART_WR]) | mem_burst_rd;
|
||||
|
||||
|
||||
|
||||
endmodule // omsp_dbg_uart
|
||||
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_undefines.v"
|
||||
`endif
|
|
@ -1,420 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_execution_unit.v
|
||||
//
|
||||
// *Module Description:
|
||||
// openMSP430 Execution unit
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 134 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
|
||||
//----------------------------------------------------------------------------
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_defines.v"
|
||||
`endif
|
||||
|
||||
module omsp_execution_unit (
|
||||
|
||||
// OUTPUTs
|
||||
cpuoff, // Turns off the CPU
|
||||
dbg_reg_din, // Debug unit CPU register data input
|
||||
gie, // General interrupt enable
|
||||
mab, // Memory address bus
|
||||
mb_en, // Memory bus enable
|
||||
mb_wr, // Memory bus write transfer
|
||||
mdb_out, // Memory data bus output
|
||||
oscoff, // Turns off LFXT1 clock input
|
||||
pc_sw, // Program counter software value
|
||||
pc_sw_wr, // Program counter software write
|
||||
scg0, // System clock generator 1. Turns off the DCO
|
||||
scg1, // System clock generator 1. Turns off the SMCLK
|
||||
|
||||
// INPUTs
|
||||
dbg_halt_st, // Halt/Run status from CPU
|
||||
dbg_mem_dout, // Debug unit data output
|
||||
dbg_reg_wr, // Debug unit CPU register write
|
||||
e_state, // Execution state
|
||||
exec_done, // Execution completed
|
||||
inst_ad, // Decoded Inst: destination addressing mode
|
||||
inst_as, // Decoded Inst: source addressing mode
|
||||
inst_alu, // ALU control signals
|
||||
inst_bw, // Decoded Inst: byte width
|
||||
inst_dest, // Decoded Inst: destination (one hot)
|
||||
inst_dext, // Decoded Inst: destination extended instruction word
|
||||
inst_irq_rst, // Decoded Inst: reset interrupt
|
||||
inst_jmp, // Decoded Inst: Conditional jump
|
||||
inst_mov, // Decoded Inst: mov instruction
|
||||
inst_sext, // Decoded Inst: source extended instruction word
|
||||
inst_so, // Decoded Inst: Single-operand arithmetic
|
||||
inst_src, // Decoded Inst: source (one hot)
|
||||
inst_type, // Decoded Instruction type
|
||||
mclk, // Main system clock
|
||||
mdb_in, // Memory data bus input
|
||||
pc, // Program counter
|
||||
pc_nxt, // Next PC value (for CALL & IRQ)
|
||||
puc_rst, // Main system reset
|
||||
scan_enable // Scan enable (active during scan shifting)
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output cpuoff; // Turns off the CPU
|
||||
output [15:0] dbg_reg_din; // Debug unit CPU register data input
|
||||
output gie; // General interrupt enable
|
||||
output [15:0] mab; // Memory address bus
|
||||
output mb_en; // Memory bus enable
|
||||
output [1:0] mb_wr; // Memory bus write transfer
|
||||
output [15:0] mdb_out; // Memory data bus output
|
||||
output oscoff; // Turns off LFXT1 clock input
|
||||
output [15:0] pc_sw; // Program counter software value
|
||||
output pc_sw_wr; // Program counter software write
|
||||
output scg0; // System clock generator 1. Turns off the DCO
|
||||
output scg1; // System clock generator 1. Turns off the SMCLK
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input dbg_halt_st; // Halt/Run status from CPU
|
||||
input [15:0] dbg_mem_dout; // Debug unit data output
|
||||
input dbg_reg_wr; // Debug unit CPU register write
|
||||
input [3:0] e_state; // Execution state
|
||||
input exec_done; // Execution completed
|
||||
input [7:0] inst_ad; // Decoded Inst: destination addressing mode
|
||||
input [7:0] inst_as; // Decoded Inst: source addressing mode
|
||||
input [11:0] inst_alu; // ALU control signals
|
||||
input inst_bw; // Decoded Inst: byte width
|
||||
input [15:0] inst_dest; // Decoded Inst: destination (one hot)
|
||||
input [15:0] inst_dext; // Decoded Inst: destination extended instruction word
|
||||
input inst_irq_rst; // Decoded Inst: reset interrupt
|
||||
input [7:0] inst_jmp; // Decoded Inst: Conditional jump
|
||||
input inst_mov; // Decoded Inst: mov instruction
|
||||
input [15:0] inst_sext; // Decoded Inst: source extended instruction word
|
||||
input [7:0] inst_so; // Decoded Inst: Single-operand arithmetic
|
||||
input [15:0] inst_src; // Decoded Inst: source (one hot)
|
||||
input [2:0] inst_type; // Decoded Instruction type
|
||||
input mclk; // Main system clock
|
||||
input [15:0] mdb_in; // Memory data bus input
|
||||
input [15:0] pc; // Program counter
|
||||
input [15:0] pc_nxt; // Next PC value (for CALL & IRQ)
|
||||
input puc_rst; // Main system reset
|
||||
input scan_enable; // Scan enable (active during scan shifting)
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) INTERNAL WIRES/REGISTERS/PARAMETERS DECLARATION
|
||||
//=============================================================================
|
||||
|
||||
wire [15:0] alu_out;
|
||||
wire [15:0] alu_out_add;
|
||||
wire [3:0] alu_stat;
|
||||
wire [3:0] alu_stat_wr;
|
||||
wire [15:0] op_dst;
|
||||
wire [15:0] op_src;
|
||||
wire [15:0] reg_dest;
|
||||
wire [15:0] reg_src;
|
||||
wire [15:0] mdb_in_bw;
|
||||
wire [15:0] mdb_in_val;
|
||||
wire [3:0] status;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 2) REGISTER FILE
|
||||
//=============================================================================
|
||||
|
||||
wire reg_dest_wr = ((e_state==`E_EXEC) & (
|
||||
(inst_type[`INST_TO] & inst_ad[`DIR] & ~inst_alu[`EXEC_NO_WR]) |
|
||||
(inst_type[`INST_SO] & inst_as[`DIR] & ~(inst_so[`PUSH] | inst_so[`CALL] | inst_so[`RETI])) |
|
||||
inst_type[`INST_JMP])) | dbg_reg_wr;
|
||||
|
||||
wire reg_sp_wr = (((e_state==`E_IRQ_1) | (e_state==`E_IRQ_3)) & ~inst_irq_rst) |
|
||||
((e_state==`E_DST_RD) & ((inst_so[`PUSH] | inst_so[`CALL]) & ~inst_as[`IDX] & ~((inst_as[`INDIR] | inst_as[`INDIR_I]) & inst_src[1]))) |
|
||||
((e_state==`E_SRC_AD) & ((inst_so[`PUSH] | inst_so[`CALL]) & inst_as[`IDX])) |
|
||||
((e_state==`E_SRC_RD) & ((inst_so[`PUSH] | inst_so[`CALL]) & ((inst_as[`INDIR] | inst_as[`INDIR_I]) & inst_src[1])));
|
||||
|
||||
wire reg_sr_wr = (e_state==`E_DST_RD) & inst_so[`RETI];
|
||||
|
||||
wire reg_sr_clr = (e_state==`E_IRQ_2);
|
||||
|
||||
wire reg_pc_call = ((e_state==`E_EXEC) & inst_so[`CALL]) |
|
||||
((e_state==`E_DST_WR) & inst_so[`RETI]);
|
||||
|
||||
wire reg_incr = (exec_done & inst_as[`INDIR_I]) |
|
||||
((e_state==`E_SRC_RD) & inst_so[`RETI]) |
|
||||
((e_state==`E_EXEC) & inst_so[`RETI]);
|
||||
|
||||
assign dbg_reg_din = reg_dest;
|
||||
|
||||
|
||||
omsp_register_file register_file_0 (
|
||||
|
||||
// OUTPUTs
|
||||
.cpuoff (cpuoff), // Turns off the CPU
|
||||
.gie (gie), // General interrupt enable
|
||||
.oscoff (oscoff), // Turns off LFXT1 clock input
|
||||
.pc_sw (pc_sw), // Program counter software value
|
||||
.pc_sw_wr (pc_sw_wr), // Program counter software write
|
||||
.reg_dest (reg_dest), // Selected register destination content
|
||||
.reg_src (reg_src), // Selected register source content
|
||||
.scg0 (scg0), // System clock generator 1. Turns off the DCO
|
||||
.scg1 (scg1), // System clock generator 1. Turns off the SMCLK
|
||||
.status (status), // R2 Status {V,N,Z,C}
|
||||
|
||||
// INPUTs
|
||||
.alu_stat (alu_stat), // ALU Status {V,N,Z,C}
|
||||
.alu_stat_wr (alu_stat_wr), // ALU Status write {V,N,Z,C}
|
||||
.inst_bw (inst_bw), // Decoded Inst: byte width
|
||||
.inst_dest (inst_dest), // Register destination selection
|
||||
.inst_src (inst_src), // Register source selection
|
||||
.mclk (mclk), // Main system clock
|
||||
.pc (pc), // Program counter
|
||||
.puc_rst (puc_rst), // Main system reset
|
||||
.reg_dest_val (alu_out), // Selected register destination value
|
||||
.reg_dest_wr (reg_dest_wr), // Write selected register destination
|
||||
.reg_pc_call (reg_pc_call), // Trigger PC update for a CALL instruction
|
||||
.reg_sp_val (alu_out_add), // Stack Pointer next value
|
||||
.reg_sp_wr (reg_sp_wr), // Stack Pointer write
|
||||
.reg_sr_clr (reg_sr_clr), // Status register clear for interrupts
|
||||
.reg_sr_wr (reg_sr_wr), // Status Register update for RETI instruction
|
||||
.reg_incr (reg_incr), // Increment source register
|
||||
.scan_enable (scan_enable) // Scan enable (active during scan shifting)
|
||||
);
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 3) SOURCE OPERAND MUXING
|
||||
//=============================================================================
|
||||
// inst_as[`DIR] : Register direct. -> Source is in register
|
||||
// inst_as[`IDX] : Register indexed. -> Source is in memory, address is register+offset
|
||||
// inst_as[`INDIR] : Register indirect.
|
||||
// inst_as[`INDIR_I]: Register indirect autoincrement.
|
||||
// inst_as[`SYMB] : Symbolic (operand is in memory at address PC+x).
|
||||
// inst_as[`IMM] : Immediate (operand is next word in the instruction stream).
|
||||
// inst_as[`ABS] : Absolute (operand is in memory at address x).
|
||||
// inst_as[`CONST] : Constant.
|
||||
|
||||
wire src_reg_src_sel = (e_state==`E_IRQ_0) |
|
||||
(e_state==`E_IRQ_2) |
|
||||
((e_state==`E_SRC_RD) & ~inst_as[`ABS]) |
|
||||
((e_state==`E_SRC_WR) & ~inst_as[`ABS]) |
|
||||
((e_state==`E_EXEC) & inst_as[`DIR] & ~inst_type[`INST_JMP]);
|
||||
|
||||
wire src_reg_dest_sel = (e_state==`E_IRQ_1) |
|
||||
(e_state==`E_IRQ_3) |
|
||||
((e_state==`E_DST_RD) & (inst_so[`PUSH] | inst_so[`CALL])) |
|
||||
((e_state==`E_SRC_AD) & (inst_so[`PUSH] | inst_so[`CALL]) & inst_as[`IDX]);
|
||||
|
||||
wire src_mdb_in_val_sel = ((e_state==`E_DST_RD) & inst_so[`RETI]) |
|
||||
((e_state==`E_EXEC) & (inst_as[`INDIR] | inst_as[`INDIR_I] |
|
||||
inst_as[`IDX] | inst_as[`SYMB] |
|
||||
inst_as[`ABS]));
|
||||
|
||||
wire src_inst_dext_sel = ((e_state==`E_DST_RD) & ~(inst_so[`PUSH] | inst_so[`CALL])) |
|
||||
((e_state==`E_DST_WR) & ~(inst_so[`PUSH] | inst_so[`CALL] |
|
||||
inst_so[`RETI]));
|
||||
|
||||
wire src_inst_sext_sel = ((e_state==`E_EXEC) & (inst_type[`INST_JMP] | inst_as[`IMM] |
|
||||
inst_as[`CONST] | inst_so[`RETI]));
|
||||
|
||||
|
||||
assign op_src = src_reg_src_sel ? reg_src :
|
||||
src_reg_dest_sel ? reg_dest :
|
||||
src_mdb_in_val_sel ? mdb_in_val :
|
||||
src_inst_dext_sel ? inst_dext :
|
||||
src_inst_sext_sel ? inst_sext : 16'h0000;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 4) DESTINATION OPERAND MUXING
|
||||
//=============================================================================
|
||||
// inst_ad[`DIR] : Register direct.
|
||||
// inst_ad[`IDX] : Register indexed.
|
||||
// inst_ad[`SYMB] : Symbolic (operand is in memory at address PC+x).
|
||||
// inst_ad[`ABS] : Absolute (operand is in memory at address x).
|
||||
|
||||
|
||||
wire dst_inst_sext_sel = ((e_state==`E_SRC_RD) & (inst_as[`IDX] | inst_as[`SYMB] |
|
||||
inst_as[`ABS])) |
|
||||
((e_state==`E_SRC_WR) & (inst_as[`IDX] | inst_as[`SYMB] |
|
||||
inst_as[`ABS]));
|
||||
|
||||
wire dst_mdb_in_bw_sel = ((e_state==`E_DST_WR) & inst_so[`RETI]) |
|
||||
((e_state==`E_EXEC) & ~(inst_ad[`DIR] | inst_type[`INST_JMP] |
|
||||
inst_type[`INST_SO]) & ~inst_so[`RETI]);
|
||||
|
||||
wire dst_fffe_sel = (e_state==`E_IRQ_0) |
|
||||
(e_state==`E_IRQ_1) |
|
||||
(e_state==`E_IRQ_3) |
|
||||
((e_state==`E_DST_RD) & (inst_so[`PUSH] | inst_so[`CALL]) & ~inst_so[`RETI]) |
|
||||
((e_state==`E_SRC_AD) & (inst_so[`PUSH] | inst_so[`CALL]) & inst_as[`IDX]) |
|
||||
((e_state==`E_SRC_RD) & (inst_so[`PUSH] | inst_so[`CALL]) & (inst_as[`INDIR] | inst_as[`INDIR_I]) & inst_src[1]);
|
||||
|
||||
wire dst_reg_dest_sel = ((e_state==`E_DST_RD) & ~(inst_so[`PUSH] | inst_so[`CALL] | inst_ad[`ABS] | inst_so[`RETI])) |
|
||||
((e_state==`E_DST_WR) & ~inst_ad[`ABS]) |
|
||||
((e_state==`E_EXEC) & (inst_ad[`DIR] | inst_type[`INST_JMP] |
|
||||
inst_type[`INST_SO]) & ~inst_so[`RETI]);
|
||||
|
||||
|
||||
assign op_dst = dbg_halt_st ? dbg_mem_dout :
|
||||
dst_inst_sext_sel ? inst_sext :
|
||||
dst_mdb_in_bw_sel ? mdb_in_bw :
|
||||
dst_reg_dest_sel ? reg_dest :
|
||||
dst_fffe_sel ? 16'hfffe : 16'h0000;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 5) ALU
|
||||
//=============================================================================
|
||||
|
||||
wire exec_cycle = (e_state==`E_EXEC);
|
||||
|
||||
omsp_alu alu_0 (
|
||||
|
||||
// OUTPUTs
|
||||
.alu_out (alu_out), // ALU output value
|
||||
.alu_out_add (alu_out_add), // ALU adder output value
|
||||
.alu_stat (alu_stat), // ALU Status {V,N,Z,C}
|
||||
.alu_stat_wr (alu_stat_wr), // ALU Status write {V,N,Z,C}
|
||||
|
||||
// INPUTs
|
||||
.dbg_halt_st (dbg_halt_st), // Halt/Run status from CPU
|
||||
.exec_cycle (exec_cycle), // Instruction execution cycle
|
||||
.inst_alu (inst_alu), // ALU control signals
|
||||
.inst_bw (inst_bw), // Decoded Inst: byte width
|
||||
.inst_jmp (inst_jmp), // Decoded Inst: Conditional jump
|
||||
.inst_so (inst_so), // Single-operand arithmetic
|
||||
.op_dst (op_dst), // Destination operand
|
||||
.op_src (op_src), // Source operand
|
||||
.status (status) // R2 Status {V,N,Z,C}
|
||||
);
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 6) MEMORY INTERFACE
|
||||
//=============================================================================
|
||||
|
||||
// Detect memory read/write access
|
||||
assign mb_en = ((e_state==`E_IRQ_1) & ~inst_irq_rst) |
|
||||
((e_state==`E_IRQ_3) & ~inst_irq_rst) |
|
||||
((e_state==`E_SRC_RD) & ~inst_as[`IMM]) |
|
||||
(e_state==`E_SRC_WR) |
|
||||
((e_state==`E_EXEC) & inst_so[`RETI]) |
|
||||
((e_state==`E_DST_RD) & ~inst_type[`INST_SO]
|
||||
& ~inst_mov) |
|
||||
(e_state==`E_DST_WR);
|
||||
|
||||
wire [1:0] mb_wr_msk = inst_alu[`EXEC_NO_WR] ? 2'b00 :
|
||||
~inst_bw ? 2'b11 :
|
||||
alu_out_add[0] ? 2'b10 : 2'b01;
|
||||
assign mb_wr = ({2{(e_state==`E_IRQ_1)}} |
|
||||
{2{(e_state==`E_IRQ_3)}} |
|
||||
{2{(e_state==`E_DST_WR)}} |
|
||||
{2{(e_state==`E_SRC_WR)}}) & mb_wr_msk;
|
||||
|
||||
// Memory address bus
|
||||
assign mab = alu_out_add[15:0];
|
||||
|
||||
// Memory data bus output
|
||||
reg [15:0] mdb_out_nxt;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire mdb_out_nxt_en = (e_state==`E_DST_RD) |
|
||||
(((e_state==`E_EXEC) & ~inst_so[`CALL]) |
|
||||
(e_state==`E_IRQ_0) | (e_state==`E_IRQ_2));
|
||||
wire mclk_mdb_out_nxt;
|
||||
omsp_clock_gate clock_gate_mdb_out_nxt (.gclk(mclk_mdb_out_nxt),
|
||||
.clk (mclk), .enable(mdb_out_nxt_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_mdb_out_nxt = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_mdb_out_nxt or posedge puc_rst)
|
||||
if (puc_rst) mdb_out_nxt <= 16'h0000;
|
||||
else if (e_state==`E_DST_RD) mdb_out_nxt <= pc_nxt;
|
||||
`ifdef CLOCK_GATING
|
||||
else mdb_out_nxt <= alu_out;
|
||||
`else
|
||||
else if ((e_state==`E_EXEC & ~inst_so[`CALL]) |
|
||||
(e_state==`E_IRQ_0) | (e_state==`E_IRQ_2)) mdb_out_nxt <= alu_out;
|
||||
`endif
|
||||
|
||||
assign mdb_out = inst_bw ? {2{mdb_out_nxt[7:0]}} : mdb_out_nxt;
|
||||
|
||||
// Format memory data bus input depending on BW
|
||||
reg mab_lsb;
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) mab_lsb <= 1'b0;
|
||||
else if (mb_en) mab_lsb <= alu_out_add[0];
|
||||
|
||||
assign mdb_in_bw = ~inst_bw ? mdb_in :
|
||||
mab_lsb ? {2{mdb_in[15:8]}} : mdb_in;
|
||||
|
||||
// Memory data bus input buffer (buffer after a source read)
|
||||
reg mdb_in_buf_en;
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) mdb_in_buf_en <= 1'b0;
|
||||
else mdb_in_buf_en <= (e_state==`E_SRC_RD);
|
||||
|
||||
reg mdb_in_buf_valid;
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) mdb_in_buf_valid <= 1'b0;
|
||||
else if (e_state==`E_EXEC) mdb_in_buf_valid <= 1'b0;
|
||||
else if (mdb_in_buf_en) mdb_in_buf_valid <= 1'b1;
|
||||
|
||||
reg [15:0] mdb_in_buf;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire mclk_mdb_in_buf;
|
||||
omsp_clock_gate clock_gate_mdb_in_buf (.gclk(mclk_mdb_in_buf),
|
||||
.clk (mclk), .enable(mdb_in_buf_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_mdb_in_buf = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_mdb_in_buf or posedge puc_rst)
|
||||
if (puc_rst) mdb_in_buf <= 16'h0000;
|
||||
`ifdef CLOCK_GATING
|
||||
else mdb_in_buf <= mdb_in_bw;
|
||||
`else
|
||||
else if (mdb_in_buf_en) mdb_in_buf <= mdb_in_bw;
|
||||
`endif
|
||||
|
||||
assign mdb_in_val = mdb_in_buf_valid ? mdb_in_buf : mdb_in_bw;
|
||||
|
||||
|
||||
endmodule // omsp_execution_unit
|
||||
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_undefines.v"
|
||||
`endif
|
|
@ -1,966 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_frontend.v
|
||||
//
|
||||
// *Module Description:
|
||||
// openMSP430 Instruction fetch and decode unit
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 134 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
|
||||
//----------------------------------------------------------------------------
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_defines.v"
|
||||
`endif
|
||||
|
||||
module omsp_frontend (
|
||||
|
||||
// OUTPUTs
|
||||
dbg_halt_st, // Halt/Run status from CPU
|
||||
decode_noirq, // Frontend decode instruction
|
||||
e_state, // Execution state
|
||||
exec_done, // Execution completed
|
||||
inst_ad, // Decoded Inst: destination addressing mode
|
||||
inst_as, // Decoded Inst: source addressing mode
|
||||
inst_alu, // ALU control signals
|
||||
inst_bw, // Decoded Inst: byte width
|
||||
inst_dest, // Decoded Inst: destination (one hot)
|
||||
inst_dext, // Decoded Inst: destination extended instruction word
|
||||
inst_irq_rst, // Decoded Inst: Reset interrupt
|
||||
inst_jmp, // Decoded Inst: Conditional jump
|
||||
inst_mov, // Decoded Inst: mov instruction
|
||||
inst_sext, // Decoded Inst: source extended instruction word
|
||||
inst_so, // Decoded Inst: Single-operand arithmetic
|
||||
inst_src, // Decoded Inst: source (one hot)
|
||||
inst_type, // Decoded Instruction type
|
||||
irq_acc, // Interrupt request accepted (one-hot signal)
|
||||
mab, // Frontend Memory address bus
|
||||
mb_en, // Frontend Memory bus enable
|
||||
mclk_enable, // Main System Clock enable
|
||||
mclk_wkup, // Main System Clock wake-up (asynchronous)
|
||||
nmi_acc, // Non-Maskable interrupt request accepted
|
||||
pc, // Program counter
|
||||
pc_nxt, // Next PC value (for CALL & IRQ)
|
||||
|
||||
// INPUTs
|
||||
cpu_en_s, // Enable CPU code execution (synchronous)
|
||||
cpuoff, // Turns off the CPU
|
||||
dbg_halt_cmd, // Halt CPU command
|
||||
dbg_reg_sel, // Debug selected register for rd/wr access
|
||||
fe_pmem_wait, // Frontend wait for Instruction fetch
|
||||
gie, // General interrupt enable
|
||||
irq, // Maskable interrupts
|
||||
mclk, // Main system clock
|
||||
mdb_in, // Frontend Memory data bus input
|
||||
nmi_pnd, // Non-maskable interrupt pending
|
||||
nmi_wkup, // NMI Wakeup
|
||||
pc_sw, // Program counter software value
|
||||
pc_sw_wr, // Program counter software write
|
||||
puc_rst, // Main system reset
|
||||
scan_enable, // Scan enable (active during scan shifting)
|
||||
wdt_irq, // Watchdog-timer interrupt
|
||||
wdt_wkup, // Watchdog Wakeup
|
||||
wkup // System Wake-up (asynchronous)
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output dbg_halt_st; // Halt/Run status from CPU
|
||||
output decode_noirq; // Frontend decode instruction
|
||||
output [3:0] e_state; // Execution state
|
||||
output exec_done; // Execution completed
|
||||
output [7:0] inst_ad; // Decoded Inst: destination addressing mode
|
||||
output [7:0] inst_as; // Decoded Inst: source addressing mode
|
||||
output [11:0] inst_alu; // ALU control signals
|
||||
output inst_bw; // Decoded Inst: byte width
|
||||
output [15:0] inst_dest; // Decoded Inst: destination (one hot)
|
||||
output [15:0] inst_dext; // Decoded Inst: destination extended instruction word
|
||||
output inst_irq_rst; // Decoded Inst: Reset interrupt
|
||||
output [7:0] inst_jmp; // Decoded Inst: Conditional jump
|
||||
output inst_mov; // Decoded Inst: mov instruction
|
||||
output [15:0] inst_sext; // Decoded Inst: source extended instruction word
|
||||
output [7:0] inst_so; // Decoded Inst: Single-operand arithmetic
|
||||
output [15:0] inst_src; // Decoded Inst: source (one hot)
|
||||
output [2:0] inst_type; // Decoded Instruction type
|
||||
output [13:0] irq_acc; // Interrupt request accepted (one-hot signal)
|
||||
output [15:0] mab; // Frontend Memory address bus
|
||||
output mb_en; // Frontend Memory bus enable
|
||||
output mclk_enable; // Main System Clock enable
|
||||
output mclk_wkup; // Main System Clock wake-up (asynchronous)
|
||||
output nmi_acc; // Non-Maskable interrupt request accepted
|
||||
output [15:0] pc; // Program counter
|
||||
output [15:0] pc_nxt; // Next PC value (for CALL & IRQ)
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input cpu_en_s; // Enable CPU code execution (synchronous)
|
||||
input cpuoff; // Turns off the CPU
|
||||
input dbg_halt_cmd; // Halt CPU command
|
||||
input [3:0] dbg_reg_sel; // Debug selected register for rd/wr access
|
||||
input fe_pmem_wait; // Frontend wait for Instruction fetch
|
||||
input gie; // General interrupt enable
|
||||
input [13:0] irq; // Maskable interrupts
|
||||
input mclk; // Main system clock
|
||||
input [15:0] mdb_in; // Frontend Memory data bus input
|
||||
input nmi_pnd; // Non-maskable interrupt pending
|
||||
input nmi_wkup; // NMI Wakeup
|
||||
input [15:0] pc_sw; // Program counter software value
|
||||
input pc_sw_wr; // Program counter software write
|
||||
input puc_rst; // Main system reset
|
||||
input scan_enable; // Scan enable (active during scan shifting)
|
||||
input wdt_irq; // Watchdog-timer interrupt
|
||||
input wdt_wkup; // Watchdog Wakeup
|
||||
input wkup; // System Wake-up (asynchronous)
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) UTILITY FUNCTIONS
|
||||
//=============================================================================
|
||||
|
||||
// 16 bits one-hot decoder
|
||||
function [15:0] one_hot16;
|
||||
input [3:0] binary;
|
||||
begin
|
||||
one_hot16 = 16'h0000;
|
||||
one_hot16[binary] = 1'b1;
|
||||
end
|
||||
endfunction
|
||||
|
||||
// 8 bits one-hot decoder
|
||||
function [7:0] one_hot8;
|
||||
input [2:0] binary;
|
||||
begin
|
||||
one_hot8 = 8'h00;
|
||||
one_hot8[binary] = 1'b1;
|
||||
end
|
||||
endfunction
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 2) PARAMETER DEFINITIONS
|
||||
//=============================================================================
|
||||
|
||||
//
|
||||
// 2.1) Instruction State machine definitons
|
||||
//-------------------------------------------
|
||||
|
||||
parameter I_IRQ_FETCH = `I_IRQ_FETCH;
|
||||
parameter I_IRQ_DONE = `I_IRQ_DONE;
|
||||
parameter I_DEC = `I_DEC; // New instruction ready for decode
|
||||
parameter I_EXT1 = `I_EXT1; // 1st Extension word
|
||||
parameter I_EXT2 = `I_EXT2; // 2nd Extension word
|
||||
parameter I_IDLE = `I_IDLE; // CPU is in IDLE mode
|
||||
|
||||
//
|
||||
// 2.2) Execution State machine definitons
|
||||
//-------------------------------------------
|
||||
|
||||
parameter E_IRQ_0 = `E_IRQ_0;
|
||||
parameter E_IRQ_1 = `E_IRQ_1;
|
||||
parameter E_IRQ_2 = `E_IRQ_2;
|
||||
parameter E_IRQ_3 = `E_IRQ_3;
|
||||
parameter E_IRQ_4 = `E_IRQ_4;
|
||||
parameter E_SRC_AD = `E_SRC_AD;
|
||||
parameter E_SRC_RD = `E_SRC_RD;
|
||||
parameter E_SRC_WR = `E_SRC_WR;
|
||||
parameter E_DST_AD = `E_DST_AD;
|
||||
parameter E_DST_RD = `E_DST_RD;
|
||||
parameter E_DST_WR = `E_DST_WR;
|
||||
parameter E_EXEC = `E_EXEC;
|
||||
parameter E_JUMP = `E_JUMP;
|
||||
parameter E_IDLE = `E_IDLE;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 3) FRONTEND STATE MACHINE
|
||||
//=============================================================================
|
||||
|
||||
// The wire "conv" is used as state bits to calculate the next response
|
||||
reg [2:0] i_state;
|
||||
reg [2:0] i_state_nxt;
|
||||
|
||||
reg [1:0] inst_sz;
|
||||
wire [1:0] inst_sz_nxt;
|
||||
wire irq_detect;
|
||||
wire [2:0] inst_type_nxt;
|
||||
wire is_const;
|
||||
reg [15:0] sconst_nxt;
|
||||
reg [3:0] e_state_nxt;
|
||||
|
||||
// CPU on/off through the debug interface or cpu_en port
|
||||
wire cpu_halt_cmd = dbg_halt_cmd | ~cpu_en_s;
|
||||
|
||||
// States Transitions
|
||||
always @(i_state or inst_sz or inst_sz_nxt or pc_sw_wr or exec_done or
|
||||
irq_detect or cpuoff or cpu_halt_cmd or e_state)
|
||||
case(i_state)
|
||||
I_IDLE : i_state_nxt = (irq_detect & ~cpu_halt_cmd) ? I_IRQ_FETCH :
|
||||
(~cpuoff & ~cpu_halt_cmd) ? I_DEC : I_IDLE;
|
||||
I_IRQ_FETCH: i_state_nxt = I_IRQ_DONE;
|
||||
I_IRQ_DONE : i_state_nxt = I_DEC;
|
||||
I_DEC : i_state_nxt = irq_detect ? I_IRQ_FETCH :
|
||||
(cpuoff | cpu_halt_cmd) & exec_done ? I_IDLE :
|
||||
cpu_halt_cmd & (e_state==E_IDLE) ? I_IDLE :
|
||||
pc_sw_wr ? I_DEC :
|
||||
~exec_done & ~(e_state==E_IDLE) ? I_DEC : // Wait in decode state
|
||||
(inst_sz_nxt!=2'b00) ? I_EXT1 : I_DEC; // until execution is completed
|
||||
I_EXT1 : i_state_nxt = pc_sw_wr ? I_DEC :
|
||||
(inst_sz!=2'b01) ? I_EXT2 : I_DEC;
|
||||
I_EXT2 : i_state_nxt = I_DEC;
|
||||
// pragma coverage off
|
||||
default : i_state_nxt = I_IRQ_FETCH;
|
||||
// pragma coverage on
|
||||
endcase
|
||||
|
||||
// State machine
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) i_state <= I_IRQ_FETCH;
|
||||
else i_state <= i_state_nxt;
|
||||
|
||||
// Utility signals
|
||||
wire decode_noirq = ((i_state==I_DEC) & (exec_done | (e_state==E_IDLE)));
|
||||
wire decode = decode_noirq | irq_detect;
|
||||
wire fetch = ~((i_state==I_DEC) & ~(exec_done | (e_state==E_IDLE))) & ~(e_state_nxt==E_IDLE);
|
||||
|
||||
// Debug interface cpu status
|
||||
reg dbg_halt_st;
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) dbg_halt_st <= 1'b0;
|
||||
else dbg_halt_st <= cpu_halt_cmd & (i_state_nxt==I_IDLE);
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 4) INTERRUPT HANDLING & SYSTEM WAKEUP
|
||||
//=============================================================================
|
||||
|
||||
//
|
||||
// 4.1) INTERRUPT HANDLING
|
||||
//-----------------------------------------
|
||||
|
||||
// Detect reset interrupt
|
||||
reg inst_irq_rst;
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) inst_irq_rst <= 1'b1;
|
||||
else if (exec_done) inst_irq_rst <= 1'b0;
|
||||
|
||||
// Detect other interrupts
|
||||
assign irq_detect = (nmi_pnd | ((|irq | wdt_irq) & gie)) & ~cpu_halt_cmd & ~dbg_halt_st & (exec_done | (i_state==I_IDLE));
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire mclk_irq_num;
|
||||
omsp_clock_gate clock_gate_irq_num (.gclk(mclk_irq_num),
|
||||
.clk (mclk), .enable(irq_detect), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_irq_num = mclk;
|
||||
`endif
|
||||
|
||||
// Select interrupt vector
|
||||
reg [3:0] irq_num;
|
||||
always @(posedge mclk_irq_num or posedge puc_rst)
|
||||
if (puc_rst) irq_num <= 4'hf;
|
||||
`ifdef CLOCK_GATING
|
||||
else irq_num <= nmi_pnd ? 4'he :
|
||||
`else
|
||||
else if (irq_detect) irq_num <= nmi_pnd ? 4'he :
|
||||
`endif
|
||||
irq[13] ? 4'hd :
|
||||
irq[12] ? 4'hc :
|
||||
irq[11] ? 4'hb :
|
||||
(irq[10] | wdt_irq) ? 4'ha :
|
||||
irq[9] ? 4'h9 :
|
||||
irq[8] ? 4'h8 :
|
||||
irq[7] ? 4'h7 :
|
||||
irq[6] ? 4'h6 :
|
||||
irq[5] ? 4'h5 :
|
||||
irq[4] ? 4'h4 :
|
||||
irq[3] ? 4'h3 :
|
||||
irq[2] ? 4'h2 :
|
||||
irq[1] ? 4'h1 :
|
||||
irq[0] ? 4'h0 : 4'hf;
|
||||
|
||||
wire [15:0] irq_addr = {11'h7ff, irq_num, 1'b0};
|
||||
|
||||
// Interrupt request accepted
|
||||
wire [15:0] irq_acc_all = one_hot16(irq_num) & {16{(i_state==I_IRQ_FETCH)}};
|
||||
wire [13:0] irq_acc = irq_acc_all[13:0];
|
||||
wire nmi_acc = irq_acc_all[14];
|
||||
|
||||
//
|
||||
// 4.2) SYSTEM WAKEUP
|
||||
//-----------------------------------------
|
||||
`ifdef CPUOFF_EN
|
||||
|
||||
// Generate the main system clock enable signal
|
||||
// Keep the clock running if:
|
||||
wire mclk_enable = inst_irq_rst ? cpu_en_s : // - the RESET interrupt is currently executing
|
||||
// and if the CPU is enabled
|
||||
// otherwise if:
|
||||
~((cpuoff | ~cpu_en_s) & // - the CPUOFF flag, cpu_en command, instruction
|
||||
(i_state==I_IDLE) & // and execution state machines are all two
|
||||
(e_state==E_IDLE)); // not idle.
|
||||
|
||||
|
||||
// Wakeup condition from maskable interrupts
|
||||
wire mirq_wkup;
|
||||
omsp_and_gate and_mirq_wkup (.y(mirq_wkup), .a(wkup | wdt_wkup), .b(gie));
|
||||
|
||||
// Combined asynchronous wakeup detection from nmi & irq (masked if the cpu is disabled)
|
||||
omsp_and_gate and_mclk_wkup (.y(mclk_wkup), .a(nmi_wkup | mirq_wkup), .b(cpu_en_s));
|
||||
|
||||
`else
|
||||
|
||||
// In the CPUOFF feature is disabled, the wake-up and enable signals are always 1
|
||||
assign mclk_wkup = 1'b1;
|
||||
assign mclk_enable = 1'b1;
|
||||
`endif
|
||||
|
||||
//=============================================================================
|
||||
// 5) FETCH INSTRUCTION
|
||||
//=============================================================================
|
||||
|
||||
//
|
||||
// 5.1) PROGRAM COUNTER & MEMORY INTERFACE
|
||||
//-----------------------------------------
|
||||
|
||||
// Program counter
|
||||
reg [15:0] pc;
|
||||
|
||||
// Compute next PC value
|
||||
wire [15:0] pc_incr = pc + {14'h0000, fetch, 1'b0};
|
||||
wire [15:0] pc_nxt = pc_sw_wr ? pc_sw :
|
||||
(i_state==I_IRQ_FETCH) ? irq_addr :
|
||||
(i_state==I_IRQ_DONE) ? mdb_in : pc_incr;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire pc_en = fetch |
|
||||
pc_sw_wr |
|
||||
(i_state==I_IRQ_FETCH) |
|
||||
(i_state==I_IRQ_DONE);
|
||||
wire mclk_pc;
|
||||
omsp_clock_gate clock_gate_pc (.gclk(mclk_pc),
|
||||
.clk (mclk), .enable(pc_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_pc = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_pc or posedge puc_rst)
|
||||
if (puc_rst) pc <= 16'h0000;
|
||||
else pc <= pc_nxt;
|
||||
|
||||
// Check if ROM has been busy in order to retry ROM access
|
||||
reg pmem_busy;
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) pmem_busy <= 1'b0;
|
||||
else pmem_busy <= fe_pmem_wait;
|
||||
|
||||
// Memory interface
|
||||
wire [15:0] mab = pc_nxt;
|
||||
wire mb_en = fetch | pc_sw_wr | (i_state==I_IRQ_FETCH) | pmem_busy | (dbg_halt_st & ~cpu_halt_cmd);
|
||||
|
||||
|
||||
//
|
||||
// 5.2) INSTRUCTION REGISTER
|
||||
//--------------------------------
|
||||
|
||||
// Instruction register
|
||||
wire [15:0] ir = mdb_in;
|
||||
|
||||
// Detect if source extension word is required
|
||||
wire is_sext = (inst_as[`IDX] | inst_as[`SYMB] | inst_as[`ABS] | inst_as[`IMM]);
|
||||
|
||||
// For the Symbolic addressing mode, add -2 to the extension word in order
|
||||
// to make up for the PC address
|
||||
wire [15:0] ext_incr = ((i_state==I_EXT1) & inst_as[`SYMB]) |
|
||||
((i_state==I_EXT2) & inst_ad[`SYMB]) |
|
||||
((i_state==I_EXT1) & ~inst_as[`SYMB] &
|
||||
~(i_state_nxt==I_EXT2) & inst_ad[`SYMB]) ? 16'hfffe : 16'h0000;
|
||||
|
||||
wire [15:0] ext_nxt = ir + ext_incr;
|
||||
|
||||
// Store source extension word
|
||||
reg [15:0] inst_sext;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire inst_sext_en = (decode & is_const) |
|
||||
(decode & inst_type_nxt[`INST_JMP]) |
|
||||
((i_state==I_EXT1) & is_sext);
|
||||
wire mclk_inst_sext;
|
||||
omsp_clock_gate clock_gate_inst_sext (.gclk(mclk_inst_sext),
|
||||
.clk (mclk), .enable(inst_sext_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_inst_sext = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_inst_sext or posedge puc_rst)
|
||||
if (puc_rst) inst_sext <= 16'h0000;
|
||||
else if (decode & is_const) inst_sext <= sconst_nxt;
|
||||
else if (decode & inst_type_nxt[`INST_JMP]) inst_sext <= {{5{ir[9]}},ir[9:0],1'b0};
|
||||
`ifdef CLOCK_GATING
|
||||
else inst_sext <= ext_nxt;
|
||||
`else
|
||||
else if ((i_state==I_EXT1) & is_sext) inst_sext <= ext_nxt;
|
||||
`endif
|
||||
|
||||
// Source extension word is ready
|
||||
wire inst_sext_rdy = (i_state==I_EXT1) & is_sext;
|
||||
|
||||
|
||||
// Store destination extension word
|
||||
reg [15:0] inst_dext;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire inst_dext_en = ((i_state==I_EXT1) & ~is_sext) |
|
||||
(i_state==I_EXT2);
|
||||
wire mclk_inst_dext;
|
||||
omsp_clock_gate clock_gate_inst_dext (.gclk(mclk_inst_dext),
|
||||
.clk (mclk), .enable(inst_dext_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_inst_dext = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_inst_dext or posedge puc_rst)
|
||||
if (puc_rst) inst_dext <= 16'h0000;
|
||||
else if ((i_state==I_EXT1) & ~is_sext) inst_dext <= ext_nxt;
|
||||
`ifdef CLOCK_GATING
|
||||
else inst_dext <= ext_nxt;
|
||||
`else
|
||||
else if (i_state==I_EXT2) inst_dext <= ext_nxt;
|
||||
`endif
|
||||
|
||||
// Destination extension word is ready
|
||||
wire inst_dext_rdy = (((i_state==I_EXT1) & ~is_sext) | (i_state==I_EXT2));
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 6) DECODE INSTRUCTION
|
||||
//=============================================================================
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire mclk_decode;
|
||||
omsp_clock_gate clock_gate_decode (.gclk(mclk_decode),
|
||||
.clk (mclk), .enable(decode), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_decode = mclk;
|
||||
`endif
|
||||
|
||||
//
|
||||
// 6.1) OPCODE: INSTRUCTION TYPE
|
||||
//----------------------------------------
|
||||
// Instructions type is encoded in a one hot fashion as following:
|
||||
//
|
||||
// 3'b001: Single-operand arithmetic
|
||||
// 3'b010: Conditional jump
|
||||
// 3'b100: Two-operand arithmetic
|
||||
|
||||
reg [2:0] inst_type;
|
||||
assign inst_type_nxt = {(ir[15:14]!=2'b00),
|
||||
(ir[15:13]==3'b001),
|
||||
(ir[15:13]==3'b000)} & {3{~irq_detect}};
|
||||
|
||||
always @(posedge mclk_decode or posedge puc_rst)
|
||||
if (puc_rst) inst_type <= 3'b000;
|
||||
`ifdef CLOCK_GATING
|
||||
else inst_type <= inst_type_nxt;
|
||||
`else
|
||||
else if (decode) inst_type <= inst_type_nxt;
|
||||
`endif
|
||||
|
||||
//
|
||||
// 6.2) OPCODE: SINGLE-OPERAND ARITHMETIC
|
||||
//----------------------------------------
|
||||
// Instructions are encoded in a one hot fashion as following:
|
||||
//
|
||||
// 8'b00000001: RRC
|
||||
// 8'b00000010: SWPB
|
||||
// 8'b00000100: RRA
|
||||
// 8'b00001000: SXT
|
||||
// 8'b00010000: PUSH
|
||||
// 8'b00100000: CALL
|
||||
// 8'b01000000: RETI
|
||||
// 8'b10000000: IRQ
|
||||
|
||||
reg [7:0] inst_so;
|
||||
wire [7:0] inst_so_nxt = irq_detect ? 8'h80 : (one_hot8(ir[9:7]) & {8{inst_type_nxt[`INST_SO]}});
|
||||
|
||||
always @(posedge mclk_decode or posedge puc_rst)
|
||||
if (puc_rst) inst_so <= 8'h00;
|
||||
`ifdef CLOCK_GATING
|
||||
else inst_so <= inst_so_nxt;
|
||||
`else
|
||||
else if (decode) inst_so <= inst_so_nxt;
|
||||
`endif
|
||||
|
||||
//
|
||||
// 6.3) OPCODE: CONDITIONAL JUMP
|
||||
//--------------------------------
|
||||
// Instructions are encoded in a one hot fashion as following:
|
||||
//
|
||||
// 8'b00000001: JNE/JNZ
|
||||
// 8'b00000010: JEQ/JZ
|
||||
// 8'b00000100: JNC/JLO
|
||||
// 8'b00001000: JC/JHS
|
||||
// 8'b00010000: JN
|
||||
// 8'b00100000: JGE
|
||||
// 8'b01000000: JL
|
||||
// 8'b10000000: JMP
|
||||
|
||||
reg [2:0] inst_jmp_bin;
|
||||
always @(posedge mclk_decode or posedge puc_rst)
|
||||
if (puc_rst) inst_jmp_bin <= 3'h0;
|
||||
`ifdef CLOCK_GATING
|
||||
else inst_jmp_bin <= ir[12:10];
|
||||
`else
|
||||
else if (decode) inst_jmp_bin <= ir[12:10];
|
||||
`endif
|
||||
|
||||
wire [7:0] inst_jmp = one_hot8(inst_jmp_bin) & {8{inst_type[`INST_JMP]}};
|
||||
|
||||
|
||||
//
|
||||
// 6.4) OPCODE: TWO-OPERAND ARITHMETIC
|
||||
//-------------------------------------
|
||||
// Instructions are encoded in a one hot fashion as following:
|
||||
//
|
||||
// 12'b000000000001: MOV
|
||||
// 12'b000000000010: ADD
|
||||
// 12'b000000000100: ADDC
|
||||
// 12'b000000001000: SUBC
|
||||
// 12'b000000010000: SUB
|
||||
// 12'b000000100000: CMP
|
||||
// 12'b000001000000: DADD
|
||||
// 12'b000010000000: BIT
|
||||
// 12'b000100000000: BIC
|
||||
// 12'b001000000000: BIS
|
||||
// 12'b010000000000: XOR
|
||||
// 12'b100000000000: AND
|
||||
|
||||
wire [15:0] inst_to_1hot = one_hot16(ir[15:12]) & {16{inst_type_nxt[`INST_TO]}};
|
||||
wire [11:0] inst_to_nxt = inst_to_1hot[15:4];
|
||||
|
||||
reg inst_mov;
|
||||
always @(posedge mclk_decode or posedge puc_rst)
|
||||
if (puc_rst) inst_mov <= 1'b0;
|
||||
`ifdef CLOCK_GATING
|
||||
else inst_mov <= inst_to_nxt[`MOV];
|
||||
`else
|
||||
else if (decode) inst_mov <= inst_to_nxt[`MOV];
|
||||
`endif
|
||||
|
||||
|
||||
//
|
||||
// 6.5) SOURCE AND DESTINATION REGISTERS
|
||||
//---------------------------------------
|
||||
|
||||
// Destination register
|
||||
reg [3:0] inst_dest_bin;
|
||||
always @(posedge mclk_decode or posedge puc_rst)
|
||||
if (puc_rst) inst_dest_bin <= 4'h0;
|
||||
`ifdef CLOCK_GATING
|
||||
else inst_dest_bin <= ir[3:0];
|
||||
`else
|
||||
else if (decode) inst_dest_bin <= ir[3:0];
|
||||
`endif
|
||||
|
||||
wire [15:0] inst_dest = dbg_halt_st ? one_hot16(dbg_reg_sel) :
|
||||
inst_type[`INST_JMP] ? 16'h0001 :
|
||||
inst_so[`IRQ] |
|
||||
inst_so[`PUSH] |
|
||||
inst_so[`CALL] ? 16'h0002 :
|
||||
one_hot16(inst_dest_bin);
|
||||
|
||||
|
||||
// Source register
|
||||
reg [3:0] inst_src_bin;
|
||||
always @(posedge mclk_decode or posedge puc_rst)
|
||||
if (puc_rst) inst_src_bin <= 4'h0;
|
||||
`ifdef CLOCK_GATING
|
||||
else inst_src_bin <= ir[11:8];
|
||||
`else
|
||||
else if (decode) inst_src_bin <= ir[11:8];
|
||||
`endif
|
||||
|
||||
wire [15:0] inst_src = inst_type[`INST_TO] ? one_hot16(inst_src_bin) :
|
||||
inst_so[`RETI] ? 16'h0002 :
|
||||
inst_so[`IRQ] ? 16'h0001 :
|
||||
inst_type[`INST_SO] ? one_hot16(inst_dest_bin) : 16'h0000;
|
||||
|
||||
|
||||
//
|
||||
// 6.6) SOURCE ADDRESSING MODES
|
||||
//--------------------------------
|
||||
// Source addressing modes are encoded in a one hot fashion as following:
|
||||
//
|
||||
// 13'b0000000000001: Register direct.
|
||||
// 13'b0000000000010: Register indexed.
|
||||
// 13'b0000000000100: Register indirect.
|
||||
// 13'b0000000001000: Register indirect autoincrement.
|
||||
// 13'b0000000010000: Symbolic (operand is in memory at address PC+x).
|
||||
// 13'b0000000100000: Immediate (operand is next word in the instruction stream).
|
||||
// 13'b0000001000000: Absolute (operand is in memory at address x).
|
||||
// 13'b0000010000000: Constant 4.
|
||||
// 13'b0000100000000: Constant 8.
|
||||
// 13'b0001000000000: Constant 0.
|
||||
// 13'b0010000000000: Constant 1.
|
||||
// 13'b0100000000000: Constant 2.
|
||||
// 13'b1000000000000: Constant -1.
|
||||
|
||||
reg [12:0] inst_as_nxt;
|
||||
|
||||
wire [3:0] src_reg = inst_type_nxt[`INST_SO] ? ir[3:0] : ir[11:8];
|
||||
|
||||
always @(src_reg or ir or inst_type_nxt)
|
||||
begin
|
||||
if (inst_type_nxt[`INST_JMP])
|
||||
inst_as_nxt = 13'b0000000000001;
|
||||
else if (src_reg==4'h3) // Addressing mode using R3
|
||||
case (ir[5:4])
|
||||
2'b11 : inst_as_nxt = 13'b1000000000000;
|
||||
2'b10 : inst_as_nxt = 13'b0100000000000;
|
||||
2'b01 : inst_as_nxt = 13'b0010000000000;
|
||||
default: inst_as_nxt = 13'b0001000000000;
|
||||
endcase
|
||||
else if (src_reg==4'h2) // Addressing mode using R2
|
||||
case (ir[5:4])
|
||||
2'b11 : inst_as_nxt = 13'b0000100000000;
|
||||
2'b10 : inst_as_nxt = 13'b0000010000000;
|
||||
2'b01 : inst_as_nxt = 13'b0000001000000;
|
||||
default: inst_as_nxt = 13'b0000000000001;
|
||||
endcase
|
||||
else if (src_reg==4'h0) // Addressing mode using R0
|
||||
case (ir[5:4])
|
||||
2'b11 : inst_as_nxt = 13'b0000000100000;
|
||||
2'b10 : inst_as_nxt = 13'b0000000000100;
|
||||
2'b01 : inst_as_nxt = 13'b0000000010000;
|
||||
default: inst_as_nxt = 13'b0000000000001;
|
||||
endcase
|
||||
else // General Addressing mode
|
||||
case (ir[5:4])
|
||||
2'b11 : inst_as_nxt = 13'b0000000001000;
|
||||
2'b10 : inst_as_nxt = 13'b0000000000100;
|
||||
2'b01 : inst_as_nxt = 13'b0000000000010;
|
||||
default: inst_as_nxt = 13'b0000000000001;
|
||||
endcase
|
||||
end
|
||||
assign is_const = |inst_as_nxt[12:7];
|
||||
|
||||
reg [7:0] inst_as;
|
||||
always @(posedge mclk_decode or posedge puc_rst)
|
||||
if (puc_rst) inst_as <= 8'h00;
|
||||
`ifdef CLOCK_GATING
|
||||
else inst_as <= {is_const, inst_as_nxt[6:0]};
|
||||
`else
|
||||
else if (decode) inst_as <= {is_const, inst_as_nxt[6:0]};
|
||||
`endif
|
||||
|
||||
|
||||
// 13'b0000010000000: Constant 4.
|
||||
// 13'b0000100000000: Constant 8.
|
||||
// 13'b0001000000000: Constant 0.
|
||||
// 13'b0010000000000: Constant 1.
|
||||
// 13'b0100000000000: Constant 2.
|
||||
// 13'b1000000000000: Constant -1.
|
||||
always @(inst_as_nxt)
|
||||
begin
|
||||
if (inst_as_nxt[7]) sconst_nxt = 16'h0004;
|
||||
else if (inst_as_nxt[8]) sconst_nxt = 16'h0008;
|
||||
else if (inst_as_nxt[9]) sconst_nxt = 16'h0000;
|
||||
else if (inst_as_nxt[10]) sconst_nxt = 16'h0001;
|
||||
else if (inst_as_nxt[11]) sconst_nxt = 16'h0002;
|
||||
else if (inst_as_nxt[12]) sconst_nxt = 16'hffff;
|
||||
else sconst_nxt = 16'h0000;
|
||||
end
|
||||
|
||||
|
||||
//
|
||||
// 6.7) DESTINATION ADDRESSING MODES
|
||||
//-----------------------------------
|
||||
// Destination addressing modes are encoded in a one hot fashion as following:
|
||||
//
|
||||
// 8'b00000001: Register direct.
|
||||
// 8'b00000010: Register indexed.
|
||||
// 8'b00010000: Symbolic (operand is in memory at address PC+x).
|
||||
// 8'b01000000: Absolute (operand is in memory at address x).
|
||||
|
||||
reg [7:0] inst_ad_nxt;
|
||||
|
||||
wire [3:0] dest_reg = ir[3:0];
|
||||
|
||||
always @(dest_reg or ir or inst_type_nxt)
|
||||
begin
|
||||
if (~inst_type_nxt[`INST_TO])
|
||||
inst_ad_nxt = 8'b00000000;
|
||||
else if (dest_reg==4'h2) // Addressing mode using R2
|
||||
case (ir[7])
|
||||
1'b1 : inst_ad_nxt = 8'b01000000;
|
||||
default: inst_ad_nxt = 8'b00000001;
|
||||
endcase
|
||||
else if (dest_reg==4'h0) // Addressing mode using R0
|
||||
case (ir[7])
|
||||
1'b1 : inst_ad_nxt = 8'b00010000;
|
||||
default: inst_ad_nxt = 8'b00000001;
|
||||
endcase
|
||||
else // General Addressing mode
|
||||
case (ir[7])
|
||||
1'b1 : inst_ad_nxt = 8'b00000010;
|
||||
default: inst_ad_nxt = 8'b00000001;
|
||||
endcase
|
||||
end
|
||||
|
||||
reg [7:0] inst_ad;
|
||||
always @(posedge mclk_decode or posedge puc_rst)
|
||||
if (puc_rst) inst_ad <= 8'h00;
|
||||
`ifdef CLOCK_GATING
|
||||
else inst_ad <= inst_ad_nxt;
|
||||
`else
|
||||
else if (decode) inst_ad <= inst_ad_nxt;
|
||||
`endif
|
||||
|
||||
|
||||
//
|
||||
// 6.8) REMAINING INSTRUCTION DECODING
|
||||
//-------------------------------------
|
||||
|
||||
// Operation size
|
||||
reg inst_bw;
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) inst_bw <= 1'b0;
|
||||
else if (decode) inst_bw <= ir[6] & ~inst_type_nxt[`INST_JMP] & ~irq_detect & ~cpu_halt_cmd;
|
||||
|
||||
// Extended instruction size
|
||||
assign inst_sz_nxt = {1'b0, (inst_as_nxt[`IDX] | inst_as_nxt[`SYMB] | inst_as_nxt[`ABS] | inst_as_nxt[`IMM])} +
|
||||
{1'b0, ((inst_ad_nxt[`IDX] | inst_ad_nxt[`SYMB] | inst_ad_nxt[`ABS]) & ~inst_type_nxt[`INST_SO])};
|
||||
always @(posedge mclk_decode or posedge puc_rst)
|
||||
if (puc_rst) inst_sz <= 2'b00;
|
||||
`ifdef CLOCK_GATING
|
||||
else inst_sz <= inst_sz_nxt;
|
||||
`else
|
||||
else if (decode) inst_sz <= inst_sz_nxt;
|
||||
`endif
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 7) EXECUTION-UNIT STATE MACHINE
|
||||
//=============================================================================
|
||||
|
||||
// State machine registers
|
||||
reg [3:0] e_state;
|
||||
|
||||
|
||||
// State machine control signals
|
||||
//--------------------------------
|
||||
|
||||
wire src_acalc_pre = inst_as_nxt[`IDX] | inst_as_nxt[`SYMB] | inst_as_nxt[`ABS];
|
||||
wire src_rd_pre = inst_as_nxt[`INDIR] | inst_as_nxt[`INDIR_I] | inst_as_nxt[`IMM] | inst_so_nxt[`RETI];
|
||||
wire dst_acalc_pre = inst_ad_nxt[`IDX] | inst_ad_nxt[`SYMB] | inst_ad_nxt[`ABS];
|
||||
wire dst_acalc = inst_ad[`IDX] | inst_ad[`SYMB] | inst_ad[`ABS];
|
||||
wire dst_rd_pre = inst_ad_nxt[`IDX] | inst_so_nxt[`PUSH] | inst_so_nxt[`CALL] | inst_so_nxt[`RETI];
|
||||
wire dst_rd = inst_ad[`IDX] | inst_so[`PUSH] | inst_so[`CALL] | inst_so[`RETI];
|
||||
|
||||
wire inst_branch = (inst_ad_nxt[`DIR] & (ir[3:0]==4'h0)) | inst_type_nxt[`INST_JMP] | inst_so_nxt[`RETI];
|
||||
|
||||
reg exec_jmp;
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) exec_jmp <= 1'b0;
|
||||
else if (inst_branch & decode) exec_jmp <= 1'b1;
|
||||
else if (e_state==E_JUMP) exec_jmp <= 1'b0;
|
||||
|
||||
reg exec_dst_wr;
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) exec_dst_wr <= 1'b0;
|
||||
else if (e_state==E_DST_RD) exec_dst_wr <= 1'b1;
|
||||
else if (e_state==E_DST_WR) exec_dst_wr <= 1'b0;
|
||||
|
||||
reg exec_src_wr;
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) exec_src_wr <= 1'b0;
|
||||
else if (inst_type[`INST_SO] & (e_state==E_SRC_RD)) exec_src_wr <= 1'b1;
|
||||
else if ((e_state==E_SRC_WR) || (e_state==E_DST_WR)) exec_src_wr <= 1'b0;
|
||||
|
||||
reg exec_dext_rdy;
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) exec_dext_rdy <= 1'b0;
|
||||
else if (e_state==E_DST_RD) exec_dext_rdy <= 1'b0;
|
||||
else if (inst_dext_rdy) exec_dext_rdy <= 1'b1;
|
||||
|
||||
// Execution first state
|
||||
wire [3:0] e_first_state = ~dbg_halt_st & inst_so_nxt[`IRQ] ? E_IRQ_0 :
|
||||
cpu_halt_cmd | (i_state==I_IDLE) ? E_IDLE :
|
||||
cpuoff ? E_IDLE :
|
||||
src_acalc_pre ? E_SRC_AD :
|
||||
src_rd_pre ? E_SRC_RD :
|
||||
dst_acalc_pre ? E_DST_AD :
|
||||
dst_rd_pre ? E_DST_RD : E_EXEC;
|
||||
|
||||
|
||||
// State machine
|
||||
//--------------------------------
|
||||
|
||||
// States Transitions
|
||||
always @(e_state or dst_acalc or dst_rd or inst_sext_rdy or
|
||||
inst_dext_rdy or exec_dext_rdy or exec_jmp or exec_dst_wr or
|
||||
e_first_state or exec_src_wr)
|
||||
case(e_state)
|
||||
E_IDLE : e_state_nxt = e_first_state;
|
||||
E_IRQ_0 : e_state_nxt = E_IRQ_1;
|
||||
E_IRQ_1 : e_state_nxt = E_IRQ_2;
|
||||
E_IRQ_2 : e_state_nxt = E_IRQ_3;
|
||||
E_IRQ_3 : e_state_nxt = E_IRQ_4;
|
||||
E_IRQ_4 : e_state_nxt = E_EXEC;
|
||||
|
||||
E_SRC_AD : e_state_nxt = inst_sext_rdy ? E_SRC_RD : E_SRC_AD;
|
||||
|
||||
E_SRC_RD : e_state_nxt = dst_acalc ? E_DST_AD :
|
||||
dst_rd ? E_DST_RD : E_EXEC;
|
||||
|
||||
E_DST_AD : e_state_nxt = (inst_dext_rdy |
|
||||
exec_dext_rdy) ? E_DST_RD : E_DST_AD;
|
||||
|
||||
E_DST_RD : e_state_nxt = E_EXEC;
|
||||
|
||||
E_EXEC : e_state_nxt = exec_dst_wr ? E_DST_WR :
|
||||
exec_jmp ? E_JUMP :
|
||||
exec_src_wr ? E_SRC_WR : e_first_state;
|
||||
|
||||
E_JUMP : e_state_nxt = e_first_state;
|
||||
E_DST_WR : e_state_nxt = exec_jmp ? E_JUMP : e_first_state;
|
||||
E_SRC_WR : e_state_nxt = e_first_state;
|
||||
// pragma coverage off
|
||||
default : e_state_nxt = E_IRQ_0;
|
||||
// pragma coverage on
|
||||
endcase
|
||||
|
||||
// State machine
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) e_state <= E_IRQ_1;
|
||||
else e_state <= e_state_nxt;
|
||||
|
||||
|
||||
// Frontend State machine control signals
|
||||
//----------------------------------------
|
||||
|
||||
wire exec_done = exec_jmp ? (e_state==E_JUMP) :
|
||||
exec_dst_wr ? (e_state==E_DST_WR) :
|
||||
exec_src_wr ? (e_state==E_SRC_WR) : (e_state==E_EXEC);
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 8) EXECUTION-UNIT STATE CONTROL
|
||||
//=============================================================================
|
||||
|
||||
//
|
||||
// 8.1) ALU CONTROL SIGNALS
|
||||
//-------------------------------------
|
||||
//
|
||||
// 12'b000000000001: Enable ALU source inverter
|
||||
// 12'b000000000010: Enable Incrementer
|
||||
// 12'b000000000100: Enable Incrementer on carry bit
|
||||
// 12'b000000001000: Select Adder
|
||||
// 12'b000000010000: Select AND
|
||||
// 12'b000000100000: Select OR
|
||||
// 12'b000001000000: Select XOR
|
||||
// 12'b000010000000: Select DADD
|
||||
// 12'b000100000000: Update N, Z & C (C=~Z)
|
||||
// 12'b001000000000: Update all status bits
|
||||
// 12'b010000000000: Update status bit for XOR instruction
|
||||
// 12'b100000000000: Don't write to destination
|
||||
|
||||
reg [11:0] inst_alu;
|
||||
|
||||
wire alu_src_inv = inst_to_nxt[`SUB] | inst_to_nxt[`SUBC] |
|
||||
inst_to_nxt[`CMP] | inst_to_nxt[`BIC] ;
|
||||
|
||||
wire alu_inc = inst_to_nxt[`SUB] | inst_to_nxt[`CMP];
|
||||
|
||||
wire alu_inc_c = inst_to_nxt[`ADDC] | inst_to_nxt[`DADD] |
|
||||
inst_to_nxt[`SUBC];
|
||||
|
||||
wire alu_add = inst_to_nxt[`ADD] | inst_to_nxt[`ADDC] |
|
||||
inst_to_nxt[`SUB] | inst_to_nxt[`SUBC] |
|
||||
inst_to_nxt[`CMP] | inst_type_nxt[`INST_JMP] |
|
||||
inst_so_nxt[`RETI];
|
||||
|
||||
|
||||
wire alu_and = inst_to_nxt[`AND] | inst_to_nxt[`BIC] |
|
||||
inst_to_nxt[`BIT];
|
||||
|
||||
wire alu_or = inst_to_nxt[`BIS];
|
||||
|
||||
wire alu_xor = inst_to_nxt[`XOR];
|
||||
|
||||
wire alu_dadd = inst_to_nxt[`DADD];
|
||||
|
||||
wire alu_stat_7 = inst_to_nxt[`BIT] | inst_to_nxt[`AND] |
|
||||
inst_so_nxt[`SXT];
|
||||
|
||||
wire alu_stat_f = inst_to_nxt[`ADD] | inst_to_nxt[`ADDC] |
|
||||
inst_to_nxt[`SUB] | inst_to_nxt[`SUBC] |
|
||||
inst_to_nxt[`CMP] | inst_to_nxt[`DADD] |
|
||||
inst_to_nxt[`BIT] | inst_to_nxt[`XOR] |
|
||||
inst_to_nxt[`AND] |
|
||||
inst_so_nxt[`RRC] | inst_so_nxt[`RRA] |
|
||||
inst_so_nxt[`SXT];
|
||||
|
||||
wire alu_shift = inst_so_nxt[`RRC] | inst_so_nxt[`RRA];
|
||||
|
||||
wire exec_no_wr = inst_to_nxt[`CMP] | inst_to_nxt[`BIT];
|
||||
|
||||
wire [11:0] inst_alu_nxt = {exec_no_wr,
|
||||
alu_shift,
|
||||
alu_stat_f,
|
||||
alu_stat_7,
|
||||
alu_dadd,
|
||||
alu_xor,
|
||||
alu_or,
|
||||
alu_and,
|
||||
alu_add,
|
||||
alu_inc_c,
|
||||
alu_inc,
|
||||
alu_src_inv};
|
||||
|
||||
always @(posedge mclk_decode or posedge puc_rst)
|
||||
if (puc_rst) inst_alu <= 12'h000;
|
||||
`ifdef CLOCK_GATING
|
||||
else inst_alu <= inst_alu_nxt;
|
||||
`else
|
||||
else if (decode) inst_alu <= inst_alu_nxt;
|
||||
`endif
|
||||
|
||||
|
||||
endmodule // omsp_frontend
|
||||
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_undefines.v"
|
||||
`endif
|
|
@ -1,275 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_mem_backbone.v
|
||||
//
|
||||
// *Module Description:
|
||||
// Memory interface backbone (decoder + arbiter)
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 151 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2012-07-23 00:24:11 +0200 (Mon, 23 Jul 2012) $
|
||||
//----------------------------------------------------------------------------
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_defines.v"
|
||||
`endif
|
||||
|
||||
module omsp_mem_backbone (
|
||||
|
||||
// OUTPUTs
|
||||
dbg_mem_din, // Debug unit Memory data input
|
||||
dmem_addr, // Data Memory address
|
||||
dmem_cen, // Data Memory chip enable (low active)
|
||||
dmem_din, // Data Memory data input
|
||||
dmem_wen, // Data Memory write enable (low active)
|
||||
eu_mdb_in, // Execution Unit Memory data bus input
|
||||
fe_mdb_in, // Frontend Memory data bus input
|
||||
fe_pmem_wait, // Frontend wait for Instruction fetch
|
||||
per_addr, // Peripheral address
|
||||
per_din, // Peripheral data input
|
||||
per_we, // Peripheral write enable (high active)
|
||||
per_en, // Peripheral enable (high active)
|
||||
pmem_addr, // Program Memory address
|
||||
pmem_cen, // Program Memory chip enable (low active)
|
||||
pmem_din, // Program Memory data input (optional)
|
||||
pmem_wen, // Program Memory write enable (low active) (optional)
|
||||
|
||||
// INPUTs
|
||||
dbg_halt_st, // Halt/Run status from CPU
|
||||
dbg_mem_addr, // Debug address for rd/wr access
|
||||
dbg_mem_dout, // Debug unit data output
|
||||
dbg_mem_en, // Debug unit memory enable
|
||||
dbg_mem_wr, // Debug unit memory write
|
||||
dmem_dout, // Data Memory data output
|
||||
eu_mab, // Execution Unit Memory address bus
|
||||
eu_mb_en, // Execution Unit Memory bus enable
|
||||
eu_mb_wr, // Execution Unit Memory bus write transfer
|
||||
eu_mdb_out, // Execution Unit Memory data bus output
|
||||
fe_mab, // Frontend Memory address bus
|
||||
fe_mb_en, // Frontend Memory bus enable
|
||||
mclk, // Main system clock
|
||||
per_dout, // Peripheral data output
|
||||
pmem_dout, // Program Memory data output
|
||||
puc_rst, // Main system reset
|
||||
scan_enable // Scan enable (active during scan shifting)
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output [15:0] dbg_mem_din; // Debug unit Memory data input
|
||||
output [`DMEM_MSB:0] dmem_addr; // Data Memory address
|
||||
output dmem_cen; // Data Memory chip enable (low active)
|
||||
output [15:0] dmem_din; // Data Memory data input
|
||||
output [1:0] dmem_wen; // Data Memory write enable (low active)
|
||||
output [15:0] eu_mdb_in; // Execution Unit Memory data bus input
|
||||
output [15:0] fe_mdb_in; // Frontend Memory data bus input
|
||||
output fe_pmem_wait; // Frontend wait for Instruction fetch
|
||||
output [13:0] per_addr; // Peripheral address
|
||||
output [15:0] per_din; // Peripheral data input
|
||||
output [1:0] per_we; // Peripheral write enable (high active)
|
||||
output per_en; // Peripheral enable (high active)
|
||||
output [`PMEM_MSB:0] pmem_addr; // Program Memory address
|
||||
output pmem_cen; // Program Memory chip enable (low active)
|
||||
output [15:0] pmem_din; // Program Memory data input (optional)
|
||||
output [1:0] pmem_wen; // Program Memory write enable (low active) (optional)
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input dbg_halt_st; // Halt/Run status from CPU
|
||||
input [15:0] dbg_mem_addr; // Debug address for rd/wr access
|
||||
input [15:0] dbg_mem_dout; // Debug unit data output
|
||||
input dbg_mem_en; // Debug unit memory enable
|
||||
input [1:0] dbg_mem_wr; // Debug unit memory write
|
||||
input [15:0] dmem_dout; // Data Memory data output
|
||||
input [14:0] eu_mab; // Execution Unit Memory address bus
|
||||
input eu_mb_en; // Execution Unit Memory bus enable
|
||||
input [1:0] eu_mb_wr; // Execution Unit Memory bus write transfer
|
||||
input [15:0] eu_mdb_out; // Execution Unit Memory data bus output
|
||||
input [14:0] fe_mab; // Frontend Memory address bus
|
||||
input fe_mb_en; // Frontend Memory bus enable
|
||||
input mclk; // Main system clock
|
||||
input [15:0] per_dout; // Peripheral data output
|
||||
input [15:0] pmem_dout; // Program Memory data output
|
||||
input puc_rst; // Main system reset
|
||||
input scan_enable; // Scan enable (active during scan shifting)
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) DECODER
|
||||
//=============================================================================
|
||||
|
||||
// RAM Interface
|
||||
//------------------
|
||||
|
||||
// Execution unit access
|
||||
wire eu_dmem_cen = ~(eu_mb_en & (eu_mab>=(`DMEM_BASE>>1)) &
|
||||
(eu_mab<((`DMEM_BASE+`DMEM_SIZE)>>1)));
|
||||
wire [15:0] eu_dmem_addr = {1'b0, eu_mab}-(`DMEM_BASE>>1);
|
||||
|
||||
// Debug interface access
|
||||
wire dbg_dmem_cen = ~(dbg_mem_en & (dbg_mem_addr[15:1]>=(`DMEM_BASE>>1)) &
|
||||
(dbg_mem_addr[15:1]<((`DMEM_BASE+`DMEM_SIZE)>>1)));
|
||||
wire [15:0] dbg_dmem_addr = {1'b0, dbg_mem_addr[15:1]}-(`DMEM_BASE>>1);
|
||||
|
||||
|
||||
// RAM Interface
|
||||
wire [`DMEM_MSB:0] dmem_addr = ~dbg_dmem_cen ? dbg_dmem_addr[`DMEM_MSB:0] : eu_dmem_addr[`DMEM_MSB:0];
|
||||
wire dmem_cen = dbg_dmem_cen & eu_dmem_cen;
|
||||
wire [1:0] dmem_wen = ~(dbg_mem_wr | eu_mb_wr);
|
||||
wire [15:0] dmem_din = ~dbg_dmem_cen ? dbg_mem_dout : eu_mdb_out;
|
||||
|
||||
|
||||
// ROM Interface
|
||||
//------------------
|
||||
parameter PMEM_OFFSET = (16'hFFFF-`PMEM_SIZE+1);
|
||||
|
||||
// Execution unit access (only read access are accepted)
|
||||
wire eu_pmem_cen = ~(eu_mb_en & ~|eu_mb_wr & (eu_mab>=(PMEM_OFFSET>>1)));
|
||||
wire [15:0] eu_pmem_addr = eu_mab-(PMEM_OFFSET>>1);
|
||||
|
||||
// Front-end access
|
||||
wire fe_pmem_cen = ~(fe_mb_en & (fe_mab>=(PMEM_OFFSET>>1)));
|
||||
wire [15:0] fe_pmem_addr = fe_mab-(PMEM_OFFSET>>1);
|
||||
|
||||
// Debug interface access
|
||||
wire dbg_pmem_cen = ~(dbg_mem_en & (dbg_mem_addr[15:1]>=(PMEM_OFFSET>>1)));
|
||||
wire [15:0] dbg_pmem_addr = {1'b0, dbg_mem_addr[15:1]}-(PMEM_OFFSET>>1);
|
||||
|
||||
|
||||
// ROM Interface (Execution unit has priority)
|
||||
wire [`PMEM_MSB:0] pmem_addr = ~dbg_pmem_cen ? dbg_pmem_addr[`PMEM_MSB:0] :
|
||||
~eu_pmem_cen ? eu_pmem_addr[`PMEM_MSB:0] : fe_pmem_addr[`PMEM_MSB:0];
|
||||
wire pmem_cen = fe_pmem_cen & eu_pmem_cen & dbg_pmem_cen;
|
||||
wire [1:0] pmem_wen = ~dbg_mem_wr;
|
||||
wire [15:0] pmem_din = dbg_mem_dout;
|
||||
|
||||
wire fe_pmem_wait = (~fe_pmem_cen & ~eu_pmem_cen);
|
||||
|
||||
|
||||
// Peripherals
|
||||
//--------------------
|
||||
wire dbg_per_en = dbg_mem_en & (dbg_mem_addr[15:1]<(`PER_SIZE>>1));
|
||||
wire eu_per_en = eu_mb_en & (eu_mab<(`PER_SIZE>>1));
|
||||
|
||||
wire [15:0] per_din = dbg_mem_en ? dbg_mem_dout : eu_mdb_out;
|
||||
wire [1:0] per_we = dbg_mem_en ? dbg_mem_wr : eu_mb_wr;
|
||||
wire per_en = dbg_mem_en ? dbg_per_en : eu_per_en;
|
||||
wire [`PER_MSB:0] per_addr_mux = dbg_mem_en ? dbg_mem_addr[`PER_MSB+1:1] : eu_mab[`PER_MSB:0];
|
||||
wire [14:0] per_addr_ful = {{15-`PER_AWIDTH{1'b0}}, per_addr_mux};
|
||||
wire [13:0] per_addr = per_addr_ful[13:0];
|
||||
|
||||
reg [15:0] per_dout_val;
|
||||
always @ (posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) per_dout_val <= 16'h0000;
|
||||
else per_dout_val <= per_dout;
|
||||
|
||||
|
||||
// Frontend data Mux
|
||||
//---------------------------------
|
||||
// Whenever the frontend doesn't access the ROM, backup the data
|
||||
|
||||
// Detect whenever the data should be backuped and restored
|
||||
reg fe_pmem_cen_dly;
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) fe_pmem_cen_dly <= 1'b0;
|
||||
else fe_pmem_cen_dly <= fe_pmem_cen;
|
||||
|
||||
wire fe_pmem_save = ( fe_pmem_cen & ~fe_pmem_cen_dly) & ~dbg_halt_st;
|
||||
wire fe_pmem_restore = (~fe_pmem_cen & fe_pmem_cen_dly) | dbg_halt_st;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire mclk_bckup;
|
||||
omsp_clock_gate clock_gate_bckup (.gclk(mclk_bckup),
|
||||
.clk (mclk), .enable(fe_pmem_save), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_bckup = mclk;
|
||||
`endif
|
||||
|
||||
reg [15:0] pmem_dout_bckup;
|
||||
always @(posedge mclk_bckup or posedge puc_rst)
|
||||
if (puc_rst) pmem_dout_bckup <= 16'h0000;
|
||||
`ifdef CLOCK_GATING
|
||||
else pmem_dout_bckup <= pmem_dout;
|
||||
`else
|
||||
else if (fe_pmem_save) pmem_dout_bckup <= pmem_dout;
|
||||
`endif
|
||||
|
||||
// Mux between the ROM data and the backup
|
||||
reg pmem_dout_bckup_sel;
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) pmem_dout_bckup_sel <= 1'b0;
|
||||
else if (fe_pmem_save) pmem_dout_bckup_sel <= 1'b1;
|
||||
else if (fe_pmem_restore) pmem_dout_bckup_sel <= 1'b0;
|
||||
|
||||
assign fe_mdb_in = pmem_dout_bckup_sel ? pmem_dout_bckup : pmem_dout;
|
||||
|
||||
|
||||
// Execution-Unit data Mux
|
||||
//---------------------------------
|
||||
|
||||
// Select between peripherals, RAM and ROM
|
||||
reg [1:0] eu_mdb_in_sel;
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) eu_mdb_in_sel <= 2'b00;
|
||||
else eu_mdb_in_sel <= {~eu_pmem_cen, per_en};
|
||||
|
||||
// Mux
|
||||
assign eu_mdb_in = eu_mdb_in_sel[1] ? pmem_dout :
|
||||
eu_mdb_in_sel[0] ? per_dout_val : dmem_dout;
|
||||
|
||||
// Debug interface data Mux
|
||||
//---------------------------------
|
||||
|
||||
// Select between peripherals, RAM and ROM
|
||||
`ifdef DBG_EN
|
||||
reg [1:0] dbg_mem_din_sel;
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) dbg_mem_din_sel <= 2'b00;
|
||||
else dbg_mem_din_sel <= {~dbg_pmem_cen, dbg_per_en};
|
||||
|
||||
`else
|
||||
wire [1:0] dbg_mem_din_sel = 2'b00;
|
||||
`endif
|
||||
|
||||
// Mux
|
||||
assign dbg_mem_din = dbg_mem_din_sel[1] ? pmem_dout :
|
||||
dbg_mem_din_sel[0] ? per_dout_val : dmem_dout;
|
||||
|
||||
|
||||
endmodule // omsp_mem_backbone
|
||||
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_undefines.v"
|
||||
`endif
|
|
@ -1,420 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_multiplier.v
|
||||
//
|
||||
// *Module Description:
|
||||
// 16x16 Hardware multiplier.
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 23 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2009-08-30 18:39:26 +0200 (Sun, 30 Aug 2009) $
|
||||
//----------------------------------------------------------------------------
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_defines.v"
|
||||
`endif
|
||||
|
||||
module omsp_multiplier (
|
||||
|
||||
// OUTPUTs
|
||||
per_dout, // Peripheral data output
|
||||
|
||||
// INPUTs
|
||||
mclk, // Main system clock
|
||||
per_addr, // Peripheral address
|
||||
per_din, // Peripheral data input
|
||||
per_en, // Peripheral enable (high active)
|
||||
per_we, // Peripheral write enable (high active)
|
||||
puc_rst, // Main system reset
|
||||
scan_enable // Scan enable (active during scan shifting)
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output [15:0] per_dout; // Peripheral data output
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input mclk; // Main system clock
|
||||
input [13:0] per_addr; // Peripheral address
|
||||
input [15:0] per_din; // Peripheral data input
|
||||
input per_en; // Peripheral enable (high active)
|
||||
input [1:0] per_we; // Peripheral write enable (high active)
|
||||
input puc_rst; // Main system reset
|
||||
input scan_enable; // Scan enable (active during scan shifting)
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) PARAMETER/REGISTERS & WIRE DECLARATION
|
||||
//=============================================================================
|
||||
|
||||
// Register base address (must be aligned to decoder bit width)
|
||||
parameter [14:0] BASE_ADDR = 15'h0130;
|
||||
|
||||
// Decoder bit width (defines how many bits are considered for address decoding)
|
||||
parameter DEC_WD = 4;
|
||||
|
||||
// Register addresses offset
|
||||
parameter [DEC_WD-1:0] OP1_MPY = 'h0,
|
||||
OP1_MPYS = 'h2,
|
||||
OP1_MAC = 'h4,
|
||||
OP1_MACS = 'h6,
|
||||
OP2 = 'h8,
|
||||
RESLO = 'hA,
|
||||
RESHI = 'hC,
|
||||
SUMEXT = 'hE;
|
||||
|
||||
// Register one-hot decoder utilities
|
||||
parameter DEC_SZ = (1 << DEC_WD);
|
||||
parameter [DEC_SZ-1:0] BASE_REG = {{DEC_SZ-1{1'b0}}, 1'b1};
|
||||
|
||||
// Register one-hot decoder
|
||||
parameter [DEC_SZ-1:0] OP1_MPY_D = (BASE_REG << OP1_MPY),
|
||||
OP1_MPYS_D = (BASE_REG << OP1_MPYS),
|
||||
OP1_MAC_D = (BASE_REG << OP1_MAC),
|
||||
OP1_MACS_D = (BASE_REG << OP1_MACS),
|
||||
OP2_D = (BASE_REG << OP2),
|
||||
RESLO_D = (BASE_REG << RESLO),
|
||||
RESHI_D = (BASE_REG << RESHI),
|
||||
SUMEXT_D = (BASE_REG << SUMEXT);
|
||||
|
||||
|
||||
// Wire pre-declarations
|
||||
wire result_wr;
|
||||
wire result_clr;
|
||||
wire early_read;
|
||||
|
||||
|
||||
//============================================================================
|
||||
// 2) REGISTER DECODER
|
||||
//============================================================================
|
||||
|
||||
// Local register selection
|
||||
wire reg_sel = per_en & (per_addr[13:DEC_WD-1]==BASE_ADDR[14:DEC_WD]);
|
||||
|
||||
// Register local address
|
||||
wire [DEC_WD-1:0] reg_addr = {per_addr[DEC_WD-2:0], 1'b0};
|
||||
|
||||
// Register address decode
|
||||
wire [DEC_SZ-1:0] reg_dec = (OP1_MPY_D & {DEC_SZ{(reg_addr == OP1_MPY )}}) |
|
||||
(OP1_MPYS_D & {DEC_SZ{(reg_addr == OP1_MPYS )}}) |
|
||||
(OP1_MAC_D & {DEC_SZ{(reg_addr == OP1_MAC )}}) |
|
||||
(OP1_MACS_D & {DEC_SZ{(reg_addr == OP1_MACS )}}) |
|
||||
(OP2_D & {DEC_SZ{(reg_addr == OP2 )}}) |
|
||||
(RESLO_D & {DEC_SZ{(reg_addr == RESLO )}}) |
|
||||
(RESHI_D & {DEC_SZ{(reg_addr == RESHI )}}) |
|
||||
(SUMEXT_D & {DEC_SZ{(reg_addr == SUMEXT )}});
|
||||
|
||||
// Read/Write probes
|
||||
wire reg_write = |per_we & reg_sel;
|
||||
wire reg_read = ~|per_we & reg_sel;
|
||||
|
||||
// Read/Write vectors
|
||||
wire [DEC_SZ-1:0] reg_wr = reg_dec & {DEC_SZ{reg_write}};
|
||||
wire [DEC_SZ-1:0] reg_rd = reg_dec & {DEC_SZ{reg_read}};
|
||||
|
||||
|
||||
//============================================================================
|
||||
// 3) REGISTERS
|
||||
//============================================================================
|
||||
|
||||
// OP1 Register
|
||||
//-----------------
|
||||
reg [15:0] op1;
|
||||
|
||||
wire op1_wr = reg_wr[OP1_MPY] |
|
||||
reg_wr[OP1_MPYS] |
|
||||
reg_wr[OP1_MAC] |
|
||||
reg_wr[OP1_MACS];
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire mclk_op1;
|
||||
omsp_clock_gate clock_gate_op1 (.gclk(mclk_op1),
|
||||
.clk (mclk), .enable(op1_wr), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_op1 = mclk;
|
||||
`endif
|
||||
|
||||
always @ (posedge mclk_op1 or posedge puc_rst)
|
||||
if (puc_rst) op1 <= 16'h0000;
|
||||
`ifdef CLOCK_GATING
|
||||
else op1 <= per_din;
|
||||
`else
|
||||
else if (op1_wr) op1 <= per_din;
|
||||
`endif
|
||||
|
||||
wire [15:0] op1_rd = op1;
|
||||
|
||||
|
||||
// OP2 Register
|
||||
//-----------------
|
||||
reg [15:0] op2;
|
||||
|
||||
wire op2_wr = reg_wr[OP2];
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire mclk_op2;
|
||||
omsp_clock_gate clock_gate_op2 (.gclk(mclk_op2),
|
||||
.clk (mclk), .enable(op2_wr), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_op2 = mclk;
|
||||
`endif
|
||||
|
||||
always @ (posedge mclk_op2 or posedge puc_rst)
|
||||
if (puc_rst) op2 <= 16'h0000;
|
||||
`ifdef CLOCK_GATING
|
||||
else op2 <= per_din;
|
||||
`else
|
||||
else if (op2_wr) op2 <= per_din;
|
||||
`endif
|
||||
|
||||
wire [15:0] op2_rd = op2;
|
||||
|
||||
|
||||
// RESLO Register
|
||||
//-----------------
|
||||
reg [15:0] reslo;
|
||||
|
||||
wire [15:0] reslo_nxt;
|
||||
wire reslo_wr = reg_wr[RESLO];
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire reslo_en = reslo_wr | result_clr | result_wr;
|
||||
wire mclk_reslo;
|
||||
omsp_clock_gate clock_gate_reslo (.gclk(mclk_reslo),
|
||||
.clk (mclk), .enable(reslo_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_reslo = mclk;
|
||||
`endif
|
||||
|
||||
always @ (posedge mclk_reslo or posedge puc_rst)
|
||||
if (puc_rst) reslo <= 16'h0000;
|
||||
else if (reslo_wr) reslo <= per_din;
|
||||
else if (result_clr) reslo <= 16'h0000;
|
||||
`ifdef CLOCK_GATING
|
||||
else reslo <= reslo_nxt;
|
||||
`else
|
||||
else if (result_wr) reslo <= reslo_nxt;
|
||||
`endif
|
||||
|
||||
wire [15:0] reslo_rd = early_read ? reslo_nxt : reslo;
|
||||
|
||||
|
||||
// RESHI Register
|
||||
//-----------------
|
||||
reg [15:0] reshi;
|
||||
|
||||
wire [15:0] reshi_nxt;
|
||||
wire reshi_wr = reg_wr[RESHI];
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire reshi_en = reshi_wr | result_clr | result_wr;
|
||||
wire mclk_reshi;
|
||||
omsp_clock_gate clock_gate_reshi (.gclk(mclk_reshi),
|
||||
.clk (mclk), .enable(reshi_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_reshi = mclk;
|
||||
`endif
|
||||
|
||||
always @ (posedge mclk_reshi or posedge puc_rst)
|
||||
if (puc_rst) reshi <= 16'h0000;
|
||||
else if (reshi_wr) reshi <= per_din;
|
||||
else if (result_clr) reshi <= 16'h0000;
|
||||
`ifdef CLOCK_GATING
|
||||
else reshi <= reshi_nxt;
|
||||
`else
|
||||
else if (result_wr) reshi <= reshi_nxt;
|
||||
`endif
|
||||
|
||||
wire [15:0] reshi_rd = early_read ? reshi_nxt : reshi;
|
||||
|
||||
|
||||
// SUMEXT Register
|
||||
//-----------------
|
||||
reg [1:0] sumext_s;
|
||||
|
||||
wire [1:0] sumext_s_nxt;
|
||||
|
||||
always @ (posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) sumext_s <= 2'b00;
|
||||
else if (op2_wr) sumext_s <= 2'b00;
|
||||
else if (result_wr) sumext_s <= sumext_s_nxt;
|
||||
|
||||
wire [15:0] sumext_nxt = {{14{sumext_s_nxt[1]}}, sumext_s_nxt};
|
||||
wire [15:0] sumext = {{14{sumext_s[1]}}, sumext_s};
|
||||
wire [15:0] sumext_rd = early_read ? sumext_nxt : sumext;
|
||||
|
||||
|
||||
//============================================================================
|
||||
// 4) DATA OUTPUT GENERATION
|
||||
//============================================================================
|
||||
|
||||
// Data output mux
|
||||
wire [15:0] op1_mux = op1_rd & {16{reg_rd[OP1_MPY] |
|
||||
reg_rd[OP1_MPYS] |
|
||||
reg_rd[OP1_MAC] |
|
||||
reg_rd[OP1_MACS]}};
|
||||
wire [15:0] op2_mux = op2_rd & {16{reg_rd[OP2]}};
|
||||
wire [15:0] reslo_mux = reslo_rd & {16{reg_rd[RESLO]}};
|
||||
wire [15:0] reshi_mux = reshi_rd & {16{reg_rd[RESHI]}};
|
||||
wire [15:0] sumext_mux = sumext_rd & {16{reg_rd[SUMEXT]}};
|
||||
|
||||
wire [15:0] per_dout = op1_mux |
|
||||
op2_mux |
|
||||
reslo_mux |
|
||||
reshi_mux |
|
||||
sumext_mux;
|
||||
|
||||
|
||||
//============================================================================
|
||||
// 5) HARDWARE MULTIPLIER FUNCTIONAL LOGIC
|
||||
//============================================================================
|
||||
|
||||
// Multiplier configuration
|
||||
//--------------------------
|
||||
|
||||
// Detect signed mode
|
||||
reg sign_sel;
|
||||
always @ (posedge mclk_op1 or posedge puc_rst)
|
||||
if (puc_rst) sign_sel <= 1'b0;
|
||||
`ifdef CLOCK_GATING
|
||||
else sign_sel <= reg_wr[OP1_MPYS] | reg_wr[OP1_MACS];
|
||||
`else
|
||||
else if (op1_wr) sign_sel <= reg_wr[OP1_MPYS] | reg_wr[OP1_MACS];
|
||||
`endif
|
||||
|
||||
|
||||
// Detect accumulate mode
|
||||
reg acc_sel;
|
||||
always @ (posedge mclk_op1 or posedge puc_rst)
|
||||
if (puc_rst) acc_sel <= 1'b0;
|
||||
`ifdef CLOCK_GATING
|
||||
else acc_sel <= reg_wr[OP1_MAC] | reg_wr[OP1_MACS];
|
||||
`else
|
||||
else if (op1_wr) acc_sel <= reg_wr[OP1_MAC] | reg_wr[OP1_MACS];
|
||||
`endif
|
||||
|
||||
|
||||
// Detect whenever the RESHI and RESLO registers should be cleared
|
||||
assign result_clr = op2_wr & ~acc_sel;
|
||||
|
||||
// Combine RESHI & RESLO
|
||||
wire [31:0] result = {reshi, reslo};
|
||||
|
||||
|
||||
// 16x16 Multiplier (result computed in 1 clock cycle)
|
||||
//-----------------------------------------------------
|
||||
`ifdef MPY_16x16
|
||||
|
||||
// Detect start of a multiplication
|
||||
reg cycle;
|
||||
always @ (posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) cycle <= 1'b0;
|
||||
else cycle <= op2_wr;
|
||||
|
||||
assign result_wr = cycle;
|
||||
|
||||
// Expand the operands to support signed & unsigned operations
|
||||
wire signed [16:0] op1_xp = {sign_sel & op1[15], op1};
|
||||
wire signed [16:0] op2_xp = {sign_sel & op2[15], op2};
|
||||
|
||||
|
||||
// 17x17 signed multiplication
|
||||
wire signed [33:0] product = op1_xp * op2_xp;
|
||||
|
||||
// Accumulate
|
||||
wire [32:0] result_nxt = {1'b0, result} + {1'b0, product[31:0]};
|
||||
|
||||
|
||||
// Next register values
|
||||
assign reslo_nxt = result_nxt[15:0];
|
||||
assign reshi_nxt = result_nxt[31:16];
|
||||
assign sumext_s_nxt = sign_sel ? {2{result_nxt[31]}} :
|
||||
{1'b0, result_nxt[32]};
|
||||
|
||||
|
||||
// Since the MAC is completed within 1 clock cycle,
|
||||
// an early read can't happen.
|
||||
assign early_read = 1'b0;
|
||||
|
||||
|
||||
// 16x8 Multiplier (result computed in 2 clock cycles)
|
||||
//-----------------------------------------------------
|
||||
`else
|
||||
|
||||
// Detect start of a multiplication
|
||||
reg [1:0] cycle;
|
||||
always @ (posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) cycle <= 2'b00;
|
||||
else cycle <= {cycle[0], op2_wr};
|
||||
|
||||
assign result_wr = |cycle;
|
||||
|
||||
|
||||
// Expand the operands to support signed & unsigned operations
|
||||
wire signed [16:0] op1_xp = {sign_sel & op1[15], op1};
|
||||
wire signed [8:0] op2_hi_xp = {sign_sel & op2[15], op2[15:8]};
|
||||
wire signed [8:0] op2_lo_xp = { 1'b0, op2[7:0]};
|
||||
wire signed [8:0] op2_xp = cycle[0] ? op2_hi_xp : op2_lo_xp;
|
||||
|
||||
|
||||
// 17x9 signed multiplication
|
||||
wire signed [25:0] product = op1_xp * op2_xp;
|
||||
|
||||
wire [31:0] product_xp = cycle[0] ? {product[23:0], 8'h00} :
|
||||
{{8{sign_sel & product[23]}}, product[23:0]};
|
||||
|
||||
// Accumulate
|
||||
wire [32:0] result_nxt = {1'b0, result} + {1'b0, product_xp[31:0]};
|
||||
|
||||
|
||||
// Next register values
|
||||
assign reslo_nxt = result_nxt[15:0];
|
||||
assign reshi_nxt = result_nxt[31:16];
|
||||
assign sumext_s_nxt = sign_sel ? {2{result_nxt[31]}} :
|
||||
{1'b0, result_nxt[32] | sumext_s[0]};
|
||||
|
||||
// Since the MAC is completed within 2 clock cycle,
|
||||
// an early read can happen during the second cycle.
|
||||
assign early_read = cycle[1];
|
||||
|
||||
`endif
|
||||
|
||||
|
||||
endmodule // omsp_multiplier
|
||||
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_undefines.v"
|
||||
`endif
|
|
@ -1,618 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_register_file.v
|
||||
//
|
||||
// *Module Description:
|
||||
// openMSP430 Register files
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 134 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
|
||||
//----------------------------------------------------------------------------
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_defines.v"
|
||||
`endif
|
||||
|
||||
module omsp_register_file (
|
||||
|
||||
// OUTPUTs
|
||||
cpuoff, // Turns off the CPU
|
||||
gie, // General interrupt enable
|
||||
oscoff, // Turns off LFXT1 clock input
|
||||
pc_sw, // Program counter software value
|
||||
pc_sw_wr, // Program counter software write
|
||||
reg_dest, // Selected register destination content
|
||||
reg_src, // Selected register source content
|
||||
scg0, // System clock generator 1. Turns off the DCO
|
||||
scg1, // System clock generator 1. Turns off the SMCLK
|
||||
status, // R2 Status {V,N,Z,C}
|
||||
|
||||
// INPUTs
|
||||
alu_stat, // ALU Status {V,N,Z,C}
|
||||
alu_stat_wr, // ALU Status write {V,N,Z,C}
|
||||
inst_bw, // Decoded Inst: byte width
|
||||
inst_dest, // Register destination selection
|
||||
inst_src, // Register source selection
|
||||
mclk, // Main system clock
|
||||
pc, // Program counter
|
||||
puc_rst, // Main system reset
|
||||
reg_dest_val, // Selected register destination value
|
||||
reg_dest_wr, // Write selected register destination
|
||||
reg_pc_call, // Trigger PC update for a CALL instruction
|
||||
reg_sp_val, // Stack Pointer next value
|
||||
reg_sp_wr, // Stack Pointer write
|
||||
reg_sr_wr, // Status register update for RETI instruction
|
||||
reg_sr_clr, // Status register clear for interrupts
|
||||
reg_incr, // Increment source register
|
||||
scan_enable // Scan enable (active during scan shifting)
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output cpuoff; // Turns off the CPU
|
||||
output gie; // General interrupt enable
|
||||
output oscoff; // Turns off LFXT1 clock input
|
||||
output [15:0] pc_sw; // Program counter software value
|
||||
output pc_sw_wr; // Program counter software write
|
||||
output [15:0] reg_dest; // Selected register destination content
|
||||
output [15:0] reg_src; // Selected register source content
|
||||
output scg0; // System clock generator 1. Turns off the DCO
|
||||
output scg1; // System clock generator 1. Turns off the SMCLK
|
||||
output [3:0] status; // R2 Status {V,N,Z,C}
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input [3:0] alu_stat; // ALU Status {V,N,Z,C}
|
||||
input [3:0] alu_stat_wr; // ALU Status write {V,N,Z,C}
|
||||
input inst_bw; // Decoded Inst: byte width
|
||||
input [15:0] inst_dest; // Register destination selection
|
||||
input [15:0] inst_src; // Register source selection
|
||||
input mclk; // Main system clock
|
||||
input [15:0] pc; // Program counter
|
||||
input puc_rst; // Main system reset
|
||||
input [15:0] reg_dest_val; // Selected register destination value
|
||||
input reg_dest_wr; // Write selected register destination
|
||||
input reg_pc_call; // Trigger PC update for a CALL instruction
|
||||
input [15:0] reg_sp_val; // Stack Pointer next value
|
||||
input reg_sp_wr; // Stack Pointer write
|
||||
input reg_sr_wr; // Status register update for RETI instruction
|
||||
input reg_sr_clr; // Status register clear for interrupts
|
||||
input reg_incr; // Increment source register
|
||||
input scan_enable; // Scan enable (active during scan shifting)
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) AUTOINCREMENT UNIT
|
||||
//=============================================================================
|
||||
|
||||
wire [15:0] inst_src_in;
|
||||
wire [15:0] incr_op = (inst_bw & ~inst_src_in[1]) ? 16'h0001 : 16'h0002;
|
||||
wire [15:0] reg_incr_val = reg_src+incr_op;
|
||||
|
||||
wire [15:0] reg_dest_val_in = inst_bw ? {8'h00,reg_dest_val[7:0]} : reg_dest_val;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 2) SPECIAL REGISTERS (R1/R2/R3)
|
||||
//=============================================================================
|
||||
|
||||
// Source input selection mask (for interrupt support)
|
||||
//-----------------------------------------------------
|
||||
|
||||
assign inst_src_in = reg_sr_clr ? 16'h0004 : inst_src;
|
||||
|
||||
|
||||
// R0: Program counter
|
||||
//---------------------
|
||||
|
||||
wire [15:0] r0 = pc;
|
||||
|
||||
wire [15:0] pc_sw = reg_dest_val_in;
|
||||
wire pc_sw_wr = (inst_dest[0] & reg_dest_wr) | reg_pc_call;
|
||||
|
||||
|
||||
// R1: Stack pointer
|
||||
//-------------------
|
||||
reg [15:0] r1;
|
||||
wire r1_wr = inst_dest[1] & reg_dest_wr;
|
||||
wire r1_inc = inst_src_in[1] & reg_incr;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire r1_en = r1_wr | reg_sp_wr | r1_inc;
|
||||
wire mclk_r1;
|
||||
omsp_clock_gate clock_gate_r1 (.gclk(mclk_r1),
|
||||
.clk (mclk), .enable(r1_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_r1 = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_r1 or posedge puc_rst)
|
||||
if (puc_rst) r1 <= 16'h0000;
|
||||
else if (r1_wr) r1 <= reg_dest_val_in & 16'hfffe;
|
||||
else if (reg_sp_wr) r1 <= reg_sp_val & 16'hfffe;
|
||||
`ifdef CLOCK_GATING
|
||||
else r1 <= reg_incr_val & 16'hfffe;
|
||||
`else
|
||||
else if (r1_inc) r1 <= reg_incr_val & 16'hfffe;
|
||||
`endif
|
||||
|
||||
|
||||
// R2: Status register
|
||||
//---------------------
|
||||
reg [15:0] r2;
|
||||
wire r2_wr = (inst_dest[2] & reg_dest_wr) | reg_sr_wr;
|
||||
|
||||
`ifdef CLOCK_GATING // -- WITH CLOCK GATING --
|
||||
wire r2_c = alu_stat_wr[0] ? alu_stat[0] : reg_dest_val_in[0]; // C
|
||||
|
||||
wire r2_z = alu_stat_wr[1] ? alu_stat[1] : reg_dest_val_in[1]; // Z
|
||||
|
||||
wire r2_n = alu_stat_wr[2] ? alu_stat[2] : reg_dest_val_in[2]; // N
|
||||
|
||||
wire [7:3] r2_nxt = r2_wr ? reg_dest_val_in[7:3] : r2[7:3];
|
||||
|
||||
wire r2_v = alu_stat_wr[3] ? alu_stat[3] : reg_dest_val_in[8]; // V
|
||||
|
||||
wire r2_en = |alu_stat_wr | r2_wr | reg_sr_clr;
|
||||
wire mclk_r2;
|
||||
omsp_clock_gate clock_gate_r2 (.gclk(mclk_r2),
|
||||
.clk (mclk), .enable(r2_en), .scan_enable(scan_enable));
|
||||
|
||||
`else // -- WITHOUT CLOCK GATING --
|
||||
wire r2_c = alu_stat_wr[0] ? alu_stat[0] :
|
||||
r2_wr ? reg_dest_val_in[0] : r2[0]; // C
|
||||
|
||||
wire r2_z = alu_stat_wr[1] ? alu_stat[1] :
|
||||
r2_wr ? reg_dest_val_in[1] : r2[1]; // Z
|
||||
|
||||
wire r2_n = alu_stat_wr[2] ? alu_stat[2] :
|
||||
r2_wr ? reg_dest_val_in[2] : r2[2]; // N
|
||||
|
||||
wire [7:3] r2_nxt = r2_wr ? reg_dest_val_in[7:3] : r2[7:3];
|
||||
|
||||
wire r2_v = alu_stat_wr[3] ? alu_stat[3] :
|
||||
r2_wr ? reg_dest_val_in[8] : r2[8]; // V
|
||||
|
||||
|
||||
wire mclk_r2 = mclk;
|
||||
`endif
|
||||
|
||||
`ifdef ASIC
|
||||
`ifdef CPUOFF_EN
|
||||
wire [15:0] cpuoff_mask = 16'h0010;
|
||||
`else
|
||||
wire [15:0] cpuoff_mask = 16'h0000;
|
||||
`endif
|
||||
`ifdef OSCOFF_EN
|
||||
wire [15:0] oscoff_mask = 16'h0020;
|
||||
`else
|
||||
wire [15:0] oscoff_mask = 16'h0000;
|
||||
`endif
|
||||
`ifdef SCG0_EN
|
||||
wire [15:0] scg0_mask = 16'h0040;
|
||||
`else
|
||||
wire [15:0] scg0_mask = 16'h0000;
|
||||
`endif
|
||||
`ifdef SCG1_EN
|
||||
wire [15:0] scg1_mask = 16'h0080;
|
||||
`else
|
||||
wire [15:0] scg1_mask = 16'h0000;
|
||||
`endif
|
||||
`else
|
||||
wire [15:0] cpuoff_mask = 16'h0010; // For the FPGA version: - the CPUOFF mode is emulated
|
||||
wire [15:0] oscoff_mask = 16'h0020; // - the SCG1 mode is emulated
|
||||
wire [15:0] scg0_mask = 16'h0000; // - the SCG0 is not supported
|
||||
wire [15:0] scg1_mask = 16'h0080; // - the SCG1 mode is emulated
|
||||
`endif
|
||||
|
||||
wire [15:0] r2_mask = cpuoff_mask | oscoff_mask | scg0_mask | scg1_mask | 16'h010f;
|
||||
|
||||
always @(posedge mclk_r2 or posedge puc_rst)
|
||||
if (puc_rst) r2 <= 16'h0000;
|
||||
else if (reg_sr_clr) r2 <= 16'h0000;
|
||||
else r2 <= {7'h00, r2_v, r2_nxt, r2_n, r2_z, r2_c} & r2_mask;
|
||||
|
||||
assign status = {r2[8], r2[2:0]};
|
||||
assign gie = r2[3];
|
||||
assign cpuoff = r2[4] | (r2_nxt[4] & r2_wr & cpuoff_mask[4]);
|
||||
assign oscoff = r2[5];
|
||||
assign scg0 = r2[6];
|
||||
assign scg1 = r2[7];
|
||||
|
||||
|
||||
// R3: Constant generator
|
||||
//-------------------------------------------------------------
|
||||
// Note: the auto-increment feature is not implemented for R3
|
||||
// because the @R3+ addressing mode is used for constant
|
||||
// generation (#-1).
|
||||
reg [15:0] r3;
|
||||
wire r3_wr = inst_dest[3] & reg_dest_wr;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire r3_en = r3_wr;
|
||||
wire mclk_r3;
|
||||
omsp_clock_gate clock_gate_r3 (.gclk(mclk_r3),
|
||||
.clk (mclk), .enable(r3_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_r3 = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_r3 or posedge puc_rst)
|
||||
if (puc_rst) r3 <= 16'h0000;
|
||||
`ifdef CLOCK_GATING
|
||||
else r3 <= reg_dest_val_in;
|
||||
`else
|
||||
else if (r3_wr) r3 <= reg_dest_val_in;
|
||||
`endif
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 4) GENERAL PURPOSE REGISTERS (R4...R15)
|
||||
//=============================================================================
|
||||
|
||||
// R4
|
||||
//------------
|
||||
reg [15:0] r4;
|
||||
wire r4_wr = inst_dest[4] & reg_dest_wr;
|
||||
wire r4_inc = inst_src_in[4] & reg_incr;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire r4_en = r4_wr | r4_inc;
|
||||
wire mclk_r4;
|
||||
omsp_clock_gate clock_gate_r4 (.gclk(mclk_r4),
|
||||
.clk (mclk), .enable(r4_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_r4 = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_r4 or posedge puc_rst)
|
||||
if (puc_rst) r4 <= 16'h0000;
|
||||
else if (r4_wr) r4 <= reg_dest_val_in;
|
||||
`ifdef CLOCK_GATING
|
||||
else r4 <= reg_incr_val;
|
||||
`else
|
||||
else if (r4_inc) r4 <= reg_incr_val;
|
||||
`endif
|
||||
|
||||
// R5
|
||||
//------------
|
||||
reg [15:0] r5;
|
||||
wire r5_wr = inst_dest[5] & reg_dest_wr;
|
||||
wire r5_inc = inst_src_in[5] & reg_incr;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire r5_en = r5_wr | r5_inc;
|
||||
wire mclk_r5;
|
||||
omsp_clock_gate clock_gate_r5 (.gclk(mclk_r5),
|
||||
.clk (mclk), .enable(r5_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_r5 = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_r5 or posedge puc_rst)
|
||||
if (puc_rst) r5 <= 16'h0000;
|
||||
else if (r5_wr) r5 <= reg_dest_val_in;
|
||||
`ifdef CLOCK_GATING
|
||||
else r5 <= reg_incr_val;
|
||||
`else
|
||||
else if (r5_inc) r5 <= reg_incr_val;
|
||||
`endif
|
||||
|
||||
// R6
|
||||
//------------
|
||||
reg [15:0] r6;
|
||||
wire r6_wr = inst_dest[6] & reg_dest_wr;
|
||||
wire r6_inc = inst_src_in[6] & reg_incr;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire r6_en = r6_wr | r6_inc;
|
||||
wire mclk_r6;
|
||||
omsp_clock_gate clock_gate_r6 (.gclk(mclk_r6),
|
||||
.clk (mclk), .enable(r6_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_r6 = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_r6 or posedge puc_rst)
|
||||
if (puc_rst) r6 <= 16'h0000;
|
||||
else if (r6_wr) r6 <= reg_dest_val_in;
|
||||
`ifdef CLOCK_GATING
|
||||
else r6 <= reg_incr_val;
|
||||
`else
|
||||
else if (r6_inc) r6 <= reg_incr_val;
|
||||
`endif
|
||||
|
||||
// R7
|
||||
//------------
|
||||
reg [15:0] r7;
|
||||
wire r7_wr = inst_dest[7] & reg_dest_wr;
|
||||
wire r7_inc = inst_src_in[7] & reg_incr;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire r7_en = r7_wr | r7_inc;
|
||||
wire mclk_r7;
|
||||
omsp_clock_gate clock_gate_r7 (.gclk(mclk_r7),
|
||||
.clk (mclk), .enable(r7_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_r7 = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_r7 or posedge puc_rst)
|
||||
if (puc_rst) r7 <= 16'h0000;
|
||||
else if (r7_wr) r7 <= reg_dest_val_in;
|
||||
`ifdef CLOCK_GATING
|
||||
else r7 <= reg_incr_val;
|
||||
`else
|
||||
else if (r7_inc) r7 <= reg_incr_val;
|
||||
`endif
|
||||
|
||||
// R8
|
||||
//------------
|
||||
reg [15:0] r8;
|
||||
wire r8_wr = inst_dest[8] & reg_dest_wr;
|
||||
wire r8_inc = inst_src_in[8] & reg_incr;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire r8_en = r8_wr | r8_inc;
|
||||
wire mclk_r8;
|
||||
omsp_clock_gate clock_gate_r8 (.gclk(mclk_r8),
|
||||
.clk (mclk), .enable(r8_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_r8 = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_r8 or posedge puc_rst)
|
||||
if (puc_rst) r8 <= 16'h0000;
|
||||
else if (r8_wr) r8 <= reg_dest_val_in;
|
||||
`ifdef CLOCK_GATING
|
||||
else r8 <= reg_incr_val;
|
||||
`else
|
||||
else if (r8_inc) r8 <= reg_incr_val;
|
||||
`endif
|
||||
|
||||
// R9
|
||||
//------------
|
||||
reg [15:0] r9;
|
||||
wire r9_wr = inst_dest[9] & reg_dest_wr;
|
||||
wire r9_inc = inst_src_in[9] & reg_incr;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire r9_en = r9_wr | r9_inc;
|
||||
wire mclk_r9;
|
||||
omsp_clock_gate clock_gate_r9 (.gclk(mclk_r9),
|
||||
.clk (mclk), .enable(r9_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_r9 = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_r9 or posedge puc_rst)
|
||||
if (puc_rst) r9 <= 16'h0000;
|
||||
else if (r9_wr) r9 <= reg_dest_val_in;
|
||||
`ifdef CLOCK_GATING
|
||||
else r9 <= reg_incr_val;
|
||||
`else
|
||||
else if (r9_inc) r9 <= reg_incr_val;
|
||||
`endif
|
||||
|
||||
// R10
|
||||
//------------
|
||||
reg [15:0] r10;
|
||||
wire r10_wr = inst_dest[10] & reg_dest_wr;
|
||||
wire r10_inc = inst_src_in[10] & reg_incr;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire r10_en = r10_wr | r10_inc;
|
||||
wire mclk_r10;
|
||||
omsp_clock_gate clock_gate_r10 (.gclk(mclk_r10),
|
||||
.clk (mclk), .enable(r10_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_r10 = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_r10 or posedge puc_rst)
|
||||
if (puc_rst) r10 <= 16'h0000;
|
||||
else if (r10_wr) r10 <= reg_dest_val_in;
|
||||
`ifdef CLOCK_GATING
|
||||
else r10 <= reg_incr_val;
|
||||
`else
|
||||
else if (r10_inc) r10 <= reg_incr_val;
|
||||
`endif
|
||||
|
||||
// R11
|
||||
//------------
|
||||
reg [15:0] r11;
|
||||
wire r11_wr = inst_dest[11] & reg_dest_wr;
|
||||
wire r11_inc = inst_src_in[11] & reg_incr;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire r11_en = r11_wr | r11_inc;
|
||||
wire mclk_r11;
|
||||
omsp_clock_gate clock_gate_r11 (.gclk(mclk_r11),
|
||||
.clk (mclk), .enable(r11_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_r11 = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_r11 or posedge puc_rst)
|
||||
if (puc_rst) r11 <= 16'h0000;
|
||||
else if (r11_wr) r11 <= reg_dest_val_in;
|
||||
`ifdef CLOCK_GATING
|
||||
else r11 <= reg_incr_val;
|
||||
`else
|
||||
else if (r11_inc) r11 <= reg_incr_val;
|
||||
`endif
|
||||
|
||||
// R12
|
||||
//------------
|
||||
reg [15:0] r12;
|
||||
wire r12_wr = inst_dest[12] & reg_dest_wr;
|
||||
wire r12_inc = inst_src_in[12] & reg_incr;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire r12_en = r12_wr | r12_inc;
|
||||
wire mclk_r12;
|
||||
omsp_clock_gate clock_gate_r12 (.gclk(mclk_r12),
|
||||
.clk (mclk), .enable(r12_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_r12 = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_r12 or posedge puc_rst)
|
||||
if (puc_rst) r12 <= 16'h0000;
|
||||
else if (r12_wr) r12 <= reg_dest_val_in;
|
||||
`ifdef CLOCK_GATING
|
||||
else r12 <= reg_incr_val;
|
||||
`else
|
||||
else if (r12_inc) r12 <= reg_incr_val;
|
||||
`endif
|
||||
|
||||
// R13
|
||||
//------------
|
||||
reg [15:0] r13;
|
||||
wire r13_wr = inst_dest[13] & reg_dest_wr;
|
||||
wire r13_inc = inst_src_in[13] & reg_incr;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire r13_en = r13_wr | r13_inc;
|
||||
wire mclk_r13;
|
||||
omsp_clock_gate clock_gate_r13 (.gclk(mclk_r13),
|
||||
.clk (mclk), .enable(r13_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_r13 = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_r13 or posedge puc_rst)
|
||||
if (puc_rst) r13 <= 16'h0000;
|
||||
else if (r13_wr) r13 <= reg_dest_val_in;
|
||||
`ifdef CLOCK_GATING
|
||||
else r13 <= reg_incr_val;
|
||||
`else
|
||||
else if (r13_inc) r13 <= reg_incr_val;
|
||||
`endif
|
||||
|
||||
// R14
|
||||
//------------
|
||||
reg [15:0] r14;
|
||||
wire r14_wr = inst_dest[14] & reg_dest_wr;
|
||||
wire r14_inc = inst_src_in[14] & reg_incr;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire r14_en = r14_wr | r14_inc;
|
||||
wire mclk_r14;
|
||||
omsp_clock_gate clock_gate_r14 (.gclk(mclk_r14),
|
||||
.clk (mclk), .enable(r14_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_r14 = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_r14 or posedge puc_rst)
|
||||
if (puc_rst) r14 <= 16'h0000;
|
||||
else if (r14_wr) r14 <= reg_dest_val_in;
|
||||
`ifdef CLOCK_GATING
|
||||
else r14 <= reg_incr_val;
|
||||
`else
|
||||
else if (r14_inc) r14 <= reg_incr_val;
|
||||
`endif
|
||||
|
||||
// R15
|
||||
//------------
|
||||
reg [15:0] r15;
|
||||
wire r15_wr = inst_dest[15] & reg_dest_wr;
|
||||
wire r15_inc = inst_src_in[15] & reg_incr;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire r15_en = r15_wr | r15_inc;
|
||||
wire mclk_r15;
|
||||
omsp_clock_gate clock_gate_r15 (.gclk(mclk_r15),
|
||||
.clk (mclk), .enable(r15_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_r15 = mclk;
|
||||
`endif
|
||||
|
||||
always @(posedge mclk_r15 or posedge puc_rst)
|
||||
if (puc_rst) r15 <= 16'h0000;
|
||||
else if (r15_wr) r15 <= reg_dest_val_in;
|
||||
`ifdef CLOCK_GATING
|
||||
else r15 <= reg_incr_val;
|
||||
`else
|
||||
else if (r15_inc) r15 <= reg_incr_val;
|
||||
`endif
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 5) READ MUX
|
||||
//=============================================================================
|
||||
|
||||
assign reg_src = (r0 & {16{inst_src_in[0]}}) |
|
||||
(r1 & {16{inst_src_in[1]}}) |
|
||||
(r2 & {16{inst_src_in[2]}}) |
|
||||
(r3 & {16{inst_src_in[3]}}) |
|
||||
(r4 & {16{inst_src_in[4]}}) |
|
||||
(r5 & {16{inst_src_in[5]}}) |
|
||||
(r6 & {16{inst_src_in[6]}}) |
|
||||
(r7 & {16{inst_src_in[7]}}) |
|
||||
(r8 & {16{inst_src_in[8]}}) |
|
||||
(r9 & {16{inst_src_in[9]}}) |
|
||||
(r10 & {16{inst_src_in[10]}}) |
|
||||
(r11 & {16{inst_src_in[11]}}) |
|
||||
(r12 & {16{inst_src_in[12]}}) |
|
||||
(r13 & {16{inst_src_in[13]}}) |
|
||||
(r14 & {16{inst_src_in[14]}}) |
|
||||
(r15 & {16{inst_src_in[15]}});
|
||||
|
||||
assign reg_dest = (r0 & {16{inst_dest[0]}}) |
|
||||
(r1 & {16{inst_dest[1]}}) |
|
||||
(r2 & {16{inst_dest[2]}}) |
|
||||
(r3 & {16{inst_dest[3]}}) |
|
||||
(r4 & {16{inst_dest[4]}}) |
|
||||
(r5 & {16{inst_dest[5]}}) |
|
||||
(r6 & {16{inst_dest[6]}}) |
|
||||
(r7 & {16{inst_dest[7]}}) |
|
||||
(r8 & {16{inst_dest[8]}}) |
|
||||
(r9 & {16{inst_dest[9]}}) |
|
||||
(r10 & {16{inst_dest[10]}}) |
|
||||
(r11 & {16{inst_dest[11]}}) |
|
||||
(r12 & {16{inst_dest[12]}}) |
|
||||
(r13 & {16{inst_dest[13]}}) |
|
||||
(r14 & {16{inst_dest[14]}}) |
|
||||
(r15 & {16{inst_dest[15]}});
|
||||
|
||||
|
||||
endmodule // omsp_register_file
|
||||
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_undefines.v"
|
||||
`endif
|
|
@ -1,75 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_scan_mux.v
|
||||
//
|
||||
// *Module Description:
|
||||
// Generic mux for scan mode
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 103 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
module omsp_scan_mux (
|
||||
|
||||
// OUTPUTs
|
||||
data_out, // Scan mux data output
|
||||
|
||||
// INPUTs
|
||||
data_in_scan, // Selected data input for scan mode
|
||||
data_in_func, // Selected data input for functional mode
|
||||
scan_mode // Scan mode
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output data_out; // Scan mux data output
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input data_in_scan; // Selected data input for scan mode
|
||||
input data_in_func; // Selected data input for functional mode
|
||||
input scan_mode; // Scan mode
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) SCAN MUX
|
||||
//=============================================================================
|
||||
|
||||
assign data_out = scan_mode ? data_in_scan : data_in_func;
|
||||
|
||||
|
||||
endmodule // omsp_scan_mux
|
||||
|
||||
|
|
@ -1,353 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_sfr.v
|
||||
//
|
||||
// *Module Description:
|
||||
// Processor Special function register
|
||||
// Non-Maskable Interrupt generation
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 134 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
|
||||
//----------------------------------------------------------------------------
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_defines.v"
|
||||
`endif
|
||||
|
||||
module omsp_sfr (
|
||||
|
||||
// OUTPUTs
|
||||
cpu_id, // CPU ID
|
||||
nmi_pnd, // NMI Pending
|
||||
nmi_wkup, // NMI Wakeup
|
||||
per_dout, // Peripheral data output
|
||||
wdtie, // Watchdog-timer interrupt enable
|
||||
wdtifg_sw_clr, // Watchdog-timer interrupt flag software clear
|
||||
wdtifg_sw_set, // Watchdog-timer interrupt flag software set
|
||||
|
||||
// INPUTs
|
||||
mclk, // Main system clock
|
||||
nmi, // Non-maskable interrupt (asynchronous)
|
||||
nmi_acc, // Non-Maskable interrupt request accepted
|
||||
per_addr, // Peripheral address
|
||||
per_din, // Peripheral data input
|
||||
per_en, // Peripheral enable (high active)
|
||||
per_we, // Peripheral write enable (high active)
|
||||
puc_rst, // Main system reset
|
||||
scan_mode, // Scan mode
|
||||
wdtifg, // Watchdog-timer interrupt flag
|
||||
wdtnmies // Watchdog-timer NMI edge selection
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output [31:0] cpu_id; // CPU ID
|
||||
output nmi_pnd; // NMI Pending
|
||||
output nmi_wkup; // NMI Wakeup
|
||||
output [15:0] per_dout; // Peripheral data output
|
||||
output wdtie; // Watchdog-timer interrupt enable
|
||||
output wdtifg_sw_clr;// Watchdog-timer interrupt flag software clear
|
||||
output wdtifg_sw_set;// Watchdog-timer interrupt flag software set
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input mclk; // Main system clock
|
||||
input nmi; // Non-maskable interrupt (asynchronous)
|
||||
input nmi_acc; // Non-Maskable interrupt request accepted
|
||||
input [13:0] per_addr; // Peripheral address
|
||||
input [15:0] per_din; // Peripheral data input
|
||||
input per_en; // Peripheral enable (high active)
|
||||
input [1:0] per_we; // Peripheral write enable (high active)
|
||||
input puc_rst; // Main system reset
|
||||
input scan_mode; // Scan mode
|
||||
input wdtifg; // Watchdog-timer interrupt flag
|
||||
input wdtnmies; // Watchdog-timer NMI edge selection
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) PARAMETER DECLARATION
|
||||
//=============================================================================
|
||||
|
||||
// Register base address (must be aligned to decoder bit width)
|
||||
parameter [14:0] BASE_ADDR = 15'h0000;
|
||||
|
||||
// Decoder bit width (defines how many bits are considered for address decoding)
|
||||
parameter DEC_WD = 3;
|
||||
|
||||
// Register addresses offset
|
||||
parameter [DEC_WD-1:0] IE1 = 'h0,
|
||||
IFG1 = 'h2,
|
||||
CPU_ID_LO = 'h4,
|
||||
CPU_ID_HI = 'h6;
|
||||
|
||||
// Register one-hot decoder utilities
|
||||
parameter DEC_SZ = (1 << DEC_WD);
|
||||
parameter [DEC_SZ-1:0] BASE_REG = {{DEC_SZ-1{1'b0}}, 1'b1};
|
||||
|
||||
// Register one-hot decoder
|
||||
parameter [DEC_SZ-1:0] IE1_D = (BASE_REG << IE1),
|
||||
IFG1_D = (BASE_REG << IFG1),
|
||||
CPU_ID_LO_D = (BASE_REG << CPU_ID_LO),
|
||||
CPU_ID_HI_D = (BASE_REG << CPU_ID_HI);
|
||||
|
||||
|
||||
//============================================================================
|
||||
// 2) REGISTER DECODER
|
||||
//============================================================================
|
||||
|
||||
// Local register selection
|
||||
wire reg_sel = per_en & (per_addr[13:DEC_WD-1]==BASE_ADDR[14:DEC_WD]);
|
||||
|
||||
// Register local address
|
||||
wire [DEC_WD-1:0] reg_addr = {1'b0, per_addr[DEC_WD-2:0]};
|
||||
|
||||
// Register address decode
|
||||
wire [DEC_SZ-1:0] reg_dec = (IE1_D & {DEC_SZ{(reg_addr==(IE1 >>1))}}) |
|
||||
(IFG1_D & {DEC_SZ{(reg_addr==(IFG1 >>1))}}) |
|
||||
(CPU_ID_LO_D & {DEC_SZ{(reg_addr==(CPU_ID_LO >>1))}}) |
|
||||
(CPU_ID_HI_D & {DEC_SZ{(reg_addr==(CPU_ID_HI >>1))}});
|
||||
|
||||
// Read/Write probes
|
||||
wire reg_lo_write = per_we[0] & reg_sel;
|
||||
wire reg_hi_write = per_we[1] & reg_sel;
|
||||
wire reg_read = ~|per_we & reg_sel;
|
||||
|
||||
// Read/Write vectors
|
||||
wire [DEC_SZ-1:0] reg_hi_wr = reg_dec & {DEC_SZ{reg_hi_write}};
|
||||
wire [DEC_SZ-1:0] reg_lo_wr = reg_dec & {DEC_SZ{reg_lo_write}};
|
||||
wire [DEC_SZ-1:0] reg_rd = reg_dec & {DEC_SZ{reg_read}};
|
||||
|
||||
|
||||
//============================================================================
|
||||
// 3) REGISTERS
|
||||
//============================================================================
|
||||
|
||||
// IE1 Register
|
||||
//--------------
|
||||
wire [7:0] ie1;
|
||||
wire ie1_wr = IE1[0] ? reg_hi_wr[IE1] : reg_lo_wr[IE1];
|
||||
wire [7:0] ie1_nxt = IE1[0] ? per_din[15:8] : per_din[7:0];
|
||||
|
||||
`ifdef NMI
|
||||
reg nmie;
|
||||
always @ (posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) nmie <= 1'b0;
|
||||
else if (nmi_acc) nmie <= 1'b0;
|
||||
else if (ie1_wr) nmie <= ie1_nxt[4];
|
||||
`else
|
||||
wire nmie = 1'b0;
|
||||
`endif
|
||||
|
||||
`ifdef WATCHDOG
|
||||
reg wdtie;
|
||||
always @ (posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) wdtie <= 1'b0;
|
||||
else if (ie1_wr) wdtie <= ie1_nxt[0];
|
||||
`else
|
||||
wire wdtie = 1'b0;
|
||||
`endif
|
||||
|
||||
assign ie1 = {3'b000, nmie, 3'b000, wdtie};
|
||||
|
||||
|
||||
// IFG1 Register
|
||||
//---------------
|
||||
wire [7:0] ifg1;
|
||||
|
||||
wire ifg1_wr = IFG1[0] ? reg_hi_wr[IFG1] : reg_lo_wr[IFG1];
|
||||
wire [7:0] ifg1_nxt = IFG1[0] ? per_din[15:8] : per_din[7:0];
|
||||
|
||||
`ifdef NMI
|
||||
reg nmiifg;
|
||||
wire nmi_edge;
|
||||
always @ (posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) nmiifg <= 1'b0;
|
||||
else if (nmi_edge) nmiifg <= 1'b1;
|
||||
else if (ifg1_wr) nmiifg <= ifg1_nxt[4];
|
||||
`else
|
||||
wire nmiifg = 1'b0;
|
||||
`endif
|
||||
|
||||
`ifdef WATCHDOG
|
||||
assign wdtifg_sw_clr = ifg1_wr & ~ifg1_nxt[0];
|
||||
assign wdtifg_sw_set = ifg1_wr & ifg1_nxt[0];
|
||||
`else
|
||||
assign wdtifg_sw_clr = 1'b0;
|
||||
assign wdtifg_sw_set = 1'b0;
|
||||
`endif
|
||||
|
||||
assign ifg1 = {3'b000, nmiifg, 3'b000, wdtifg};
|
||||
|
||||
|
||||
// CPU_ID Register (READ ONLY)
|
||||
//-----------------------------
|
||||
// -------------------------------------------------------------------
|
||||
// CPU_ID_LO: | 15 14 13 12 11 10 9 | 8 7 6 5 4 | 3 | 2 1 0 |
|
||||
// |----------------------------+-----------------+------+-------------|
|
||||
// | PER_SPACE | USER_VERSION | ASIC | CPU_VERSION |
|
||||
// --------------------------------------------------------------------
|
||||
// CPU_ID_HI: | 15 14 13 12 11 10 | 9 8 7 6 5 4 3 2 1 | 0 |
|
||||
// |----------------------------+-------------------------------+------|
|
||||
// | PMEM_SIZE | DMEM_SIZE | MPY |
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
wire [2:0] cpu_version = `CPU_VERSION;
|
||||
`ifdef ASIC
|
||||
wire cpu_asic = 1'b1;
|
||||
`else
|
||||
wire cpu_asic = 1'b0;
|
||||
`endif
|
||||
wire [4:0] user_version = `USER_VERSION;
|
||||
wire [6:0] per_space = (`PER_SIZE >> 9); // cpu_id_per * 512 = peripheral space size
|
||||
`ifdef MULTIPLIER
|
||||
wire mpy_info = 1'b1;
|
||||
`else
|
||||
wire mpy_info = 1'b0;
|
||||
`endif
|
||||
wire [8:0] dmem_size = (`DMEM_SIZE >> 7); // cpu_id_dmem * 128 = data memory size
|
||||
wire [5:0] pmem_size = (`PMEM_SIZE >> 10); // cpu_id_pmem * 1024 = program memory size
|
||||
|
||||
assign cpu_id = {pmem_size,
|
||||
dmem_size,
|
||||
mpy_info,
|
||||
per_space,
|
||||
user_version,
|
||||
cpu_asic,
|
||||
cpu_version};
|
||||
|
||||
|
||||
//============================================================================
|
||||
// 4) DATA OUTPUT GENERATION
|
||||
//============================================================================
|
||||
|
||||
// Data output mux
|
||||
wire [15:0] ie1_rd = {8'h00, (ie1 & {8{reg_rd[IE1]}})} << (8 & {4{IE1[0]}});
|
||||
wire [15:0] ifg1_rd = {8'h00, (ifg1 & {8{reg_rd[IFG1]}})} << (8 & {4{IFG1[0]}});
|
||||
wire [15:0] cpu_id_lo_rd = cpu_id[15:0] & {16{reg_rd[CPU_ID_LO]}};
|
||||
wire [15:0] cpu_id_hi_rd = cpu_id[31:16] & {16{reg_rd[CPU_ID_HI]}};
|
||||
|
||||
wire [15:0] per_dout = ie1_rd |
|
||||
ifg1_rd |
|
||||
cpu_id_lo_rd |
|
||||
cpu_id_hi_rd;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 5) NMI GENERATION
|
||||
//=============================================================================
|
||||
// NOTE THAT THE NMI INPUT IS ASSUMED TO BE NON-GLITCHY
|
||||
`ifdef NMI
|
||||
|
||||
//-----------------------------------
|
||||
// Edge selection
|
||||
//-----------------------------------
|
||||
wire nmi_pol = nmi ^ wdtnmies;
|
||||
|
||||
//-----------------------------------
|
||||
// Pulse capture and synchronization
|
||||
//-----------------------------------
|
||||
`ifdef SYNC_NMI
|
||||
`ifdef ASIC
|
||||
// Glitch free reset for the event capture
|
||||
reg nmi_capture_rst;
|
||||
always @(posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) nmi_capture_rst <= 1'b1;
|
||||
else nmi_capture_rst <= ifg1_wr & ~ifg1_nxt[4];
|
||||
|
||||
// NMI event capture
|
||||
wire nmi_capture;
|
||||
omsp_wakeup_cell wakeup_cell_nmi (
|
||||
.wkup_out (nmi_capture), // Wakup signal (asynchronous)
|
||||
.scan_clk (mclk), // Scan clock
|
||||
.scan_mode (scan_mode), // Scan mode
|
||||
.scan_rst (puc_rst), // Scan reset
|
||||
.wkup_clear (nmi_capture_rst), // Glitch free wakeup event clear
|
||||
.wkup_event (nmi_pol) // Glitch free asynchronous wakeup event
|
||||
);
|
||||
`else
|
||||
wire nmi_capture = nmi_pol;
|
||||
`endif
|
||||
|
||||
// Synchronization
|
||||
wire nmi_s;
|
||||
omsp_sync_cell sync_cell_nmi (
|
||||
.data_out (nmi_s),
|
||||
.data_in (nmi_capture),
|
||||
.clk (mclk),
|
||||
.rst (puc_rst)
|
||||
);
|
||||
|
||||
`else
|
||||
wire nmi_capture = nmi_pol;
|
||||
wire nmi_s = nmi_pol;
|
||||
`endif
|
||||
|
||||
//-----------------------------------
|
||||
// NMI Pending flag
|
||||
//-----------------------------------
|
||||
|
||||
// Delay
|
||||
reg nmi_dly;
|
||||
always @ (posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) nmi_dly <= 1'b0;
|
||||
else nmi_dly <= nmi_s;
|
||||
|
||||
// Edge detection
|
||||
assign nmi_edge = ~nmi_dly & nmi_s;
|
||||
|
||||
// NMI pending
|
||||
wire nmi_pnd = nmiifg & nmie;
|
||||
|
||||
// NMI wakeup
|
||||
`ifdef ASIC
|
||||
wire nmi_wkup;
|
||||
omsp_and_gate and_nmi_wkup (.y(nmi_wkup), .a(nmi_capture ^ nmi_dly), .b(nmie));
|
||||
`else
|
||||
wire nmi_wkup = 1'b0;
|
||||
`endif
|
||||
|
||||
`else
|
||||
|
||||
wire nmi_pnd = 1'b0;
|
||||
wire nmi_wkup = 1'b0;
|
||||
|
||||
`endif
|
||||
|
||||
endmodule // omsp_sfr
|
||||
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_undefines.v"
|
||||
`endif
|
|
@ -1,80 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_sync_cell.v
|
||||
//
|
||||
// *Module Description:
|
||||
// Generic synchronizer for the openMSP430
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 103 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
module omsp_sync_cell (
|
||||
|
||||
// OUTPUTs
|
||||
data_out, // Synchronized data output
|
||||
|
||||
// INPUTs
|
||||
clk, // Receiving clock
|
||||
data_in, // Asynchronous data input
|
||||
rst // Receiving reset (active high)
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output data_out; // Synchronized data output
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input clk; // Receiving clock
|
||||
input data_in; // Asynchronous data input
|
||||
input rst; // Receiving reset (active high)
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) SYNCHRONIZER
|
||||
//=============================================================================
|
||||
|
||||
reg [1:0] data_sync;
|
||||
|
||||
always @(posedge clk or posedge rst)
|
||||
if (rst) data_sync <= 2'b00;
|
||||
else data_sync <= {data_sync[0], data_in};
|
||||
|
||||
assign data_out = data_sync[1];
|
||||
|
||||
|
||||
endmodule // omsp_sync_cell
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_sync_reset.v
|
||||
//
|
||||
// *Module Description:
|
||||
// Generic reset synchronizer for the openMSP430
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 103 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
module omsp_sync_reset (
|
||||
|
||||
// OUTPUTs
|
||||
rst_s, // Synchronized reset
|
||||
|
||||
// INPUTs
|
||||
clk, // Receiving clock
|
||||
rst_a // Asynchronous reset
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output rst_s; // Synchronized reset
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input clk; // Receiving clock
|
||||
input rst_a; // Asynchronous reset
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) SYNCHRONIZER
|
||||
//=============================================================================
|
||||
|
||||
reg [1:0] data_sync;
|
||||
|
||||
always @(posedge clk or posedge rst_a)
|
||||
if (rst_a) data_sync <= 2'b11;
|
||||
else data_sync <= {data_sync[0], 1'b0};
|
||||
|
||||
assign rst_s = data_sync[1];
|
||||
|
||||
|
||||
endmodule // omsp_sync_reset
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_wakeup_cell.v
|
||||
//
|
||||
// *Module Description:
|
||||
// Generic Wakeup cell
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 103 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2011-03-05 15:44:48 +0100 (Sat, 05 Mar 2011) $
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
module omsp_wakeup_cell (
|
||||
|
||||
// OUTPUTs
|
||||
wkup_out, // Wakup signal (asynchronous)
|
||||
|
||||
// INPUTs
|
||||
scan_clk, // Scan clock
|
||||
scan_mode, // Scan mode
|
||||
scan_rst, // Scan reset
|
||||
wkup_clear, // Glitch free wakeup event clear
|
||||
wkup_event // Glitch free asynchronous wakeup event
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output wkup_out; // Wakup signal (asynchronous)
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input scan_clk; // Scan clock
|
||||
input scan_mode; // Scan mode
|
||||
input scan_rst; // Scan reset
|
||||
input wkup_clear; // Glitch free wakeup event clear
|
||||
input wkup_event; // Glitch free asynchronous wakeup event
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) AND GATE
|
||||
//=============================================================================
|
||||
|
||||
// Scan stuff for the ASIC mode
|
||||
`ifdef ASIC
|
||||
wire wkup_rst;
|
||||
omsp_scan_mux scan_mux_rst (
|
||||
.scan_mode (scan_mode),
|
||||
.data_in_scan (scan_rst),
|
||||
.data_in_func (wkup_clear),
|
||||
.data_out (wkup_rst)
|
||||
);
|
||||
|
||||
wire wkup_clk;
|
||||
omsp_scan_mux scan_mux_clk (
|
||||
.scan_mode (scan_mode),
|
||||
.data_in_scan (scan_clk),
|
||||
.data_in_func (wkup_event),
|
||||
.data_out (wkup_clk)
|
||||
);
|
||||
|
||||
`else
|
||||
wire wkup_rst = wkup_clear;
|
||||
wire wkup_clk = wkup_event;
|
||||
`endif
|
||||
|
||||
// Wakeup capture
|
||||
reg wkup_out;
|
||||
always @(posedge wkup_clk or posedge wkup_rst)
|
||||
if (wkup_rst) wkup_out <= 1'b0;
|
||||
else wkup_out <= 1'b1;
|
||||
|
||||
|
||||
endmodule // omsp_wakeup_cell
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,556 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: omsp_watchdog.v
|
||||
//
|
||||
// *Module Description:
|
||||
// Watchdog Timer
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 134 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
|
||||
//----------------------------------------------------------------------------
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_defines.v"
|
||||
`endif
|
||||
|
||||
module omsp_watchdog (
|
||||
|
||||
// OUTPUTs
|
||||
per_dout, // Peripheral data output
|
||||
wdt_irq, // Watchdog-timer interrupt
|
||||
wdt_reset, // Watchdog-timer reset
|
||||
wdt_wkup, // Watchdog Wakeup
|
||||
wdtifg, // Watchdog-timer interrupt flag
|
||||
wdtnmies, // Watchdog-timer NMI edge selection
|
||||
|
||||
// INPUTs
|
||||
aclk, // ACLK
|
||||
aclk_en, // ACLK enable
|
||||
dbg_freeze, // Freeze Watchdog counter
|
||||
mclk, // Main system clock
|
||||
per_addr, // Peripheral address
|
||||
per_din, // Peripheral data input
|
||||
per_en, // Peripheral enable (high active)
|
||||
per_we, // Peripheral write enable (high active)
|
||||
por, // Power-on reset
|
||||
puc_rst, // Main system reset
|
||||
scan_enable, // Scan enable (active during scan shifting)
|
||||
scan_mode, // Scan mode
|
||||
smclk, // SMCLK
|
||||
smclk_en, // SMCLK enable
|
||||
wdtie, // Watchdog timer interrupt enable
|
||||
wdtifg_irq_clr, // Watchdog-timer interrupt flag irq accepted clear
|
||||
wdtifg_sw_clr, // Watchdog-timer interrupt flag software clear
|
||||
wdtifg_sw_set // Watchdog-timer interrupt flag software set
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output [15:0] per_dout; // Peripheral data output
|
||||
output wdt_irq; // Watchdog-timer interrupt
|
||||
output wdt_reset; // Watchdog-timer reset
|
||||
output wdt_wkup; // Watchdog Wakeup
|
||||
output wdtifg; // Watchdog-timer interrupt flag
|
||||
output wdtnmies; // Watchdog-timer NMI edge selection
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input aclk; // ACLK
|
||||
input aclk_en; // ACLK enable
|
||||
input dbg_freeze; // Freeze Watchdog counter
|
||||
input mclk; // Main system clock
|
||||
input [13:0] per_addr; // Peripheral address
|
||||
input [15:0] per_din; // Peripheral data input
|
||||
input per_en; // Peripheral enable (high active)
|
||||
input [1:0] per_we; // Peripheral write enable (high active)
|
||||
input por; // Power-on reset
|
||||
input puc_rst; // Main system reset
|
||||
input scan_enable; // Scan enable (active during scan shifting)
|
||||
input scan_mode; // Scan mode
|
||||
input smclk; // SMCLK
|
||||
input smclk_en; // SMCLK enable
|
||||
input wdtie; // Watchdog timer interrupt enable
|
||||
input wdtifg_irq_clr; // Clear Watchdog-timer interrupt flag
|
||||
input wdtifg_sw_clr; // Watchdog-timer interrupt flag software clear
|
||||
input wdtifg_sw_set; // Watchdog-timer interrupt flag software set
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) PARAMETER DECLARATION
|
||||
//=============================================================================
|
||||
|
||||
// Register base address (must be aligned to decoder bit width)
|
||||
parameter [14:0] BASE_ADDR = 15'h0120;
|
||||
|
||||
// Decoder bit width (defines how many bits are considered for address decoding)
|
||||
parameter DEC_WD = 2;
|
||||
|
||||
// Register addresses offset
|
||||
parameter [DEC_WD-1:0] WDTCTL = 'h0;
|
||||
|
||||
// Register one-hot decoder utilities
|
||||
parameter DEC_SZ = (1 << DEC_WD);
|
||||
parameter [DEC_SZ-1:0] BASE_REG = {{DEC_SZ-1{1'b0}}, 1'b1};
|
||||
|
||||
// Register one-hot decoder
|
||||
parameter [DEC_SZ-1:0] WDTCTL_D = (BASE_REG << WDTCTL);
|
||||
|
||||
|
||||
//============================================================================
|
||||
// 2) REGISTER DECODER
|
||||
//============================================================================
|
||||
|
||||
// Local register selection
|
||||
wire reg_sel = per_en & (per_addr[13:DEC_WD-1]==BASE_ADDR[14:DEC_WD]);
|
||||
|
||||
// Register local address
|
||||
wire [DEC_WD-1:0] reg_addr = {per_addr[DEC_WD-2:0], 1'b0};
|
||||
|
||||
// Register address decode
|
||||
wire [DEC_SZ-1:0] reg_dec = (WDTCTL_D & {DEC_SZ{(reg_addr==WDTCTL)}});
|
||||
|
||||
// Read/Write probes
|
||||
wire reg_write = |per_we & reg_sel;
|
||||
wire reg_read = ~|per_we & reg_sel;
|
||||
|
||||
// Read/Write vectors
|
||||
wire [DEC_SZ-1:0] reg_wr = reg_dec & {DEC_SZ{reg_write}};
|
||||
wire [DEC_SZ-1:0] reg_rd = reg_dec & {DEC_SZ{reg_read}};
|
||||
|
||||
|
||||
//============================================================================
|
||||
// 3) REGISTERS
|
||||
//============================================================================
|
||||
|
||||
// WDTCTL Register
|
||||
//-----------------
|
||||
// WDTNMI is not implemented and therefore masked
|
||||
|
||||
reg [7:0] wdtctl;
|
||||
|
||||
wire wdtctl_wr = reg_wr[WDTCTL];
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire mclk_wdtctl;
|
||||
omsp_clock_gate clock_gate_wdtctl (.gclk(mclk_wdtctl),
|
||||
.clk (mclk), .enable(wdtctl_wr), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire mclk_wdtctl = mclk;
|
||||
`endif
|
||||
|
||||
`ifdef NMI
|
||||
parameter [7:0] WDTNMIES_MASK = 8'h40;
|
||||
`else
|
||||
parameter [7:0] WDTNMIES_MASK = 8'h00;
|
||||
`endif
|
||||
|
||||
`ifdef ASIC
|
||||
`ifdef WATCHDOG_MUX
|
||||
parameter [7:0] WDTSSEL_MASK = 8'h04;
|
||||
`else
|
||||
parameter [7:0] WDTSSEL_MASK = 8'h00;
|
||||
`endif
|
||||
`else
|
||||
parameter [7:0] WDTSSEL_MASK = 8'h04;
|
||||
`endif
|
||||
|
||||
parameter [7:0] WDTCTL_MASK = (8'b1001_0011 | WDTSSEL_MASK | WDTNMIES_MASK);
|
||||
|
||||
always @ (posedge mclk_wdtctl or posedge puc_rst)
|
||||
if (puc_rst) wdtctl <= 8'h00;
|
||||
`ifdef CLOCK_GATING
|
||||
else wdtctl <= per_din[7:0] & WDTCTL_MASK;
|
||||
`else
|
||||
else if (wdtctl_wr) wdtctl <= per_din[7:0] & WDTCTL_MASK;
|
||||
`endif
|
||||
|
||||
wire wdtpw_error = wdtctl_wr & (per_din[15:8]!=8'h5a);
|
||||
wire wdttmsel = wdtctl[4];
|
||||
wire wdtnmies = wdtctl[6];
|
||||
|
||||
|
||||
//============================================================================
|
||||
// 4) DATA OUTPUT GENERATION
|
||||
//============================================================================
|
||||
|
||||
`ifdef NMI
|
||||
parameter [7:0] WDTNMI_RD_MASK = 8'h20;
|
||||
`else
|
||||
parameter [7:0] WDTNMI_RD_MASK = 8'h00;
|
||||
`endif
|
||||
`ifdef WATCHDOG_MUX
|
||||
parameter [7:0] WDTSSEL_RD_MASK = 8'h00;
|
||||
`else
|
||||
`ifdef WATCHDOG_NOMUX_ACLK
|
||||
parameter [7:0] WDTSSEL_RD_MASK = 8'h04;
|
||||
`else
|
||||
parameter [7:0] WDTSSEL_RD_MASK = 8'h00;
|
||||
`endif
|
||||
`endif
|
||||
parameter [7:0] WDTCTL_RD_MASK = WDTNMI_RD_MASK | WDTSSEL_RD_MASK;
|
||||
|
||||
// Data output mux
|
||||
wire [15:0] wdtctl_rd = {8'h69, wdtctl | WDTCTL_RD_MASK} & {16{reg_rd[WDTCTL]}};
|
||||
wire [15:0] per_dout = wdtctl_rd;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 5) WATCHDOG TIMER (ASIC IMPLEMENTATION)
|
||||
//=============================================================================
|
||||
`ifdef ASIC
|
||||
|
||||
// Watchdog clock source selection
|
||||
//---------------------------------
|
||||
wire wdt_clk;
|
||||
|
||||
`ifdef WATCHDOG_MUX
|
||||
omsp_clock_mux clock_mux_watchdog (
|
||||
.clk_out (wdt_clk),
|
||||
.clk_in0 (smclk),
|
||||
.clk_in1 (aclk),
|
||||
.reset (puc_rst),
|
||||
.scan_mode (scan_mode),
|
||||
.select (wdtctl[2])
|
||||
);
|
||||
`else
|
||||
`ifdef WATCHDOG_NOMUX_ACLK
|
||||
assign wdt_clk = aclk;
|
||||
`else
|
||||
assign wdt_clk = smclk;
|
||||
`endif
|
||||
`endif
|
||||
|
||||
// Reset synchronizer for the watchdog local clock domain
|
||||
//--------------------------------------------------------
|
||||
|
||||
wire wdt_rst_noscan;
|
||||
wire wdt_rst;
|
||||
|
||||
// Reset Synchronizer
|
||||
omsp_sync_reset sync_reset_por (
|
||||
.rst_s (wdt_rst_noscan),
|
||||
.clk (wdt_clk),
|
||||
.rst_a (puc_rst)
|
||||
);
|
||||
|
||||
// Scan Reset Mux
|
||||
omsp_scan_mux scan_mux_wdt_rst (
|
||||
.scan_mode (scan_mode),
|
||||
.data_in_scan (puc_rst),
|
||||
.data_in_func (wdt_rst_noscan),
|
||||
.data_out (wdt_rst)
|
||||
);
|
||||
|
||||
|
||||
// Watchog counter clear (synchronization)
|
||||
//-----------------------------------------
|
||||
|
||||
// Toggle bit whenever the watchog needs to be cleared
|
||||
reg wdtcnt_clr_toggle;
|
||||
wire wdtcnt_clr_detect = (wdtctl_wr & per_din[3]);
|
||||
always @ (posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) wdtcnt_clr_toggle <= 1'b0;
|
||||
else if (wdtcnt_clr_detect) wdtcnt_clr_toggle <= ~wdtcnt_clr_toggle;
|
||||
|
||||
// Synchronization
|
||||
wire wdtcnt_clr_sync;
|
||||
omsp_sync_cell sync_cell_wdtcnt_clr (
|
||||
.data_out (wdtcnt_clr_sync),
|
||||
.data_in (wdtcnt_clr_toggle),
|
||||
.clk (wdt_clk),
|
||||
.rst (wdt_rst)
|
||||
);
|
||||
|
||||
// Edge detection
|
||||
reg wdtcnt_clr_sync_dly;
|
||||
always @ (posedge wdt_clk or posedge wdt_rst)
|
||||
if (wdt_rst) wdtcnt_clr_sync_dly <= 1'b0;
|
||||
else wdtcnt_clr_sync_dly <= wdtcnt_clr_sync;
|
||||
|
||||
wire wdtqn_edge;
|
||||
wire wdtcnt_clr = (wdtcnt_clr_sync ^ wdtcnt_clr_sync_dly) | wdtqn_edge;
|
||||
|
||||
|
||||
// Watchog counter increment (synchronization)
|
||||
//----------------------------------------------
|
||||
wire wdtcnt_incr;
|
||||
|
||||
omsp_sync_cell sync_cell_wdtcnt_incr (
|
||||
.data_out (wdtcnt_incr),
|
||||
.data_in (~wdtctl[7] & ~dbg_freeze),
|
||||
.clk (wdt_clk),
|
||||
.rst (wdt_rst)
|
||||
);
|
||||
|
||||
|
||||
// Watchdog 16 bit counter
|
||||
//--------------------------
|
||||
reg [15:0] wdtcnt;
|
||||
|
||||
wire [15:0] wdtcnt_nxt = wdtcnt+16'h0001;
|
||||
|
||||
`ifdef CLOCK_GATING
|
||||
wire wdtcnt_en = wdtcnt_clr | wdtcnt_incr;
|
||||
wire wdt_clk_cnt;
|
||||
omsp_clock_gate clock_gate_wdtcnt (.gclk(wdt_clk_cnt),
|
||||
.clk (wdt_clk), .enable(wdtcnt_en), .scan_enable(scan_enable));
|
||||
`else
|
||||
wire wdt_clk_cnt = wdt_clk;
|
||||
`endif
|
||||
|
||||
always @ (posedge wdt_clk_cnt or posedge wdt_rst)
|
||||
if (wdt_rst) wdtcnt <= 16'h0000;
|
||||
else if (wdtcnt_clr) wdtcnt <= 16'h0000;
|
||||
`ifdef CLOCK_GATING
|
||||
else wdtcnt <= wdtcnt_nxt;
|
||||
`else
|
||||
else if (wdtcnt_incr) wdtcnt <= wdtcnt_nxt;
|
||||
`endif
|
||||
|
||||
|
||||
// Local synchronizer for the wdtctl.WDTISx
|
||||
// configuration (note that we can live with
|
||||
// a full bus synchronizer as it won't hurt
|
||||
// if we get a wrong WDTISx value for a
|
||||
// single clock cycle)
|
||||
//--------------------------------------------
|
||||
reg [1:0] wdtisx_s;
|
||||
reg [1:0] wdtisx_ss;
|
||||
always @ (posedge wdt_clk_cnt or posedge wdt_rst)
|
||||
if (wdt_rst)
|
||||
begin
|
||||
wdtisx_s <= 2'h0;
|
||||
wdtisx_ss <= 2'h0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
wdtisx_s <= wdtctl[1:0];
|
||||
wdtisx_ss <= wdtisx_s;
|
||||
end
|
||||
|
||||
|
||||
// Interval selection mux
|
||||
//--------------------------
|
||||
reg wdtqn;
|
||||
|
||||
always @(wdtisx_ss or wdtcnt_nxt)
|
||||
case(wdtisx_ss)
|
||||
2'b00 : wdtqn = wdtcnt_nxt[15];
|
||||
2'b01 : wdtqn = wdtcnt_nxt[13];
|
||||
2'b10 : wdtqn = wdtcnt_nxt[9];
|
||||
default: wdtqn = wdtcnt_nxt[6];
|
||||
endcase
|
||||
|
||||
|
||||
// Watchdog event detection
|
||||
//-----------------------------
|
||||
|
||||
// Interval end detection
|
||||
assign wdtqn_edge = (wdtqn & wdtcnt_incr);
|
||||
|
||||
// Toggle bit for the transmition to the MCLK domain
|
||||
reg wdt_evt_toggle;
|
||||
always @ (posedge wdt_clk_cnt or posedge wdt_rst)
|
||||
if (wdt_rst) wdt_evt_toggle <= 1'b0;
|
||||
else if (wdtqn_edge) wdt_evt_toggle <= ~wdt_evt_toggle;
|
||||
|
||||
// Synchronize in the MCLK domain
|
||||
wire wdt_evt_toggle_sync;
|
||||
omsp_sync_cell sync_cell_wdt_evt (
|
||||
.data_out (wdt_evt_toggle_sync),
|
||||
.data_in (wdt_evt_toggle),
|
||||
.clk (mclk),
|
||||
.rst (puc_rst)
|
||||
);
|
||||
|
||||
// Delay for edge detection of the toggle bit
|
||||
reg wdt_evt_toggle_sync_dly;
|
||||
always @ (posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) wdt_evt_toggle_sync_dly <= 1'b0;
|
||||
else wdt_evt_toggle_sync_dly <= wdt_evt_toggle_sync;
|
||||
|
||||
wire wdtifg_evt = (wdt_evt_toggle_sync_dly ^ wdt_evt_toggle_sync) | wdtpw_error;
|
||||
|
||||
|
||||
// Watchdog wakeup generation
|
||||
//-------------------------------------------------------------
|
||||
|
||||
// Clear wakeup when the watchdog flag is cleared (glitch free)
|
||||
reg wdtifg_clr_reg;
|
||||
wire wdtifg_clr;
|
||||
always @ (posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) wdtifg_clr_reg <= 1'b1;
|
||||
else wdtifg_clr_reg <= wdtifg_clr;
|
||||
|
||||
// Set wakeup when the watchdog event is detected (glitch free)
|
||||
reg wdtqn_edge_reg;
|
||||
always @ (posedge wdt_clk_cnt or posedge wdt_rst)
|
||||
if (wdt_rst) wdtqn_edge_reg <= 1'b0;
|
||||
else wdtqn_edge_reg <= wdtqn_edge;
|
||||
|
||||
// Watchdog wakeup cell
|
||||
wire wdt_wkup_pre;
|
||||
omsp_wakeup_cell wakeup_cell_wdog (
|
||||
.wkup_out (wdt_wkup_pre), // Wakup signal (asynchronous)
|
||||
.scan_clk (mclk), // Scan clock
|
||||
.scan_mode (scan_mode), // Scan mode
|
||||
.scan_rst (puc_rst), // Scan reset
|
||||
.wkup_clear (wdtifg_clr_reg), // Glitch free wakeup event clear
|
||||
.wkup_event (wdtqn_edge_reg) // Glitch free asynchronous wakeup event
|
||||
);
|
||||
|
||||
// When not in HOLD, the watchdog can generate a wakeup when:
|
||||
// - in interval mode (if interrupts are enabled)
|
||||
// - in reset mode (always)
|
||||
reg wdt_wkup_en;
|
||||
always @ (posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) wdt_wkup_en <= 1'b0;
|
||||
else wdt_wkup_en <= ~wdtctl[7] & (~wdttmsel | (wdttmsel & wdtie));
|
||||
|
||||
// Make wakeup when not enabled
|
||||
wire wdt_wkup;
|
||||
omsp_and_gate and_wdt_wkup (.y(wdt_wkup), .a(wdt_wkup_pre), .b(wdt_wkup_en));
|
||||
|
||||
|
||||
// Watchdog interrupt flag
|
||||
//------------------------------
|
||||
reg wdtifg;
|
||||
|
||||
wire wdtifg_set = wdtifg_evt | wdtifg_sw_set;
|
||||
assign wdtifg_clr = (wdtifg_irq_clr & wdttmsel) | wdtifg_sw_clr;
|
||||
|
||||
always @ (posedge mclk or posedge por)
|
||||
if (por) wdtifg <= 1'b0;
|
||||
else if (wdtifg_set) wdtifg <= 1'b1;
|
||||
else if (wdtifg_clr) wdtifg <= 1'b0;
|
||||
|
||||
|
||||
// Watchdog interrupt generation
|
||||
//---------------------------------
|
||||
wire wdt_irq = wdttmsel & wdtifg & wdtie;
|
||||
|
||||
|
||||
// Watchdog reset generation
|
||||
//-----------------------------
|
||||
reg wdt_reset;
|
||||
|
||||
always @ (posedge mclk or posedge por)
|
||||
if (por) wdt_reset <= 1'b0;
|
||||
else wdt_reset <= wdtpw_error | (wdtifg_set & ~wdttmsel);
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 6) WATCHDOG TIMER (FPGA IMPLEMENTATION)
|
||||
//=============================================================================
|
||||
`else
|
||||
|
||||
// Watchdog clock source selection
|
||||
//---------------------------------
|
||||
wire clk_src_en = wdtctl[2] ? aclk_en : smclk_en;
|
||||
|
||||
|
||||
// Watchdog 16 bit counter
|
||||
//--------------------------
|
||||
reg [15:0] wdtcnt;
|
||||
|
||||
wire wdtifg_evt;
|
||||
wire wdtcnt_clr = (wdtctl_wr & per_din[3]) | wdtifg_evt;
|
||||
wire wdtcnt_incr = ~wdtctl[7] & clk_src_en & ~dbg_freeze;
|
||||
|
||||
wire [15:0] wdtcnt_nxt = wdtcnt+16'h0001;
|
||||
|
||||
always @ (posedge mclk or posedge puc_rst)
|
||||
if (puc_rst) wdtcnt <= 16'h0000;
|
||||
else if (wdtcnt_clr) wdtcnt <= 16'h0000;
|
||||
else if (wdtcnt_incr) wdtcnt <= wdtcnt_nxt;
|
||||
|
||||
|
||||
// Interval selection mux
|
||||
//--------------------------
|
||||
reg wdtqn;
|
||||
|
||||
always @(wdtctl or wdtcnt_nxt)
|
||||
case(wdtctl[1:0])
|
||||
2'b00 : wdtqn = wdtcnt_nxt[15];
|
||||
2'b01 : wdtqn = wdtcnt_nxt[13];
|
||||
2'b10 : wdtqn = wdtcnt_nxt[9];
|
||||
default: wdtqn = wdtcnt_nxt[6];
|
||||
endcase
|
||||
|
||||
|
||||
// Watchdog event detection
|
||||
//-----------------------------
|
||||
|
||||
assign wdtifg_evt = (wdtqn & wdtcnt_incr) | wdtpw_error;
|
||||
|
||||
|
||||
// Watchdog interrupt flag
|
||||
//------------------------------
|
||||
reg wdtifg;
|
||||
|
||||
wire wdtifg_set = wdtifg_evt | wdtifg_sw_set;
|
||||
wire wdtifg_clr = (wdtifg_irq_clr & wdttmsel) | wdtifg_sw_clr;
|
||||
|
||||
always @ (posedge mclk or posedge por)
|
||||
if (por) wdtifg <= 1'b0;
|
||||
else if (wdtifg_set) wdtifg <= 1'b1;
|
||||
else if (wdtifg_clr) wdtifg <= 1'b0;
|
||||
|
||||
|
||||
// Watchdog interrupt generation
|
||||
//---------------------------------
|
||||
wire wdt_irq = wdttmsel & wdtifg & wdtie;
|
||||
wire wdt_wkup = 1'b0;
|
||||
|
||||
|
||||
// Watchdog reset generation
|
||||
//-----------------------------
|
||||
reg wdt_reset;
|
||||
|
||||
always @ (posedge mclk or posedge por)
|
||||
if (por) wdt_reset <= 1'b0;
|
||||
else wdt_reset <= wdtpw_error | (wdtifg_set & ~wdttmsel);
|
||||
|
||||
|
||||
`endif
|
||||
|
||||
|
||||
endmodule // omsp_watchdog
|
||||
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_undefines.v"
|
||||
`endif
|
|
@ -1,584 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: openMSP430.v
|
||||
//
|
||||
// *Module Description:
|
||||
// openMSP430 Top level file
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 134 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2012-03-22 21:31:06 +0100 (Thu, 22 Mar 2012) $
|
||||
//----------------------------------------------------------------------------
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_defines.v"
|
||||
`endif
|
||||
|
||||
module openMSP430 (
|
||||
|
||||
// OUTPUTs
|
||||
aclk, // ASIC ONLY: ACLK
|
||||
aclk_en, // FPGA ONLY: ACLK enable
|
||||
dbg_freeze, // Freeze peripherals
|
||||
dbg_uart_txd, // Debug interface: UART TXD
|
||||
dco_enable, // ASIC ONLY: Fast oscillator enable
|
||||
dco_wkup, // ASIC ONLY: Fast oscillator wake-up (asynchronous)
|
||||
dmem_addr, // Data Memory address
|
||||
dmem_cen, // Data Memory chip enable (low active)
|
||||
dmem_din, // Data Memory data input
|
||||
dmem_wen, // Data Memory write enable (low active)
|
||||
irq_acc, // Interrupt request accepted (one-hot signal)
|
||||
lfxt_enable, // ASIC ONLY: Low frequency oscillator enable
|
||||
lfxt_wkup, // ASIC ONLY: Low frequency oscillator wake-up (asynchronous)
|
||||
mclk, // Main system clock
|
||||
per_addr, // Peripheral address
|
||||
per_din, // Peripheral data input
|
||||
per_we, // Peripheral write enable (high active)
|
||||
per_en, // Peripheral enable (high active)
|
||||
pmem_addr, // Program Memory address
|
||||
pmem_cen, // Program Memory chip enable (low active)
|
||||
pmem_din, // Program Memory data input (optional)
|
||||
pmem_wen, // Program Memory write enable (low active) (optional)
|
||||
puc_rst, // Main system reset
|
||||
smclk, // ASIC ONLY: SMCLK
|
||||
smclk_en, // FPGA ONLY: SMCLK enable
|
||||
|
||||
// INPUTs
|
||||
cpu_en, // Enable CPU code execution (asynchronous and non-glitchy)
|
||||
dbg_en, // Debug interface enable (asynchronous and non-glitchy)
|
||||
dbg_uart_rxd, // Debug interface: UART RXD (asynchronous)
|
||||
dco_clk, // Fast oscillator (fast clock)
|
||||
dmem_dout, // Data Memory data output
|
||||
irq, // Maskable interrupts
|
||||
lfxt_clk, // Low frequency oscillator (typ 32kHz)
|
||||
nmi, // Non-maskable interrupt (asynchronous)
|
||||
per_dout, // Peripheral data output
|
||||
pmem_dout, // Program Memory data output
|
||||
reset_n, // Reset Pin (low active, asynchronous and non-glitchy)
|
||||
scan_enable, // ASIC ONLY: Scan enable (active during scan shifting)
|
||||
scan_mode, // ASIC ONLY: Scan mode
|
||||
wkup // ASIC ONLY: System Wake-up (asynchronous and non-glitchy)
|
||||
);
|
||||
|
||||
// OUTPUTs
|
||||
//=========
|
||||
output aclk; // ASIC ONLY: ACLK
|
||||
output aclk_en; // FPGA ONLY: ACLK enable
|
||||
output dbg_freeze; // Freeze peripherals
|
||||
output dbg_uart_txd; // Debug interface: UART TXD
|
||||
output dco_enable; // ASIC ONLY: Fast oscillator enable
|
||||
output dco_wkup; // ASIC ONLY: Fast oscillator wake-up (asynchronous)
|
||||
output [`DMEM_MSB:0] dmem_addr; // Data Memory address
|
||||
output dmem_cen; // Data Memory chip enable (low active)
|
||||
output [15:0] dmem_din; // Data Memory data input
|
||||
output [1:0] dmem_wen; // Data Memory write enable (low active)
|
||||
output [13:0] irq_acc; // Interrupt request accepted (one-hot signal)
|
||||
output lfxt_enable; // ASIC ONLY: Low frequency oscillator enable
|
||||
output lfxt_wkup; // ASIC ONLY: Low frequency oscillator wake-up (asynchronous)
|
||||
output mclk; // Main system clock
|
||||
output [13:0] per_addr; // Peripheral address
|
||||
output [15:0] per_din; // Peripheral data input
|
||||
output [1:0] per_we; // Peripheral write enable (high active)
|
||||
output per_en; // Peripheral enable (high active)
|
||||
output [`PMEM_MSB:0] pmem_addr; // Program Memory address
|
||||
output pmem_cen; // Program Memory chip enable (low active)
|
||||
output [15:0] pmem_din; // Program Memory data input (optional)
|
||||
output [1:0] pmem_wen; // Program Memory write enable (low active) (optional)
|
||||
output puc_rst; // Main system reset
|
||||
output smclk; // ASIC ONLY: SMCLK
|
||||
output smclk_en; // FPGA ONLY: SMCLK enable
|
||||
|
||||
|
||||
// INPUTs
|
||||
//=========
|
||||
input cpu_en; // Enable CPU code execution (asynchronous and non-glitchy)
|
||||
input dbg_en; // Debug interface enable (asynchronous and non-glitchy)
|
||||
input dbg_uart_rxd; // Debug interface: UART RXD (asynchronous)
|
||||
input dco_clk; // Fast oscillator (fast clock)
|
||||
input [15:0] dmem_dout; // Data Memory data output
|
||||
input [13:0] irq; // Maskable interrupts
|
||||
input lfxt_clk; // Low frequency oscillator (typ 32kHz)
|
||||
input nmi; // Non-maskable interrupt (asynchronous and non-glitchy)
|
||||
input [15:0] per_dout; // Peripheral data output
|
||||
input [15:0] pmem_dout; // Program Memory data output
|
||||
input reset_n; // Reset Pin (active low, asynchronous and non-glitchy)
|
||||
input scan_enable; // ASIC ONLY: Scan enable (active during scan shifting)
|
||||
input scan_mode; // ASIC ONLY: Scan mode
|
||||
input wkup; // ASIC ONLY: System Wake-up (asynchronous and non-glitchy)
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 1) INTERNAL WIRES/REGISTERS/PARAMETERS DECLARATION
|
||||
//=============================================================================
|
||||
|
||||
wire [7:0] inst_ad;
|
||||
wire [7:0] inst_as;
|
||||
wire [11:0] inst_alu;
|
||||
wire inst_bw;
|
||||
wire inst_irq_rst;
|
||||
wire inst_mov;
|
||||
wire [15:0] inst_dest;
|
||||
wire [15:0] inst_dext;
|
||||
wire [15:0] inst_sext;
|
||||
wire [7:0] inst_so;
|
||||
wire [15:0] inst_src;
|
||||
wire [2:0] inst_type;
|
||||
wire [7:0] inst_jmp;
|
||||
wire [3:0] e_state;
|
||||
wire exec_done;
|
||||
wire decode_noirq;
|
||||
wire cpu_en_s;
|
||||
wire cpuoff;
|
||||
wire oscoff;
|
||||
wire scg0;
|
||||
wire scg1;
|
||||
wire por;
|
||||
wire gie;
|
||||
wire mclk_enable;
|
||||
wire mclk_wkup;
|
||||
wire [31:0] cpu_id;
|
||||
|
||||
wire [15:0] eu_mab;
|
||||
wire [15:0] eu_mdb_in;
|
||||
wire [15:0] eu_mdb_out;
|
||||
wire [1:0] eu_mb_wr;
|
||||
wire eu_mb_en;
|
||||
wire [15:0] fe_mab;
|
||||
wire [15:0] fe_mdb_in;
|
||||
wire fe_mb_en;
|
||||
wire fe_pmem_wait;
|
||||
|
||||
wire pc_sw_wr;
|
||||
wire [15:0] pc_sw;
|
||||
wire [15:0] pc;
|
||||
wire [15:0] pc_nxt;
|
||||
|
||||
wire nmi_acc;
|
||||
wire nmi_pnd;
|
||||
wire nmi_wkup;
|
||||
|
||||
wire wdtie;
|
||||
wire wdtnmies;
|
||||
wire wdtifg;
|
||||
wire wdt_irq;
|
||||
wire wdt_wkup;
|
||||
wire wdt_reset;
|
||||
wire wdtifg_sw_clr;
|
||||
wire wdtifg_sw_set;
|
||||
|
||||
wire dbg_clk;
|
||||
wire dbg_rst;
|
||||
wire dbg_en_s;
|
||||
wire dbg_halt_st;
|
||||
wire dbg_halt_cmd;
|
||||
wire dbg_mem_en;
|
||||
wire dbg_reg_wr;
|
||||
wire dbg_cpu_reset;
|
||||
wire [15:0] dbg_mem_addr;
|
||||
wire [15:0] dbg_mem_dout;
|
||||
wire [15:0] dbg_mem_din;
|
||||
wire [15:0] dbg_reg_din;
|
||||
wire [1:0] dbg_mem_wr;
|
||||
wire puc_pnd_set;
|
||||
|
||||
wire [15:0] per_dout_or;
|
||||
wire [15:0] per_dout_sfr;
|
||||
wire [15:0] per_dout_wdog;
|
||||
wire [15:0] per_dout_mpy;
|
||||
wire [15:0] per_dout_clk;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 2) GLOBAL CLOCK & RESET MANAGEMENT
|
||||
//=============================================================================
|
||||
|
||||
omsp_clock_module clock_module_0 (
|
||||
|
||||
// OUTPUTs
|
||||
.aclk (aclk), // ACLK
|
||||
.aclk_en (aclk_en), // ACLK enablex
|
||||
.cpu_en_s (cpu_en_s), // Enable CPU code execution (synchronous)
|
||||
.dbg_clk (dbg_clk), // Debug unit clock
|
||||
.dbg_en_s (dbg_en_s), // Debug interface enable (synchronous)
|
||||
.dbg_rst (dbg_rst), // Debug unit reset
|
||||
.dco_enable (dco_enable), // Fast oscillator enable
|
||||
.dco_wkup (dco_wkup), // Fast oscillator wake-up (asynchronous)
|
||||
.lfxt_enable (lfxt_enable), // Low frequency oscillator enable
|
||||
.lfxt_wkup (lfxt_wkup), // Low frequency oscillator wake-up (asynchronous)
|
||||
.mclk (mclk), // Main system clock
|
||||
.per_dout (per_dout_clk), // Peripheral data output
|
||||
.por (por), // Power-on reset
|
||||
.puc_pnd_set (puc_pnd_set), // PUC pending set for the serial debug interface
|
||||
.puc_rst (puc_rst), // Main system reset
|
||||
.smclk (smclk), // SMCLK
|
||||
.smclk_en (smclk_en), // SMCLK enable
|
||||
|
||||
// INPUTs
|
||||
.cpu_en (cpu_en), // Enable CPU code execution (asynchronous)
|
||||
.cpuoff (cpuoff), // Turns off the CPU
|
||||
.dbg_cpu_reset(dbg_cpu_reset), // Reset CPU from debug interface
|
||||
.dbg_en (dbg_en), // Debug interface enable (asynchronous)
|
||||
.dco_clk (dco_clk), // Fast oscillator (fast clock)
|
||||
.lfxt_clk (lfxt_clk), // Low frequency oscillator (typ 32kHz)
|
||||
.mclk_enable (mclk_enable), // Main System Clock enable
|
||||
.mclk_wkup (mclk_wkup), // Main System Clock wake-up (asynchronous)
|
||||
.oscoff (oscoff), // Turns off LFXT1 clock input
|
||||
.per_addr (per_addr), // Peripheral address
|
||||
.per_din (per_din), // Peripheral data input
|
||||
.per_en (per_en), // Peripheral enable (high active)
|
||||
.per_we (per_we), // Peripheral write enable (high active)
|
||||
.reset_n (reset_n), // Reset Pin (low active, asynchronous)
|
||||
.scan_enable (scan_enable), // Scan enable (active during scan shifting)
|
||||
.scan_mode (scan_mode), // Scan mode
|
||||
.scg0 (scg0), // System clock generator 1. Turns off the DCO
|
||||
.scg1 (scg1), // System clock generator 1. Turns off the SMCLK
|
||||
.wdt_reset (wdt_reset) // Watchdog-timer reset
|
||||
);
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 3) FRONTEND (<=> FETCH & DECODE)
|
||||
//=============================================================================
|
||||
|
||||
omsp_frontend frontend_0 (
|
||||
|
||||
// OUTPUTs
|
||||
.dbg_halt_st (dbg_halt_st), // Halt/Run status from CPU
|
||||
.decode_noirq (decode_noirq), // Frontend decode instruction
|
||||
.e_state (e_state), // Execution state
|
||||
.exec_done (exec_done), // Execution completed
|
||||
.inst_ad (inst_ad), // Decoded Inst: destination addressing mode
|
||||
.inst_as (inst_as), // Decoded Inst: source addressing mode
|
||||
.inst_alu (inst_alu), // ALU control signals
|
||||
.inst_bw (inst_bw), // Decoded Inst: byte width
|
||||
.inst_dest (inst_dest), // Decoded Inst: destination (one hot)
|
||||
.inst_dext (inst_dext), // Decoded Inst: destination extended instruction word
|
||||
.inst_irq_rst (inst_irq_rst), // Decoded Inst: Reset interrupt
|
||||
.inst_jmp (inst_jmp), // Decoded Inst: Conditional jump
|
||||
.inst_mov (inst_mov), // Decoded Inst: mov instruction
|
||||
.inst_sext (inst_sext), // Decoded Inst: source extended instruction word
|
||||
.inst_so (inst_so), // Decoded Inst: Single-operand arithmetic
|
||||
.inst_src (inst_src), // Decoded Inst: source (one hot)
|
||||
.inst_type (inst_type), // Decoded Instruction type
|
||||
.irq_acc (irq_acc), // Interrupt request accepted
|
||||
.mab (fe_mab), // Frontend Memory address bus
|
||||
.mb_en (fe_mb_en), // Frontend Memory bus enable
|
||||
.mclk_enable (mclk_enable), // Main System Clock enable
|
||||
.mclk_wkup (mclk_wkup), // Main System Clock wake-up (asynchronous)
|
||||
.nmi_acc (nmi_acc), // Non-Maskable interrupt request accepted
|
||||
.pc (pc), // Program counter
|
||||
.pc_nxt (pc_nxt), // Next PC value (for CALL & IRQ)
|
||||
|
||||
// INPUTs
|
||||
.cpu_en_s (cpu_en_s), // Enable CPU code execution (synchronous)
|
||||
.cpuoff (cpuoff), // Turns off the CPU
|
||||
.dbg_halt_cmd (dbg_halt_cmd), // Halt CPU command
|
||||
.dbg_reg_sel (dbg_mem_addr[3:0]), // Debug selected register for rd/wr access
|
||||
.fe_pmem_wait (fe_pmem_wait), // Frontend wait for Instruction fetch
|
||||
.gie (gie), // General interrupt enable
|
||||
.irq (irq), // Maskable interrupts
|
||||
.mclk (mclk), // Main system clock
|
||||
.mdb_in (fe_mdb_in), // Frontend Memory data bus input
|
||||
.nmi_pnd (nmi_pnd), // Non-maskable interrupt pending
|
||||
.nmi_wkup (nmi_wkup), // NMI Wakeup
|
||||
.pc_sw (pc_sw), // Program counter software value
|
||||
.pc_sw_wr (pc_sw_wr), // Program counter software write
|
||||
.puc_rst (puc_rst), // Main system reset
|
||||
.scan_enable (scan_enable), // Scan enable (active during scan shifting)
|
||||
.wdt_irq (wdt_irq), // Watchdog-timer interrupt
|
||||
.wdt_wkup (wdt_wkup), // Watchdog Wakeup
|
||||
.wkup (wkup) // System Wake-up (asynchronous)
|
||||
);
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 4) EXECUTION UNIT
|
||||
//=============================================================================
|
||||
|
||||
omsp_execution_unit execution_unit_0 (
|
||||
|
||||
// OUTPUTs
|
||||
.cpuoff (cpuoff), // Turns off the CPU
|
||||
.dbg_reg_din (dbg_reg_din), // Debug unit CPU register data input
|
||||
.mab (eu_mab), // Memory address bus
|
||||
.mb_en (eu_mb_en), // Memory bus enable
|
||||
.mb_wr (eu_mb_wr), // Memory bus write transfer
|
||||
.mdb_out (eu_mdb_out), // Memory data bus output
|
||||
.oscoff (oscoff), // Turns off LFXT1 clock input
|
||||
.pc_sw (pc_sw), // Program counter software value
|
||||
.pc_sw_wr (pc_sw_wr), // Program counter software write
|
||||
.scg0 (scg0), // System clock generator 1. Turns off the DCO
|
||||
.scg1 (scg1), // System clock generator 1. Turns off the SMCLK
|
||||
|
||||
// INPUTs
|
||||
.dbg_halt_st (dbg_halt_st), // Halt/Run status from CPU
|
||||
.dbg_mem_dout (dbg_mem_dout), // Debug unit data output
|
||||
.dbg_reg_wr (dbg_reg_wr), // Debug unit CPU register write
|
||||
.e_state (e_state), // Execution state
|
||||
.exec_done (exec_done), // Execution completed
|
||||
.gie (gie), // General interrupt enable
|
||||
.inst_ad (inst_ad), // Decoded Inst: destination addressing mode
|
||||
.inst_as (inst_as), // Decoded Inst: source addressing mode
|
||||
.inst_alu (inst_alu), // ALU control signals
|
||||
.inst_bw (inst_bw), // Decoded Inst: byte width
|
||||
.inst_dest (inst_dest), // Decoded Inst: destination (one hot)
|
||||
.inst_dext (inst_dext), // Decoded Inst: destination extended instruction word
|
||||
.inst_irq_rst (inst_irq_rst), // Decoded Inst: reset interrupt
|
||||
.inst_jmp (inst_jmp), // Decoded Inst: Conditional jump
|
||||
.inst_mov (inst_mov), // Decoded Inst: mov instruction
|
||||
.inst_sext (inst_sext), // Decoded Inst: source extended instruction word
|
||||
.inst_so (inst_so), // Decoded Inst: Single-operand arithmetic
|
||||
.inst_src (inst_src), // Decoded Inst: source (one hot)
|
||||
.inst_type (inst_type), // Decoded Instruction type
|
||||
.mclk (mclk), // Main system clock
|
||||
.mdb_in (eu_mdb_in), // Memory data bus input
|
||||
.pc (pc), // Program counter
|
||||
.pc_nxt (pc_nxt), // Next PC value (for CALL & IRQ)
|
||||
.puc_rst (puc_rst), // Main system reset
|
||||
.scan_enable (scan_enable) // Scan enable (active during scan shifting)
|
||||
);
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 5) MEMORY BACKBONE
|
||||
//=============================================================================
|
||||
|
||||
omsp_mem_backbone mem_backbone_0 (
|
||||
|
||||
// OUTPUTs
|
||||
.dbg_mem_din (dbg_mem_din), // Debug unit Memory data input
|
||||
.dmem_addr (dmem_addr), // Data Memory address
|
||||
.dmem_cen (dmem_cen), // Data Memory chip enable (low active)
|
||||
.dmem_din (dmem_din), // Data Memory data input
|
||||
.dmem_wen (dmem_wen), // Data Memory write enable (low active)
|
||||
.eu_mdb_in (eu_mdb_in), // Execution Unit Memory data bus input
|
||||
.fe_mdb_in (fe_mdb_in), // Frontend Memory data bus input
|
||||
.fe_pmem_wait (fe_pmem_wait), // Frontend wait for Instruction fetch
|
||||
.per_addr (per_addr), // Peripheral address
|
||||
.per_din (per_din), // Peripheral data input
|
||||
.per_we (per_we), // Peripheral write enable (high active)
|
||||
.per_en (per_en), // Peripheral enable (high active)
|
||||
.pmem_addr (pmem_addr), // Program Memory address
|
||||
.pmem_cen (pmem_cen), // Program Memory chip enable (low active)
|
||||
.pmem_din (pmem_din), // Program Memory data input (optional)
|
||||
.pmem_wen (pmem_wen), // Program Memory write enable (low active) (optional)
|
||||
|
||||
// INPUTs
|
||||
.dbg_halt_st (dbg_halt_st), // Halt/Run status from CPU
|
||||
.dbg_mem_addr (dbg_mem_addr), // Debug address for rd/wr access
|
||||
.dbg_mem_dout (dbg_mem_dout), // Debug unit data output
|
||||
.dbg_mem_en (dbg_mem_en), // Debug unit memory enable
|
||||
.dbg_mem_wr (dbg_mem_wr), // Debug unit memory write
|
||||
.dmem_dout (dmem_dout), // Data Memory data output
|
||||
.eu_mab (eu_mab[15:1]), // Execution Unit Memory address bus
|
||||
.eu_mb_en (eu_mb_en), // Execution Unit Memory bus enable
|
||||
.eu_mb_wr (eu_mb_wr), // Execution Unit Memory bus write transfer
|
||||
.eu_mdb_out (eu_mdb_out), // Execution Unit Memory data bus output
|
||||
.fe_mab (fe_mab[15:1]), // Frontend Memory address bus
|
||||
.fe_mb_en (fe_mb_en), // Frontend Memory bus enable
|
||||
.mclk (mclk), // Main system clock
|
||||
.per_dout (per_dout_or), // Peripheral data output
|
||||
.pmem_dout (pmem_dout), // Program Memory data output
|
||||
.puc_rst (puc_rst), // Main system reset
|
||||
.scan_enable (scan_enable) // Scan enable (active during scan shifting)
|
||||
);
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 6) SPECIAL FUNCTION REGISTERS
|
||||
//=============================================================================
|
||||
omsp_sfr sfr_0 (
|
||||
|
||||
// OUTPUTs
|
||||
.cpu_id (cpu_id), // CPU ID
|
||||
.nmi_pnd (nmi_pnd), // NMI Pending
|
||||
.nmi_wkup (nmi_wkup), // NMI Wakeup
|
||||
.per_dout (per_dout_sfr), // Peripheral data output
|
||||
.wdtie (wdtie), // Watchdog-timer interrupt enable
|
||||
.wdtifg_sw_clr(wdtifg_sw_clr), // Watchdog-timer interrupt flag software clear
|
||||
.wdtifg_sw_set(wdtifg_sw_set), // Watchdog-timer interrupt flag software set
|
||||
|
||||
// INPUTs
|
||||
.mclk (mclk), // Main system clock
|
||||
.nmi (nmi), // Non-maskable interrupt (asynchronous)
|
||||
.nmi_acc (nmi_acc), // Non-Maskable interrupt request accepted
|
||||
.per_addr (per_addr), // Peripheral address
|
||||
.per_din (per_din), // Peripheral data input
|
||||
.per_en (per_en), // Peripheral enable (high active)
|
||||
.per_we (per_we), // Peripheral write enable (high active)
|
||||
.puc_rst (puc_rst), // Main system reset
|
||||
.scan_mode (scan_mode), // Scan mode
|
||||
.wdtifg (wdtifg), // Watchdog-timer interrupt flag
|
||||
.wdtnmies (wdtnmies) // Watchdog-timer NMI edge selection
|
||||
);
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 7) WATCHDOG TIMER
|
||||
//=============================================================================
|
||||
`ifdef WATCHDOG
|
||||
omsp_watchdog watchdog_0 (
|
||||
|
||||
// OUTPUTs
|
||||
.per_dout (per_dout_wdog), // Peripheral data output
|
||||
.wdt_irq (wdt_irq), // Watchdog-timer interrupt
|
||||
.wdt_reset (wdt_reset), // Watchdog-timer reset
|
||||
.wdt_wkup (wdt_wkup), // Watchdog Wakeup
|
||||
.wdtifg (wdtifg), // Watchdog-timer interrupt flag
|
||||
.wdtnmies (wdtnmies), // Watchdog-timer NMI edge selection
|
||||
|
||||
// INPUTs
|
||||
.aclk (aclk), // ACLK
|
||||
.aclk_en (aclk_en), // ACLK enable
|
||||
.dbg_freeze (dbg_freeze), // Freeze Watchdog counter
|
||||
.mclk (mclk), // Main system clock
|
||||
.per_addr (per_addr), // Peripheral address
|
||||
.per_din (per_din), // Peripheral data input
|
||||
.per_en (per_en), // Peripheral enable (high active)
|
||||
.per_we (per_we), // Peripheral write enable (high active)
|
||||
.por (por), // Power-on reset
|
||||
.puc_rst (puc_rst), // Main system reset
|
||||
.scan_enable (scan_enable), // Scan enable (active during scan shifting)
|
||||
.scan_mode (scan_mode), // Scan mode
|
||||
.smclk (smclk), // SMCLK
|
||||
.smclk_en (smclk_en), // SMCLK enable
|
||||
.wdtie (wdtie), // Watchdog-timer interrupt enable
|
||||
.wdtifg_irq_clr (irq_acc[10]), // Clear Watchdog-timer interrupt flag
|
||||
.wdtifg_sw_clr (wdtifg_sw_clr), // Watchdog-timer interrupt flag software clear
|
||||
.wdtifg_sw_set (wdtifg_sw_set) // Watchdog-timer interrupt flag software set
|
||||
);
|
||||
`else
|
||||
assign per_dout_wdog = 16'h0000;
|
||||
assign wdt_irq = 1'b0;
|
||||
assign wdt_reset = 1'b0;
|
||||
assign wdt_wkup = 1'b0;
|
||||
assign wdtifg = 1'b0;
|
||||
assign wdtnmies = 1'b0;
|
||||
`endif
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 8) HARDWARE MULTIPLIER
|
||||
//=============================================================================
|
||||
`ifdef MULTIPLIER
|
||||
omsp_multiplier multiplier_0 (
|
||||
|
||||
// OUTPUTs
|
||||
.per_dout (per_dout_mpy), // Peripheral data output
|
||||
|
||||
// INPUTs
|
||||
.mclk (mclk), // Main system clock
|
||||
.per_addr (per_addr), // Peripheral address
|
||||
.per_din (per_din), // Peripheral data input
|
||||
.per_en (per_en), // Peripheral enable (high active)
|
||||
.per_we (per_we), // Peripheral write enable (high active)
|
||||
.puc_rst (puc_rst), // Main system reset
|
||||
.scan_enable (scan_enable) // Scan enable (active during scan shifting)
|
||||
);
|
||||
`else
|
||||
assign per_dout_mpy = 16'h0000;
|
||||
`endif
|
||||
|
||||
//=============================================================================
|
||||
// 9) PERIPHERALS' OUTPUT BUS
|
||||
//=============================================================================
|
||||
|
||||
assign per_dout_or = per_dout |
|
||||
per_dout_clk |
|
||||
per_dout_sfr |
|
||||
per_dout_wdog |
|
||||
per_dout_mpy;
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// 10) DEBUG INTERFACE
|
||||
//=============================================================================
|
||||
|
||||
`ifdef DBG_EN
|
||||
omsp_dbg dbg_0 (
|
||||
|
||||
// OUTPUTs
|
||||
.dbg_freeze (dbg_freeze), // Freeze peripherals
|
||||
.dbg_halt_cmd (dbg_halt_cmd), // Halt CPU command
|
||||
.dbg_mem_addr (dbg_mem_addr), // Debug address for rd/wr access
|
||||
.dbg_mem_dout (dbg_mem_dout), // Debug unit data output
|
||||
.dbg_mem_en (dbg_mem_en), // Debug unit memory enable
|
||||
.dbg_mem_wr (dbg_mem_wr), // Debug unit memory write
|
||||
.dbg_reg_wr (dbg_reg_wr), // Debug unit CPU register write
|
||||
.dbg_cpu_reset(dbg_cpu_reset), // Reset CPU from debug interface
|
||||
.dbg_uart_txd (dbg_uart_txd), // Debug interface: UART TXD
|
||||
|
||||
// INPUTs
|
||||
.cpu_en_s (cpu_en_s), // Enable CPU code execution (synchronous)
|
||||
.cpu_id (cpu_id), // CPU ID
|
||||
.dbg_clk (dbg_clk), // Debug unit clock
|
||||
.dbg_en_s (dbg_en_s), // Debug interface enable (synchronous)
|
||||
.dbg_halt_st (dbg_halt_st), // Halt/Run status from CPU
|
||||
.dbg_mem_din (dbg_mem_din), // Debug unit Memory data input
|
||||
.dbg_reg_din (dbg_reg_din), // Debug unit CPU register data input
|
||||
.dbg_rst (dbg_rst), // Debug unit reset
|
||||
.dbg_uart_rxd (dbg_uart_rxd), // Debug interface: UART RXD (asynchronous)
|
||||
.decode_noirq (decode_noirq), // Frontend decode instruction
|
||||
.eu_mab (eu_mab), // Execution-Unit Memory address bus
|
||||
.eu_mb_en (eu_mb_en), // Execution-Unit Memory bus enable
|
||||
.eu_mb_wr (eu_mb_wr), // Execution-Unit Memory bus write transfer
|
||||
.eu_mdb_in (eu_mdb_in), // Memory data bus input
|
||||
.eu_mdb_out (eu_mdb_out), // Memory data bus output
|
||||
.exec_done (exec_done), // Execution completed
|
||||
.fe_mb_en (fe_mb_en), // Frontend Memory bus enable
|
||||
.fe_mdb_in (fe_mdb_in), // Frontend Memory data bus input
|
||||
.pc (pc), // Program counter
|
||||
.puc_pnd_set (puc_pnd_set) // PUC pending set for the serial debug interface
|
||||
);
|
||||
|
||||
`else
|
||||
assign dbg_freeze = ~cpu_en_s;
|
||||
assign dbg_halt_cmd = 1'b0;
|
||||
assign dbg_mem_addr = 16'h0000;
|
||||
assign dbg_mem_dout = 16'h0000;
|
||||
assign dbg_mem_en = 1'b0;
|
||||
assign dbg_mem_wr = 2'b00;
|
||||
assign dbg_reg_wr = 1'b0;
|
||||
assign dbg_cpu_reset = 1'b0;
|
||||
assign dbg_uart_txd = 1'b0;
|
||||
`endif
|
||||
|
||||
|
||||
endmodule // openMSP430
|
||||
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_undefines.v"
|
||||
`endif
|
|
@ -1,843 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: openMSP430_defines.v
|
||||
//
|
||||
// *Module Description:
|
||||
// openMSP430 Configuration file
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 151 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2012-07-23 00:24:11 +0200 (Mon, 23 Jul 2012) $
|
||||
//----------------------------------------------------------------------------
|
||||
//`define OMSP_NO_INCLUDE
|
||||
`ifdef OMSP_NO_INCLUDE
|
||||
`else
|
||||
`include "openMSP430_undefines.v"
|
||||
`endif
|
||||
|
||||
//============================================================================
|
||||
//============================================================================
|
||||
// BASIC SYSTEM CONFIGURATION
|
||||
//============================================================================
|
||||
//============================================================================
|
||||
//
|
||||
// Note: the sum of program, data and peripheral memory spaces must not
|
||||
// exceed 64 kB
|
||||
//
|
||||
|
||||
// Program Memory Size:
|
||||
// Uncomment the required memory size
|
||||
//-------------------------------------------------------
|
||||
//`define PMEM_SIZE_CUSTOM
|
||||
//`define PMEM_SIZE_59_KB
|
||||
//`define PMEM_SIZE_55_KB
|
||||
//`define PMEM_SIZE_54_KB
|
||||
//`define PMEM_SIZE_51_KB
|
||||
//`define PMEM_SIZE_48_KB
|
||||
//`define PMEM_SIZE_41_KB
|
||||
//`define PMEM_SIZE_32_KB
|
||||
//`define PMEM_SIZE_24_KB
|
||||
//`define PMEM_SIZE_16_KB
|
||||
//`define PMEM_SIZE_12_KB
|
||||
//`define PMEM_SIZE_8_KB
|
||||
//`define PMEM_SIZE_4_KB
|
||||
`define PMEM_SIZE_2_KB
|
||||
//`define PMEM_SIZE_1_KB
|
||||
|
||||
|
||||
// Data Memory Size:
|
||||
// Uncomment the required memory size
|
||||
//-------------------------------------------------------
|
||||
//`define DMEM_SIZE_CUSTOM
|
||||
//`define DMEM_SIZE_32_KB
|
||||
//`define DMEM_SIZE_24_KB
|
||||
//`define DMEM_SIZE_16_KB
|
||||
//`define DMEM_SIZE_10_KB
|
||||
//`define DMEM_SIZE_8_KB
|
||||
//`define DMEM_SIZE_5_KB
|
||||
//`define DMEM_SIZE_4_KB
|
||||
//`define DMEM_SIZE_2p5_KB
|
||||
//`define DMEM_SIZE_2_KB
|
||||
//`define DMEM_SIZE_1_KB
|
||||
//`define DMEM_SIZE_512_B
|
||||
//`define DMEM_SIZE_256_B
|
||||
`define DMEM_SIZE_128_B
|
||||
|
||||
|
||||
// Include/Exclude Hardware Multiplier
|
||||
`define MULTIPLIER
|
||||
|
||||
|
||||
// Include/Exclude Serial Debug interface
|
||||
`define DBG_EN
|
||||
|
||||
|
||||
//============================================================================
|
||||
//============================================================================
|
||||
// ADVANCED SYSTEM CONFIGURATION (FOR EXPERIENCED USERS)
|
||||
//============================================================================
|
||||
//============================================================================
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Custom user version number
|
||||
//-------------------------------------------------------
|
||||
// This 5 bit field can be freely used in order to allow
|
||||
// custom identification of the system through the debug
|
||||
// interface.
|
||||
// (see CPU_ID.USER_VERSION field in the documentation)
|
||||
//-------------------------------------------------------
|
||||
`define USER_VERSION 5'b00000
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Include/Exclude Watchdog timer
|
||||
//-------------------------------------------------------
|
||||
// When excluded, the following functionality will be
|
||||
// lost:
|
||||
// - Watchog (both interval and watchdog modes)
|
||||
// - NMI interrupt edge selection
|
||||
// - Possibility to generate a software PUC reset
|
||||
//-------------------------------------------------------
|
||||
`define WATCHDOG
|
||||
|
||||
|
||||
///-------------------------------------------------------
|
||||
// Include/Exclude Non-Maskable-Interrupt support
|
||||
//-------------------------------------------------------
|
||||
`define NMI
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Input synchronizers
|
||||
//-------------------------------------------------------
|
||||
// In some cases, the asynchronous input ports might
|
||||
// already be synchronized externally.
|
||||
// If an extensive CDC design review showed that this
|
||||
// is really the case, the individual synchronizers
|
||||
// can be disabled with the following defines.
|
||||
//
|
||||
// Notes:
|
||||
// - all three signals are all sampled in the MCLK domain
|
||||
//
|
||||
// - the dbg_en signal reset the debug interface
|
||||
// when 0. Therefore make sure it is glitch free.
|
||||
//
|
||||
//-------------------------------------------------------
|
||||
`define SYNC_NMI
|
||||
//`define SYNC_CPU_EN
|
||||
//`define SYNC_DBG_EN
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Peripheral Memory Space:
|
||||
//-------------------------------------------------------
|
||||
// The original MSP430 architecture map the peripherals
|
||||
// from 0x0000 to 0x01FF (i.e. 512B of the memory space).
|
||||
// The following defines allow you to expand this space
|
||||
// up to 32 kB (i.e. from 0x0000 to 0x7fff).
|
||||
// As a consequence, the data memory mapping will be
|
||||
// shifted up and a custom linker script will therefore
|
||||
// be required by the GCC compiler.
|
||||
//-------------------------------------------------------
|
||||
//`define PER_SIZE_CUSTOM
|
||||
//`define PER_SIZE_32_KB
|
||||
//`define PER_SIZE_16_KB
|
||||
//`define PER_SIZE_8_KB
|
||||
//`define PER_SIZE_4_KB
|
||||
//`define PER_SIZE_2_KB
|
||||
//`define PER_SIZE_1_KB
|
||||
`define PER_SIZE_512_B
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Defines the debugger CPU_CTL.RST_BRK_EN reset value
|
||||
// (CPU break on PUC reset)
|
||||
//-------------------------------------------------------
|
||||
// When defined, the CPU will automatically break after
|
||||
// a PUC occurrence by default. This is typically useful
|
||||
// when the program memory can only be initialized through
|
||||
// the serial debug interface.
|
||||
//-------------------------------------------------------
|
||||
`define DBG_RST_BRK_EN
|
||||
|
||||
|
||||
//============================================================================
|
||||
//============================================================================
|
||||
// EXPERT SYSTEM CONFIGURATION ( !!!! EXPERTS ONLY !!!! )
|
||||
//============================================================================
|
||||
//============================================================================
|
||||
//
|
||||
// IMPORTANT NOTE: Please update following configuration options ONLY if
|
||||
// you have a good reason to do so... and if you know what
|
||||
// you are doing :-P
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Number of hardware breakpoint/watchpoint units
|
||||
// (each unit contains two hardware addresses available
|
||||
// for breakpoints or watchpoints):
|
||||
// - DBG_HWBRK_0 -> Include hardware breakpoints unit 0
|
||||
// - DBG_HWBRK_1 -> Include hardware breakpoints unit 1
|
||||
// - DBG_HWBRK_2 -> Include hardware breakpoints unit 2
|
||||
// - DBG_HWBRK_3 -> Include hardware breakpoints unit 3
|
||||
//-------------------------------------------------------
|
||||
// Please keep in mind that hardware breakpoints only
|
||||
// make sense whenever the program memory is not an SRAM
|
||||
// (i.e. Flash/OTP/ROM/...) or when you are interested
|
||||
// in data breakpoints.
|
||||
//-------------------------------------------------------
|
||||
//`define DBG_HWBRK_0
|
||||
//`define DBG_HWBRK_1
|
||||
//`define DBG_HWBRK_2
|
||||
//`define DBG_HWBRK_3
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Enable/Disable the hardware breakpoint RANGE mode
|
||||
//-------------------------------------------------------
|
||||
// When enabled this feature allows the hardware breakpoint
|
||||
// units to stop the cpu whenever an instruction or data
|
||||
// access lays within an address range.
|
||||
// Note that this feature is not supported by GDB.
|
||||
//-------------------------------------------------------
|
||||
//`define DBG_HWBRK_RANGE
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// Custom Program/Data and Peripheral Memory Spaces
|
||||
//-------------------------------------------------------
|
||||
// The following values are valid only if the
|
||||
// corresponding *_SIZE_CUSTOM defines are uncommented:
|
||||
//
|
||||
// - *_SIZE : size of the section in bytes.
|
||||
// - *_AWIDTH : address port width, this value must allow
|
||||
// to address all WORDS of the section
|
||||
// (i.e. the *_SIZE divided by 2)
|
||||
//-------------------------------------------------------
|
||||
|
||||
// Custom Program memory (enabled with PMEM_SIZE_CUSTOM)
|
||||
`define PMEM_CUSTOM_AWIDTH 10
|
||||
`define PMEM_CUSTOM_SIZE 2028
|
||||
|
||||
// Custom Data memory (enabled with DMEM_SIZE_CUSTOM)
|
||||
`define DMEM_CUSTOM_AWIDTH 6
|
||||
`define DMEM_CUSTOM_SIZE 128
|
||||
|
||||
// Custom Peripheral memory (enabled with PER_SIZE_CUSTOM)
|
||||
`define PER_CUSTOM_AWIDTH 8
|
||||
`define PER_CUSTOM_SIZE 512
|
||||
|
||||
|
||||
//-------------------------------------------------------
|
||||
// ASIC version
|
||||
//-------------------------------------------------------
|
||||
// When uncommented, this define will enable the
|
||||
// ASIC system configuration section (see below) and
|
||||
// will activate scan support for production test.
|
||||
//
|
||||
// WARNING: if you target an FPGA, leave this define
|
||||
// commented.
|
||||
//-------------------------------------------------------
|
||||
//`define ASIC
|
||||
|
||||
|
||||
//============================================================================
|
||||
//============================================================================
|
||||
// ASIC SYSTEM CONFIGURATION ( !!!! EXPERTS/PROFESSIONALS ONLY !!!! )
|
||||
//============================================================================
|
||||
//============================================================================
|
||||
`ifdef ASIC
|
||||
|
||||
//===============================================================
|
||||
// FINE GRAINED CLOCK GATING
|
||||
//===============================================================
|
||||
|
||||
//-------------------------------------------------------
|
||||
// When uncommented, this define will enable the fine
|
||||
// grained clock gating of all registers in the core.
|
||||
//-------------------------------------------------------
|
||||
`define CLOCK_GATING
|
||||
|
||||
|
||||
//===============================================================
|
||||
// LFXT CLOCK DOMAIN
|
||||
//===============================================================
|
||||
|
||||
//-------------------------------------------------------
|
||||
// When uncommented, this define will enable the lfxt_clk
|
||||
// clock domain.
|
||||
// When commented out, the whole chip is clocked with dco_clk.
|
||||
//-------------------------------------------------------
|
||||
`define LFXT_DOMAIN
|
||||
|
||||
|
||||
//===============================================================
|
||||
// CLOCK MUXES
|
||||
//===============================================================
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MCLK: Clock Mux
|
||||
//-------------------------------------------------------
|
||||
// When uncommented, this define will enable the
|
||||
// MCLK clock MUX allowing the selection between
|
||||
// DCO_CLK and LFXT_CLK with the BCSCTL2.SELMx register.
|
||||
// When commented, DCO_CLK is selected.
|
||||
//-------------------------------------------------------
|
||||
`define MCLK_MUX
|
||||
|
||||
//-------------------------------------------------------
|
||||
// SMCLK: Clock Mux
|
||||
//-------------------------------------------------------
|
||||
// When uncommented, this define will enable the
|
||||
// SMCLK clock MUX allowing the selection between
|
||||
// DCO_CLK and LFXT_CLK with the BCSCTL2.SELS register.
|
||||
// When commented, DCO_CLK is selected.
|
||||
//-------------------------------------------------------
|
||||
`define SMCLK_MUX
|
||||
|
||||
//-------------------------------------------------------
|
||||
// WATCHDOG: Clock Mux
|
||||
//-------------------------------------------------------
|
||||
// When uncommented, this define will enable the
|
||||
// Watchdog clock MUX allowing the selection between
|
||||
// ACLK and SMCLK with the WDTCTL.WDTSSEL register.
|
||||
// When commented out, ACLK is selected if the
|
||||
// WATCHDOG_NOMUX_ACLK define is uncommented, SMCLK is
|
||||
// selected otherwise.
|
||||
//-------------------------------------------------------
|
||||
`define WATCHDOG_MUX
|
||||
//`define WATCHDOG_NOMUX_ACLK
|
||||
|
||||
|
||||
//===============================================================
|
||||
// CLOCK DIVIDERS
|
||||
//===============================================================
|
||||
|
||||
//-------------------------------------------------------
|
||||
// MCLK: Clock divider
|
||||
//-------------------------------------------------------
|
||||
// When uncommented, this define will enable the
|
||||
// MCLK clock divider (/1/2/4/8)
|
||||
//-------------------------------------------------------
|
||||
`define MCLK_DIVIDER
|
||||
|
||||
//-------------------------------------------------------
|
||||
// SMCLK: Clock divider (/1/2/4/8)
|
||||
//-------------------------------------------------------
|
||||
// When uncommented, this define will enable the
|
||||
// SMCLK clock divider
|
||||
//-------------------------------------------------------
|
||||
`define SMCLK_DIVIDER
|
||||
|
||||
//-------------------------------------------------------
|
||||
// ACLK: Clock divider (/1/2/4/8)
|
||||
//-------------------------------------------------------
|
||||
// When uncommented, this define will enable the
|
||||
// ACLK clock divider
|
||||
//-------------------------------------------------------
|
||||
`define ACLK_DIVIDER
|
||||
|
||||
|
||||
//===============================================================
|
||||
// LOW POWER MODES
|
||||
//===============================================================
|
||||
|
||||
//-------------------------------------------------------
|
||||
// LOW POWER MODE: CPUOFF
|
||||
//-------------------------------------------------------
|
||||
// When uncommented, this define will include the
|
||||
// clock gate allowing to switch off MCLK in
|
||||
// all low power modes: LPM0, LPM1, LPM2, LPM3, LPM4
|
||||
//-------------------------------------------------------
|
||||
`define CPUOFF_EN
|
||||
|
||||
//-------------------------------------------------------
|
||||
// LOW POWER MODE: SCG0
|
||||
//-------------------------------------------------------
|
||||
// When uncommented, this define will enable the
|
||||
// DCO_ENABLE/WKUP port control (always 1 when commented).
|
||||
// This allows to switch off the DCO oscillator in the
|
||||
// following low power modes: LPM1, LPM3, LPM4
|
||||
//-------------------------------------------------------
|
||||
`define SCG0_EN
|
||||
|
||||
//-------------------------------------------------------
|
||||
// LOW POWER MODE: SCG1
|
||||
//-------------------------------------------------------
|
||||
// When uncommented, this define will include the
|
||||
// clock gate allowing to switch off SMCLK in
|
||||
// the following low power modes: LPM2, LPM3, LPM4
|
||||
//-------------------------------------------------------
|
||||
`define SCG1_EN
|
||||
|
||||
//-------------------------------------------------------
|
||||
// LOW POWER MODE: OSCOFF
|
||||
//-------------------------------------------------------
|
||||
// When uncommented, this define will include the
|
||||
// LFXT_CLK clock gate and enable the LFXT_ENABLE/WKUP
|
||||
// port control (always 1 when commented).
|
||||
// This allows to switch off the low frequency oscillator
|
||||
// in the following low power modes: LPM4
|
||||
//-------------------------------------------------------
|
||||
`define OSCOFF_EN
|
||||
|
||||
|
||||
|
||||
`endif
|
||||
|
||||
//==========================================================================//
|
||||
//==========================================================================//
|
||||
//==========================================================================//
|
||||
//==========================================================================//
|
||||
//===== SYSTEM CONSTANTS --- !!!!!!!! DO NOT EDIT !!!!!!!! =====//
|
||||
//==========================================================================//
|
||||
//==========================================================================//
|
||||
//==========================================================================//
|
||||
//==========================================================================//
|
||||
|
||||
//
|
||||
// PROGRAM, DATA & PERIPHERAL MEMORY CONFIGURATION
|
||||
//==================================================
|
||||
|
||||
// Program Memory Size
|
||||
`ifdef PMEM_SIZE_59_KB
|
||||
`define PMEM_AWIDTH 15
|
||||
`define PMEM_SIZE 60416
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_55_KB
|
||||
`define PMEM_AWIDTH 15
|
||||
`define PMEM_SIZE 56320
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_54_KB
|
||||
`define PMEM_AWIDTH 15
|
||||
`define PMEM_SIZE 55296
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_51_KB
|
||||
`define PMEM_AWIDTH 15
|
||||
`define PMEM_SIZE 52224
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_48_KB
|
||||
`define PMEM_AWIDTH 15
|
||||
`define PMEM_SIZE 49152
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_41_KB
|
||||
`define PMEM_AWIDTH 15
|
||||
`define PMEM_SIZE 41984
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_32_KB
|
||||
`define PMEM_AWIDTH 14
|
||||
`define PMEM_SIZE 32768
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_24_KB
|
||||
`define PMEM_AWIDTH 14
|
||||
`define PMEM_SIZE 24576
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_16_KB
|
||||
`define PMEM_AWIDTH 13
|
||||
`define PMEM_SIZE 16384
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_12_KB
|
||||
`define PMEM_AWIDTH 13
|
||||
`define PMEM_SIZE 12288
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_8_KB
|
||||
`define PMEM_AWIDTH 12
|
||||
`define PMEM_SIZE 8192
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_4_KB
|
||||
`define PMEM_AWIDTH 11
|
||||
`define PMEM_SIZE 4096
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_2_KB
|
||||
`define PMEM_AWIDTH 10
|
||||
`define PMEM_SIZE 2048
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_1_KB
|
||||
`define PMEM_AWIDTH 9
|
||||
`define PMEM_SIZE 1024
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_CUSTOM
|
||||
`define PMEM_AWIDTH `PMEM_CUSTOM_AWIDTH
|
||||
`define PMEM_SIZE `PMEM_CUSTOM_SIZE
|
||||
`endif
|
||||
|
||||
// Data Memory Size
|
||||
`ifdef DMEM_SIZE_32_KB
|
||||
`define DMEM_AWIDTH 14
|
||||
`define DMEM_SIZE 32768
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_24_KB
|
||||
`define DMEM_AWIDTH 14
|
||||
`define DMEM_SIZE 24576
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_16_KB
|
||||
`define DMEM_AWIDTH 13
|
||||
`define DMEM_SIZE 16384
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_10_KB
|
||||
`define DMEM_AWIDTH 13
|
||||
`define DMEM_SIZE 10240
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_8_KB
|
||||
`define DMEM_AWIDTH 12
|
||||
`define DMEM_SIZE 8192
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_5_KB
|
||||
`define DMEM_AWIDTH 12
|
||||
`define DMEM_SIZE 5120
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_4_KB
|
||||
`define DMEM_AWIDTH 11
|
||||
`define DMEM_SIZE 4096
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_2p5_KB
|
||||
`define DMEM_AWIDTH 11
|
||||
`define DMEM_SIZE 2560
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_2_KB
|
||||
`define DMEM_AWIDTH 10
|
||||
`define DMEM_SIZE 2048
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_1_KB
|
||||
`define DMEM_AWIDTH 9
|
||||
`define DMEM_SIZE 1024
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_512_B
|
||||
`define DMEM_AWIDTH 8
|
||||
`define DMEM_SIZE 512
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_256_B
|
||||
`define DMEM_AWIDTH 7
|
||||
`define DMEM_SIZE 256
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_128_B
|
||||
`define DMEM_AWIDTH 6
|
||||
`define DMEM_SIZE 128
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_CUSTOM
|
||||
`define DMEM_AWIDTH `DMEM_CUSTOM_AWIDTH
|
||||
`define DMEM_SIZE `DMEM_CUSTOM_SIZE
|
||||
`endif
|
||||
|
||||
// Peripheral Memory Size
|
||||
`ifdef PER_SIZE_32_KB
|
||||
`define PER_AWIDTH 14
|
||||
`define PER_SIZE 32768
|
||||
`endif
|
||||
`ifdef PER_SIZE_16_KB
|
||||
`define PER_AWIDTH 13
|
||||
`define PER_SIZE 16384
|
||||
`endif
|
||||
`ifdef PER_SIZE_8_KB
|
||||
`define PER_AWIDTH 12
|
||||
`define PER_SIZE 8192
|
||||
`endif
|
||||
`ifdef PER_SIZE_4_KB
|
||||
`define PER_AWIDTH 11
|
||||
`define PER_SIZE 4096
|
||||
`endif
|
||||
`ifdef PER_SIZE_2_KB
|
||||
`define PER_AWIDTH 10
|
||||
`define PER_SIZE 2048
|
||||
`endif
|
||||
`ifdef PER_SIZE_1_KB
|
||||
`define PER_AWIDTH 9
|
||||
`define PER_SIZE 1024
|
||||
`endif
|
||||
`ifdef PER_SIZE_512_B
|
||||
`define PER_AWIDTH 8
|
||||
`define PER_SIZE 512
|
||||
`endif
|
||||
`ifdef PER_SIZE_CUSTOM
|
||||
`define PER_AWIDTH `PER_CUSTOM_AWIDTH
|
||||
`define PER_SIZE `PER_CUSTOM_SIZE
|
||||
`endif
|
||||
|
||||
// Data Memory Base Adresses
|
||||
`define DMEM_BASE `PER_SIZE
|
||||
|
||||
// Program & Data Memory most significant address bit (for 16 bit words)
|
||||
`define PMEM_MSB `PMEM_AWIDTH-1
|
||||
`define DMEM_MSB `DMEM_AWIDTH-1
|
||||
`define PER_MSB `PER_AWIDTH-1
|
||||
|
||||
//
|
||||
// STATES, REGISTER FIELDS, ...
|
||||
//======================================
|
||||
|
||||
// Instructions type
|
||||
`define INST_SO 0
|
||||
`define INST_JMP 1
|
||||
`define INST_TO 2
|
||||
|
||||
// Single-operand arithmetic
|
||||
`define RRC 0
|
||||
`define SWPB 1
|
||||
`define RRA 2
|
||||
`define SXT 3
|
||||
`define PUSH 4
|
||||
`define CALL 5
|
||||
`define RETI 6
|
||||
`define IRQ 7
|
||||
|
||||
// Conditional jump
|
||||
`define JNE 0
|
||||
`define JEQ 1
|
||||
`define JNC 2
|
||||
`define JC 3
|
||||
`define JN 4
|
||||
`define JGE 5
|
||||
`define JL 6
|
||||
`define JMP 7
|
||||
|
||||
// Two-operand arithmetic
|
||||
`define MOV 0
|
||||
`define ADD 1
|
||||
`define ADDC 2
|
||||
`define SUBC 3
|
||||
`define SUB 4
|
||||
`define CMP 5
|
||||
`define DADD 6
|
||||
`define BIT 7
|
||||
`define BIC 8
|
||||
`define BIS 9
|
||||
`define XOR 10
|
||||
`define AND 11
|
||||
|
||||
// Addressing modes
|
||||
`define DIR 0
|
||||
`define IDX 1
|
||||
`define INDIR 2
|
||||
`define INDIR_I 3
|
||||
`define SYMB 4
|
||||
`define IMM 5
|
||||
`define ABS 6
|
||||
`define CONST 7
|
||||
|
||||
// Instruction state machine
|
||||
`define I_IRQ_FETCH 3'h0
|
||||
`define I_IRQ_DONE 3'h1
|
||||
`define I_DEC 3'h2
|
||||
`define I_EXT1 3'h3
|
||||
`define I_EXT2 3'h4
|
||||
`define I_IDLE 3'h5
|
||||
|
||||
// Execution state machine
|
||||
// (swapped E_IRQ_0 and E_IRQ_2 values to suppress glitch generation warning from lint tool)
|
||||
`define E_IRQ_0 4'h2
|
||||
`define E_IRQ_1 4'h1
|
||||
`define E_IRQ_2 4'h0
|
||||
`define E_IRQ_3 4'h3
|
||||
`define E_IRQ_4 4'h4
|
||||
`define E_SRC_AD 4'h5
|
||||
`define E_SRC_RD 4'h6
|
||||
`define E_SRC_WR 4'h7
|
||||
`define E_DST_AD 4'h8
|
||||
`define E_DST_RD 4'h9
|
||||
`define E_DST_WR 4'hA
|
||||
`define E_EXEC 4'hB
|
||||
`define E_JUMP 4'hC
|
||||
`define E_IDLE 4'hD
|
||||
|
||||
// ALU control signals
|
||||
`define ALU_SRC_INV 0
|
||||
`define ALU_INC 1
|
||||
`define ALU_INC_C 2
|
||||
`define ALU_ADD 3
|
||||
`define ALU_AND 4
|
||||
`define ALU_OR 5
|
||||
`define ALU_XOR 6
|
||||
`define ALU_DADD 7
|
||||
`define ALU_STAT_7 8
|
||||
`define ALU_STAT_F 9
|
||||
`define ALU_SHIFT 10
|
||||
`define EXEC_NO_WR 11
|
||||
|
||||
// Debug interface
|
||||
`define DBG_UART_WR 18
|
||||
`define DBG_UART_BW 17
|
||||
`define DBG_UART_ADDR 16:11
|
||||
|
||||
// Debug interface CPU_CTL register
|
||||
`define HALT 0
|
||||
`define RUN 1
|
||||
`define ISTEP 2
|
||||
`define SW_BRK_EN 3
|
||||
`define FRZ_BRK_EN 4
|
||||
`define RST_BRK_EN 5
|
||||
`define CPU_RST 6
|
||||
|
||||
// Debug interface CPU_STAT register
|
||||
`define HALT_RUN 0
|
||||
`define PUC_PND 1
|
||||
`define SWBRK_PND 3
|
||||
`define HWBRK0_PND 4
|
||||
`define HWBRK1_PND 5
|
||||
|
||||
// Debug interface BRKx_CTL register
|
||||
`define BRK_MODE_RD 0
|
||||
`define BRK_MODE_WR 1
|
||||
`define BRK_MODE 1:0
|
||||
`define BRK_EN 2
|
||||
`define BRK_I_EN 3
|
||||
`define BRK_RANGE 4
|
||||
|
||||
// Basic clock module: BCSCTL1 Control Register
|
||||
`define DIVAx 5:4
|
||||
|
||||
// Basic clock module: BCSCTL2 Control Register
|
||||
`define SELMx 7
|
||||
`define DIVMx 5:4
|
||||
`define SELS 3
|
||||
`define DIVSx 2:1
|
||||
|
||||
// MCLK Clock gate
|
||||
`ifdef CPUOFF_EN
|
||||
`define MCLK_CGATE
|
||||
`else
|
||||
`ifdef MCLK_DIVIDER
|
||||
`define MCLK_CGATE
|
||||
`endif
|
||||
`endif
|
||||
|
||||
// SMCLK Clock gate
|
||||
`ifdef SCG1_EN
|
||||
`define SMCLK_CGATE
|
||||
`else
|
||||
`ifdef SMCLK_DIVIDER
|
||||
`define SMCLK_CGATE
|
||||
`endif
|
||||
`endif
|
||||
|
||||
//
|
||||
// DEBUG INTERFACE EXTRA CONFIGURATION
|
||||
//======================================
|
||||
|
||||
// Debug interface: CPU version
|
||||
`define CPU_VERSION 3'h2
|
||||
|
||||
// Debug interface: Software breakpoint opcode
|
||||
`define DBG_SWBRK_OP 16'h4343
|
||||
|
||||
// Debug UART interface auto data synchronization
|
||||
// If the following define is commented out, then
|
||||
// the DBG_UART_BAUD and DBG_DCO_FREQ need to be properly
|
||||
// defined.
|
||||
`define DBG_UART_AUTO_SYNC
|
||||
|
||||
// Debug UART interface data rate
|
||||
// In order to properly setup the UART debug interface, you
|
||||
// need to specify the DCO_CLK frequency (DBG_DCO_FREQ) and
|
||||
// the chosen BAUD rate from the UART interface.
|
||||
//
|
||||
//`define DBG_UART_BAUD 9600
|
||||
//`define DBG_UART_BAUD 19200
|
||||
//`define DBG_UART_BAUD 38400
|
||||
//`define DBG_UART_BAUD 57600
|
||||
//`define DBG_UART_BAUD 115200
|
||||
//`define DBG_UART_BAUD 230400
|
||||
//`define DBG_UART_BAUD 460800
|
||||
//`define DBG_UART_BAUD 576000
|
||||
//`define DBG_UART_BAUD 921600
|
||||
`define DBG_UART_BAUD 2000000
|
||||
`define DBG_DCO_FREQ 20000000
|
||||
`define DBG_UART_CNT ((`DBG_DCO_FREQ/`DBG_UART_BAUD)-1)
|
||||
|
||||
// Debug interface selection
|
||||
// `define DBG_UART -> Enable UART (8N1) debug interface
|
||||
// `define DBG_JTAG -> DON'T UNCOMMENT, NOT SUPPORTED
|
||||
//
|
||||
`define DBG_UART
|
||||
//`define DBG_JTAG
|
||||
|
||||
// Debug interface input synchronizer
|
||||
`define SYNC_DBG_UART_RXD
|
||||
|
||||
// Enable/Disable the hardware breakpoint RANGE mode
|
||||
`ifdef DBG_HWBRK_RANGE
|
||||
`define HWBRK_RANGE 1'b1
|
||||
`else
|
||||
`define HWBRK_RANGE 1'b0
|
||||
`endif
|
||||
|
||||
// Counter width for the debug interface UART
|
||||
`define DBG_UART_XFER_CNT_W 16
|
||||
|
||||
// Check configuration
|
||||
`ifdef DBG_EN
|
||||
`ifdef DBG_UART
|
||||
`ifdef DBG_JTAG
|
||||
CONFIGURATION ERROR: JTAG AND UART DEBUG INTERFACE ARE BOTH ENABLED
|
||||
`endif
|
||||
`else
|
||||
`ifdef DBG_JTAG
|
||||
CONFIGURATION ERROR: JTAG INTERFACE NOT SUPPORTED
|
||||
`else
|
||||
CONFIGURATION ERROR: JTAG OR UART DEBUG INTERFACE SHOULD BE ENABLED
|
||||
`endif
|
||||
`endif
|
||||
`endif
|
||||
|
||||
//
|
||||
// MULTIPLIER CONFIGURATION
|
||||
//======================================
|
||||
|
||||
// If uncommented, the following define selects
|
||||
// the 16x16 multiplier (1 cycle) instead of the
|
||||
// default 16x8 multplier (2 cycles)
|
||||
//`define MPY_16x16
|
||||
|
||||
//======================================
|
||||
// CONFIGURATION CHECKS
|
||||
//======================================
|
||||
`ifdef LFXT_DOMAIN
|
||||
`else
|
||||
`ifdef MCLK_MUX
|
||||
CONFIGURATION ERROR: THE MCLK_MUX CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL
|
||||
`endif
|
||||
`ifdef SMCLK_MUX
|
||||
CONFIGURATION ERROR: THE SMCLK_MUX CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL
|
||||
`endif
|
||||
`ifdef WATCHDOG_MUX
|
||||
CONFIGURATION ERROR: THE WATCHDOG_MUX CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL
|
||||
`else
|
||||
`ifdef WATCHDOG_NOMUX_ACLK
|
||||
CONFIGURATION ERROR: THE WATCHDOG_NOMUX_ACLK CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL
|
||||
`endif
|
||||
`endif
|
||||
`ifdef OSCOFF_EN
|
||||
CONFIGURATION ERROR: THE OSCOFF LOW POWER MODE CAN ONLY BE ENABLED IF THE LFXT_DOMAIN IS ENABLED AS WELL
|
||||
`endif
|
||||
`endif
|
|
@ -1,732 +0,0 @@
|
|||
//----------------------------------------------------------------------------
|
||||
// Copyright (C) 2009 , Olivier Girard
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of the authors nor the names of its contributors
|
||||
// may be used to endorse or promote products derived from this software
|
||||
// without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
// OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
// THE POSSIBILITY OF SUCH DAMAGE
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// *File Name: openMSP430_undefines.v
|
||||
//
|
||||
// *Module Description:
|
||||
// openMSP430 Verilog `undef file
|
||||
//
|
||||
// *Author(s):
|
||||
// - Olivier Girard, olgirard@gmail.com
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
// $Rev: 23 $
|
||||
// $LastChangedBy: olivier.girard $
|
||||
// $LastChangedDate: 2009-08-30 18:39:26 +0200 (Sun, 30 Aug 2009) $
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// BASIC SYSTEM CONFIGURATION
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Program Memory sizes
|
||||
`ifdef PMEM_SIZE_59_KB
|
||||
`undef PMEM_SIZE_59_KB
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_55_KB
|
||||
`undef PMEM_SIZE_55_KB
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_54_KB
|
||||
`undef PMEM_SIZE_54_KB
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_51_KB
|
||||
`undef PMEM_SIZE_51_KB
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_48_KB
|
||||
`undef PMEM_SIZE_48_KB
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_41_KB
|
||||
`undef PMEM_SIZE_41_KB
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_32_KB
|
||||
`undef PMEM_SIZE_32_KB
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_24_KB
|
||||
`undef PMEM_SIZE_24_KB
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_16_KB
|
||||
`undef PMEM_SIZE_16_KB
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_12_KB
|
||||
`undef PMEM_SIZE_12_KB
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_8_KB
|
||||
`undef PMEM_SIZE_8_KB
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_4_KB
|
||||
`undef PMEM_SIZE_4_KB
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_2_KB
|
||||
`undef PMEM_SIZE_2_KB
|
||||
`endif
|
||||
`ifdef PMEM_SIZE_1_KB
|
||||
`undef PMEM_SIZE_1_KB
|
||||
`endif
|
||||
|
||||
// Data Memory sizes
|
||||
`ifdef DMEM_SIZE_32_KB
|
||||
`undef DMEM_SIZE_32_KB
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_24_KB
|
||||
`undef DMEM_SIZE_24_KB
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_16_KB
|
||||
`undef DMEM_SIZE_16_KB
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_10_KB
|
||||
`undef DMEM_SIZE_10_KB
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_8_KB
|
||||
`undef DMEM_SIZE_8_KB
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_5_KB
|
||||
`undef DMEM_SIZE_5_KB
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_4_KB
|
||||
`undef DMEM_SIZE_4_KB
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_2p5_KB
|
||||
`undef DMEM_SIZE_2p5_KB
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_2_KB
|
||||
`undef DMEM_SIZE_2_KB
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_1_KB
|
||||
`undef DMEM_SIZE_1_KB
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_512_B
|
||||
`undef DMEM_SIZE_512_B
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_256_B
|
||||
`undef DMEM_SIZE_256_B
|
||||
`endif
|
||||
`ifdef DMEM_SIZE_128_B
|
||||
`undef DMEM_SIZE_128_B
|
||||
`endif
|
||||
|
||||
// Include/Exclude Hardware Multiplier
|
||||
`ifdef MULTIPLIER
|
||||
`undef MULTIPLIER
|
||||
`endif
|
||||
|
||||
// Include Debug interface
|
||||
`ifdef DBG_EN
|
||||
`undef DBG_EN
|
||||
`endif
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ADVANCED SYSTEM CONFIGURATION (FOR EXPERIENCED USERS)
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Peripheral Memory Space:
|
||||
`ifdef PER_SIZE_32_KB
|
||||
`undef PER_SIZE_32_KB
|
||||
`endif
|
||||
`ifdef PER_SIZE_16_KB
|
||||
`undef PER_SIZE_16_KB
|
||||
`endif
|
||||
`ifdef PER_SIZE_8_KB
|
||||
`undef PER_SIZE_8_KB
|
||||
`endif
|
||||
`ifdef PER_SIZE_4_KB
|
||||
`undef PER_SIZE_4_KB
|
||||
`endif
|
||||
`ifdef PER_SIZE_2_KB
|
||||
`undef PER_SIZE_2_KB
|
||||
`endif
|
||||
`ifdef PER_SIZE_1_KB
|
||||
`undef PER_SIZE_1_KB
|
||||
`endif
|
||||
`ifdef PER_SIZE_512_B
|
||||
`undef PER_SIZE_512_B
|
||||
`endif
|
||||
|
||||
// Let the CPU break after a PUC occurrence by default
|
||||
`ifdef DBG_RST_BRK_EN
|
||||
`undef DBG_RST_BRK_EN
|
||||
`endif
|
||||
|
||||
// Custom user version number
|
||||
`ifdef USER_VERSION
|
||||
`undef USER_VERSION
|
||||
`endif
|
||||
|
||||
// Include/Exclude Watchdog timer
|
||||
`ifdef WATCHDOG
|
||||
`undef WATCHDOG
|
||||
`endif
|
||||
|
||||
// Include/Exclude Non-Maskable-Interrupt support
|
||||
`ifdef NMI
|
||||
`undef NMI
|
||||
`endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// EXPERT SYSTEM CONFIGURATION ( !!!! EXPERTS ONLY !!!! )
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Number of hardware breakpoint units
|
||||
`ifdef DBG_HWBRK_0
|
||||
`undef DBG_HWBRK_0
|
||||
`endif
|
||||
`ifdef DBG_HWBRK_1
|
||||
`undef DBG_HWBRK_1
|
||||
`endif
|
||||
`ifdef DBG_HWBRK_2
|
||||
`undef DBG_HWBRK_2
|
||||
`endif
|
||||
`ifdef DBG_HWBRK_3
|
||||
`undef DBG_HWBRK_3
|
||||
`endif
|
||||
|
||||
// Enable/Disable the hardware breakpoint RANGE mode
|
||||
`ifdef DBG_HWBRK_RANGE
|
||||
`undef DBG_HWBRK_RANGE
|
||||
`endif
|
||||
|
||||
// Input synchronizers
|
||||
`ifdef SYNC_CPU_EN
|
||||
`undef SYNC_CPU_EN
|
||||
`endif
|
||||
`ifdef SYNC_DBG_EN
|
||||
`undef SYNC_DBG_EN
|
||||
`endif
|
||||
`ifdef SYNC_DBG_UART_RXD
|
||||
`undef SYNC_DBG_UART_RXD
|
||||
`endif
|
||||
`ifdef SYNC_NMI
|
||||
`undef SYNC_NMI
|
||||
`endif
|
||||
|
||||
// ASIC version
|
||||
`ifdef ASIC
|
||||
`undef ASIC
|
||||
`endif
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// ASIC SYSTEM CONFIGURATION ( !!!! EXPERTS ONLY !!!! )
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// Fine grained clock gating
|
||||
`ifdef CLOCK_GATING
|
||||
`undef CLOCK_GATING
|
||||
`endif
|
||||
|
||||
// LFXT clock domain
|
||||
`ifdef LFXT_DOMAIN
|
||||
`undef LFXT_DOMAIN
|
||||
`endif
|
||||
|
||||
// MCLK: Clock Mux
|
||||
`ifdef MCLK_MUX
|
||||
`undef MCLK_MUX
|
||||
`endif
|
||||
|
||||
// SMCLK: Clock Mux
|
||||
`ifdef SMCLK_MUX
|
||||
`undef SMCLK_MUX
|
||||
`endif
|
||||
|
||||
// WATCHDOG: Clock Mux
|
||||
`ifdef WATCHDOG_MUX
|
||||
`undef WATCHDOG_MUX
|
||||
`endif
|
||||
|
||||
// MCLK: Clock divider
|
||||
`ifdef MCLK_DIVIDER
|
||||
`undef MCLK_DIVIDER
|
||||
`endif
|
||||
|
||||
// SMCLK: Clock divider (/1/2/4/8)
|
||||
`ifdef SMCLK_DIVIDER
|
||||
`undef SMCLK_DIVIDER
|
||||
`endif
|
||||
|
||||
// ACLK: Clock divider (/1/2/4/8)
|
||||
`ifdef ACLK_DIVIDER
|
||||
`undef ACLK_DIVIDER
|
||||
`endif
|
||||
|
||||
// LOW POWER MODE: CPUOFF
|
||||
`ifdef CPUOFF_EN
|
||||
`undef CPUOFF_EN
|
||||
`endif
|
||||
|
||||
// LOW POWER MODE: OSCOFF
|
||||
`ifdef OSCOFF_EN
|
||||
`undef OSCOFF_EN
|
||||
`endif
|
||||
|
||||
// LOW POWER MODE: SCG0
|
||||
`ifdef SCG0_EN
|
||||
`undef SCG0_EN
|
||||
`endif
|
||||
|
||||
// LOW POWER MODE: SCG1
|
||||
`ifdef SCG1_EN
|
||||
`undef SCG1_EN
|
||||
`endif
|
||||
|
||||
|
||||
//==========================================================================//
|
||||
//==========================================================================//
|
||||
//==========================================================================//
|
||||
//==========================================================================//
|
||||
//===== SYSTEM CONSTANTS --- !!!!!!!! DO NOT EDIT !!!!!!!! =====//
|
||||
//==========================================================================//
|
||||
//==========================================================================//
|
||||
//==========================================================================//
|
||||
//==========================================================================//
|
||||
|
||||
// Program Memory Size
|
||||
`ifdef PMEM_AWIDTH
|
||||
`undef PMEM_AWIDTH
|
||||
`endif
|
||||
`ifdef PMEM_SIZE
|
||||
`undef PMEM_SIZE
|
||||
`endif
|
||||
|
||||
// Data Memory Size
|
||||
`ifdef DMEM_AWIDTH
|
||||
`undef DMEM_AWIDTH
|
||||
`endif
|
||||
`ifdef DMEM_SIZE
|
||||
`undef DMEM_SIZE
|
||||
`endif
|
||||
|
||||
// Peripheral Memory Size
|
||||
`ifdef PER_AWIDTH
|
||||
`undef PER_AWIDTH
|
||||
`endif
|
||||
`ifdef PER_SIZE
|
||||
`undef PER_SIZE
|
||||
`endif
|
||||
|
||||
// Data Memory Base Adresses
|
||||
`ifdef DMEM_BASE
|
||||
`undef DMEM_BASE
|
||||
`endif
|
||||
|
||||
// Program & Data Memory most significant address bit (for 16 bit words)
|
||||
`ifdef PMEM_MSB
|
||||
`undef PMEM_MSB
|
||||
`endif
|
||||
`ifdef DMEM_MSB
|
||||
`undef DMEM_MSB
|
||||
`endif
|
||||
`ifdef PER_MSB
|
||||
`undef PER_MSB
|
||||
`endif
|
||||
|
||||
// Instructions type
|
||||
`ifdef INST_SO
|
||||
`undef INST_SO
|
||||
`endif
|
||||
`ifdef INST_JMP
|
||||
`undef INST_JMP
|
||||
`endif
|
||||
`ifdef INST_TO
|
||||
`undef INST_TO
|
||||
`endif
|
||||
|
||||
// Single-operand arithmetic
|
||||
`ifdef RRC
|
||||
`undef RRC
|
||||
`endif
|
||||
`ifdef SWPB
|
||||
`undef SWPB
|
||||
`endif
|
||||
`ifdef RRA
|
||||
`undef RRA
|
||||
`endif
|
||||
`ifdef SXT
|
||||
`undef SXT
|
||||
`endif
|
||||
`ifdef PUSH
|
||||
`undef PUSH
|
||||
`endif
|
||||
`ifdef CALL
|
||||
`undef CALL
|
||||
`endif
|
||||
`ifdef RETI
|
||||
`undef RETI
|
||||
`endif
|
||||
`ifdef IRQ
|
||||
`undef IRQ
|
||||
`endif
|
||||
|
||||
// Conditional jump
|
||||
`ifdef JNE
|
||||
`undef JNE
|
||||
`endif
|
||||
`ifdef JEQ
|
||||
`undef JEQ
|
||||
`endif
|
||||
`ifdef JNC
|
||||
`undef JNC
|
||||
`endif
|
||||
`ifdef JC
|
||||
`undef JC
|
||||
`endif
|
||||
`ifdef JN
|
||||
`undef JN
|
||||
`endif
|
||||
`ifdef JGE
|
||||
`undef JGE
|
||||
`endif
|
||||
`ifdef JL
|
||||
`undef JL
|
||||
`endif
|
||||
`ifdef JMP
|
||||
`undef JMP
|
||||
`endif
|
||||
|
||||
// Two-operand arithmetic
|
||||
`ifdef MOV
|
||||
`undef MOV
|
||||
`endif
|
||||
`ifdef ADD
|
||||
`undef ADD
|
||||
`endif
|
||||
`ifdef ADDC
|
||||
`undef ADDC
|
||||
`endif
|
||||
`ifdef SUBC
|
||||
`undef SUBC
|
||||
`endif
|
||||
`ifdef SUB
|
||||
`undef SUB
|
||||
`endif
|
||||
`ifdef CMP
|
||||
`undef CMP
|
||||
`endif
|
||||
`ifdef DADD
|
||||
`undef DADD
|
||||
`endif
|
||||
`ifdef BIT
|
||||
`undef BIT
|
||||
`endif
|
||||
`ifdef BIC
|
||||
`undef BIC
|
||||
`endif
|
||||
`ifdef BIS
|
||||
`undef BIS
|
||||
`endif
|
||||
`ifdef XOR
|
||||
`undef XOR
|
||||
`endif
|
||||
`ifdef AND
|
||||
`undef AND
|
||||
`endif
|
||||
|
||||
// Addressing modes
|
||||
`ifdef DIR
|
||||
`undef DIR
|
||||
`endif
|
||||
`ifdef IDX
|
||||
`undef IDX
|
||||
`endif
|
||||
`ifdef INDIR
|
||||
`undef INDIR
|
||||
`endif
|
||||
`ifdef INDIR_I
|
||||
`undef INDIR_I
|
||||
`endif
|
||||
`ifdef SYMB
|
||||
`undef SYMB
|
||||
`endif
|
||||
`ifdef IMM
|
||||
`undef IMM
|
||||
`endif
|
||||
`ifdef ABS
|
||||
`undef ABS
|
||||
`endif
|
||||
`ifdef CONST
|
||||
`undef CONST
|
||||
`endif
|
||||
|
||||
// Instruction state machine
|
||||
`ifdef I_IRQ_FETCH
|
||||
`undef I_IRQ_FETCH
|
||||
`endif
|
||||
`ifdef I_IRQ_DONE
|
||||
`undef I_IRQ_DONE
|
||||
`endif
|
||||
`ifdef I_DEC
|
||||
`undef I_DEC
|
||||
`endif
|
||||
`ifdef I_EXT1
|
||||
`undef I_EXT1
|
||||
`endif
|
||||
`ifdef I_EXT2
|
||||
`undef I_EXT2
|
||||
`endif
|
||||
`ifdef I_IDLE
|
||||
`undef I_IDLE
|
||||
`endif
|
||||
|
||||
// Execution state machine
|
||||
`ifdef E_IRQ_0
|
||||
`undef E_IRQ_0
|
||||
`endif
|
||||
`ifdef E_IRQ_1
|
||||
`undef E_IRQ_1
|
||||
`endif
|
||||
`ifdef E_IRQ_2
|
||||
`undef E_IRQ_2
|
||||
`endif
|
||||
`ifdef E_IRQ_3
|
||||
`undef E_IRQ_3
|
||||
`endif
|
||||
`ifdef E_IRQ_4
|
||||
`undef E_IRQ_4
|
||||
`endif
|
||||
`ifdef E_SRC_AD
|
||||
`undef E_SRC_AD
|
||||
`endif
|
||||
`ifdef E_SRC_RD
|
||||
`undef E_SRC_RD
|
||||
`endif
|
||||
`ifdef E_SRC_WR
|
||||
`undef E_SRC_WR
|
||||
`endif
|
||||
`ifdef E_DST_AD
|
||||
`undef E_DST_AD
|
||||
`endif
|
||||
`ifdef E_DST_RD
|
||||
`undef E_DST_RD
|
||||
`endif
|
||||
`ifdef E_DST_WR
|
||||
`undef E_DST_WR
|
||||
`endif
|
||||
`ifdef E_EXEC
|
||||
`undef E_EXEC
|
||||
`endif
|
||||
`ifdef E_JUMP
|
||||
`undef E_JUMP
|
||||
`endif
|
||||
`ifdef E_IDLE
|
||||
`undef E_IDLE
|
||||
`endif
|
||||
|
||||
// ALU control signals
|
||||
`ifdef ALU_SRC_INV
|
||||
`undef ALU_SRC_INV
|
||||
`endif
|
||||
`ifdef ALU_INC
|
||||
`undef ALU_INC
|
||||
`endif
|
||||
`ifdef ALU_INC_C
|
||||
`undef ALU_INC_C
|
||||
`endif
|
||||
`ifdef ALU_ADD
|
||||
`undef ALU_ADD
|
||||
`endif
|
||||
`ifdef ALU_AND
|
||||
`undef ALU_AND
|
||||
`endif
|
||||
`ifdef ALU_OR
|
||||
`undef ALU_OR
|
||||
`endif
|
||||
`ifdef ALU_XOR
|
||||
`undef ALU_XOR
|
||||
`endif
|
||||
`ifdef ALU_DADD
|
||||
`undef ALU_DADD
|
||||
`endif
|
||||
`ifdef ALU_STAT_7
|
||||
`undef ALU_STAT_7
|
||||
`endif
|
||||
`ifdef ALU_STAT_F
|
||||
`undef ALU_STAT_F
|
||||
`endif
|
||||
`ifdef ALU_SHIFT
|
||||
`undef ALU_SHIFT
|
||||
`endif
|
||||
`ifdef EXEC_NO_WR
|
||||
`undef EXEC_NO_WR
|
||||
`endif
|
||||
|
||||
// Debug interface
|
||||
`ifdef DBG_UART_WR
|
||||
`undef DBG_UART_WR
|
||||
`endif
|
||||
`ifdef DBG_UART_BW
|
||||
`undef DBG_UART_BW
|
||||
`endif
|
||||
`ifdef DBG_UART_ADDR
|
||||
`undef DBG_UART_ADDR
|
||||
`endif
|
||||
|
||||
// Debug interface CPU_CTL register
|
||||
`ifdef HALT
|
||||
`undef HALT
|
||||
`endif
|
||||
`ifdef RUN
|
||||
`undef RUN
|
||||
`endif
|
||||
`ifdef ISTEP
|
||||
`undef ISTEP
|
||||
`endif
|
||||
`ifdef SW_BRK_EN
|
||||
`undef SW_BRK_EN
|
||||
`endif
|
||||
`ifdef FRZ_BRK_EN
|
||||
`undef FRZ_BRK_EN
|
||||
`endif
|
||||
`ifdef RST_BRK_EN
|
||||
`undef RST_BRK_EN
|
||||
`endif
|
||||
`ifdef CPU_RST
|
||||
`undef CPU_RST
|
||||
`endif
|
||||
|
||||
// Debug interface CPU_STAT register
|
||||
`ifdef HALT_RUN
|
||||
`undef HALT_RUN
|
||||
`endif
|
||||
`ifdef PUC_PND
|
||||
`undef PUC_PND
|
||||
`endif
|
||||
`ifdef SWBRK_PND
|
||||
`undef SWBRK_PND
|
||||
`endif
|
||||
`ifdef HWBRK0_PND
|
||||
`undef HWBRK0_PND
|
||||
`endif
|
||||
`ifdef HWBRK1_PND
|
||||
`undef HWBRK1_PND
|
||||
`endif
|
||||
|
||||
// Debug interface BRKx_CTL register
|
||||
`ifdef BRK_MODE_RD
|
||||
`undef BRK_MODE_RD
|
||||
`endif
|
||||
`ifdef BRK_MODE_WR
|
||||
`undef BRK_MODE_WR
|
||||
`endif
|
||||
`ifdef BRK_MODE
|
||||
`undef BRK_MODE
|
||||
`endif
|
||||
`ifdef BRK_EN
|
||||
`undef BRK_EN
|
||||
`endif
|
||||
`ifdef BRK_I_EN
|
||||
`undef BRK_I_EN
|
||||
`endif
|
||||
`ifdef BRK_RANGE
|
||||
`undef BRK_RANGE
|
||||
`endif
|
||||
|
||||
// Basic clock module: BCSCTL1 Control Register
|
||||
`ifdef DIVAx
|
||||
`undef DIVAx
|
||||
`endif
|
||||
|
||||
// Basic clock module: BCSCTL2 Control Register
|
||||
`ifdef SELMx
|
||||
`undef SELMx
|
||||
`endif
|
||||
`ifdef DIVMx
|
||||
`undef DIVMx
|
||||
`endif
|
||||
`ifdef SELS
|
||||
`undef SELS
|
||||
`endif
|
||||
`ifdef DIVSx
|
||||
`undef DIVSx
|
||||
`endif
|
||||
|
||||
// MCLK Clock gate
|
||||
`ifdef MCLK_CGATE
|
||||
`undef MCLK_CGATE
|
||||
`endif
|
||||
|
||||
// SMCLK Clock gate
|
||||
`ifdef SMCLK_CGATE
|
||||
`undef SMCLK_CGATE
|
||||
`endif
|
||||
|
||||
//
|
||||
// DEBUG INTERFACE EXTRA CONFIGURATION
|
||||
//======================================
|
||||
|
||||
// Debug interface: CPU version
|
||||
`ifdef CPU_VERSION
|
||||
`undef CPU_VERSION
|
||||
`endif
|
||||
|
||||
// Debug interface: Software breakpoint opcode
|
||||
`ifdef DBG_SWBRK_OP
|
||||
`undef DBG_SWBRK_OP
|
||||
`endif
|
||||
|
||||
// Debug UART interface auto data synchronization
|
||||
`ifdef DBG_UART_AUTO_SYNC
|
||||
`undef DBG_UART_AUTO_SYNC
|
||||
`endif
|
||||
|
||||
// Debug UART interface data rate
|
||||
`ifdef DBG_UART_BAUD
|
||||
`undef DBG_UART_BAUD
|
||||
`endif
|
||||
`ifdef DBG_DCO_FREQ
|
||||
`undef DBG_DCO_FREQ
|
||||
`endif
|
||||
`ifdef DBG_UART_CNT
|
||||
`undef DBG_UART_CNT
|
||||
`endif
|
||||
|
||||
// Debug interface selection
|
||||
`ifdef DBG_UART
|
||||
`undef DBG_UART
|
||||
`endif
|
||||
`ifdef DBG_JTAG
|
||||
`undef DBG_JTAG
|
||||
`endif
|
||||
|
||||
// Enable/Disable the hardware breakpoint RANGE mode
|
||||
`ifdef HWBRK_RANGE
|
||||
`undef HWBRK_RANGE
|
||||
`endif
|
||||
|
||||
// Counter width for the debug interface UART
|
||||
`ifdef DBG_UART_XFER_CNT_W
|
||||
`undef DBG_UART_XFER_CNT_W
|
||||
`endif
|
||||
|
||||
//
|
||||
// MULTIPLIER CONFIGURATION
|
||||
//======================================
|
||||
|
||||
`ifdef MPY_16x16
|
||||
`undef MPY_16x16
|
||||
`endif
|
|
@ -1,37 +0,0 @@
|
|||
|
||||
set hdlin_ignore_full_case false
|
||||
set hdlin_ignore_parallel_case false
|
||||
set svf_ignore_unqualified_fsm_information true
|
||||
set hdlin_warn_on_mismatch_message "FMR_ELAB-115 FMR_VLOG-079 FMR_VLOG-091"
|
||||
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_alu.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_and_gate.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_clock_gate.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_clock_module.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_clock_mux.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_dbg_hwbrk.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_dbg_uart.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_dbg.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_execution_unit.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_frontend.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_mem_backbone.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_multiplier.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_register_file.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_scan_mux.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_sfr.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_sync_cell.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_sync_reset.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_wakeup_cell.v
|
||||
read_verilog -container r -libname WORK -01 rtl/omsp_watchdog.v
|
||||
read_verilog -container r -libname WORK -01 rtl/openMSP430.v
|
||||
set_top r:/WORK/openMSP430
|
||||
|
||||
read_verilog -container i -libname WORK -01 synth.v
|
||||
read_verilog -container i -technology_library -libname TECH_WORK -01 ../../techlibs/stdcells_sim.v
|
||||
read_verilog -container i -technology_library -libname TECH_WORK -01 sim_mul.v
|
||||
set_top i:/WORK/openMSP430
|
||||
|
||||
source fsm_info.txt
|
||||
|
||||
if ![verify] start_gui exit
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
if [ -n "$REMOTE_YOSYS_ROOT" ]; then
|
||||
rsync --exclude=".svn" --exclude="*.log" -rv -e "${REMOTE_YOSYS_SSH:-ssh} -C" "$REMOTE_YOSYS_ROOT"/tests/openmsp430/. .
|
||||
fi
|
||||
fm_shell -64 -file run-fm.do 2>&1 | tee run-fm.log
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/bash
|
||||
time ../../yosys -b "verilog -noexpr" -o synth.v -tl synth.log -s run-synth.ys \
|
||||
rtl/omsp_*.v rtl/openMSP430.v 2>&1 | egrep '^\[[0-9.]+\] (ERROR|-- |[0-9]+\.)'
|
|
@ -1,11 +0,0 @@
|
|||
hierarchy -check -top openMSP430
|
||||
proc
|
||||
opt
|
||||
memory
|
||||
opt
|
||||
fsm -fm_set_fsm_file fsm_info.txt
|
||||
opt
|
||||
techmap
|
||||
opt
|
||||
abc
|
||||
opt
|
|
@ -1,29 +0,0 @@
|
|||
|
||||
module \$mul (A, B, Y);
|
||||
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
input [A_WIDTH-1:0] A;
|
||||
generate if (A_SIGNED) begin:A_BUF
|
||||
wire signed [A_WIDTH-1:0] val = A;
|
||||
end else begin:A_BUF
|
||||
wire [A_WIDTH-1:0] val = A;
|
||||
end endgenerate
|
||||
|
||||
input [B_WIDTH-1:0] B;
|
||||
generate if (B_SIGNED) begin:B_BUF
|
||||
wire signed [B_WIDTH-1:0] val = B;
|
||||
end else begin:B_BUF
|
||||
wire [B_WIDTH-1:0] val = B;
|
||||
end endgenerate
|
||||
|
||||
output [Y_WIDTH-1:0] Y;
|
||||
|
||||
assign Y = A_BUF.val * B_BUF.val;
|
||||
|
||||
endmodule
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
Index: or1200_defines.v
|
||||
===================================================================
|
||||
--- or1200_defines.v (revision 812)
|
||||
+++ or1200_defines.v (working copy)
|
||||
@@ -56,7 +56,7 @@
|
||||
//
|
||||
//`define OR1200_VERBOSE
|
||||
|
||||
-// `define OR1200_ASIC
|
||||
+`define OR1200_ASIC
|
||||
////////////////////////////////////////////////////////
|
||||
//
|
||||
// Typical configuration for an ASIC
|
||||
@@ -69,7 +69,7 @@
|
||||
//`define OR1200_ARTISAN_SSP
|
||||
//`define OR1200_ARTISAN_SDP
|
||||
//`define OR1200_ARTISAN_STP
|
||||
-`define OR1200_VIRTUALSILICON_SSP
|
||||
+//`define OR1200_VIRTUALSILICON_SSP
|
||||
//`define OR1200_VIRTUALSILICON_STP_T1
|
||||
//`define OR1200_VIRTUALSILICON_STP_T2
|
||||
|
||||
@@ -96,17 +96,17 @@
|
||||
//
|
||||
// Select between ASIC optimized and generic multiplier
|
||||
//
|
||||
-//`define OR1200_ASIC_MULTP2_32X32
|
||||
-`define OR1200_GENERIC_MULTP2_32X32
|
||||
+`define OR1200_ASIC_MULTP2_32X32
|
||||
+//`define OR1200_GENERIC_MULTP2_32X32
|
||||
|
||||
//
|
||||
// Size/type of insn/data cache if implemented
|
||||
//
|
||||
-// `define OR1200_IC_1W_512B
|
||||
+`define OR1200_IC_1W_512B
|
||||
// `define OR1200_IC_1W_4KB
|
||||
-`define OR1200_IC_1W_8KB
|
||||
-// `define OR1200_DC_1W_4KB
|
||||
-`define OR1200_DC_1W_8KB
|
||||
+// `define OR1200_IC_1W_8KB
|
||||
+`define OR1200_DC_1W_4KB
|
||||
+// `define OR1200_DC_1W_8KB
|
||||
|
||||
`else
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
rm -rf rtl
|
||||
svn co http://opencores.org/ocsvn/openrisc/openrisc/trunk/or1200/rtl/verilog rtl
|
||||
( cd rtl; patch -p0 < ../config.patch; )
|
|
@ -1,24 +0,0 @@
|
|||
#!/bin/bash
|
||||
if [ -n "$REMOTE_YOSYS_ROOT" ]; then
|
||||
rsync --exclude=".svn" --exclude="*.log" -rv -e "${REMOTE_YOSYS_SSH:-ssh} -C" "$REMOTE_YOSYS_ROOT"/tests/or1200/. .
|
||||
fi
|
||||
for mod in $( grep '^module or1200_' synth.v | awk -F '[ (]' '{ print $2; }'; )
|
||||
do
|
||||
{
|
||||
grep '^set ' run-fm.do
|
||||
grep '^read_verilog -container r ' run-fm.do
|
||||
echo "set_top r:/WORK/$mod"
|
||||
grep '^read_verilog -container i ' run-fm.do
|
||||
echo "set_top i:/WORK/$mod"
|
||||
echo "verify"
|
||||
echo "exit"
|
||||
} > run-fm-${mod}.do
|
||||
fm_shell -64 -file run-fm-${mod}.do 2>&1 | tee run-fm-${mod}.log
|
||||
rsync -v -e "${REMOTE_YOSYS_SSH:-ssh}" run-fm-${mod}.log "$REMOTE_YOSYS_ROOT"/tests/or1200/
|
||||
done
|
||||
|
||||
echo; echo
|
||||
for x in run-fm-*.log; do
|
||||
echo -e "${x%/*}\\t$( egrep '^Verification (SUCCEEDED|FAILED)' $x; )"
|
||||
done | expand -t20
|
||||
echo; echo
|
|
@ -1,53 +0,0 @@
|
|||
|
||||
set hdlin_ignore_full_case false
|
||||
set hdlin_warn_on_mismatch_message "FMR_ELAB-115 FMR_VLOG-079 FMR_VLOG-091"
|
||||
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_alu.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_amultp2_32x32.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_cfgr.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_cpu.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_ctrl.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_dc_fsm.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_dc_ram.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_dc_tag.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_dc_top.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_dmmu_tlb.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_dmmu_top.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_dpram.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_du.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_except.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_fpu.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_freeze.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_genpc.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_ic_fsm.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_ic_ram.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_ic_tag.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_ic_top.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_if.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_immu_tlb.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_immu_top.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_lsu.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_mem2reg.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_mult_mac.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_operandmuxes.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_pic.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_pm.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_qmem_top.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_reg2mem.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_rf.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_sb.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_spram_32_bw.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_spram.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_sprs.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_top.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_tt.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_wb_biu.v
|
||||
read_verilog -container r -libname WORK -01 rtl/or1200_wbmux.v
|
||||
set_top r:/WORK/or1200_top
|
||||
|
||||
read_verilog -container i -libname WORK -01 synth.v
|
||||
read_verilog -container i -technology_library -libname TECH_WORK -01 ../../techlibs/stdcells_sim.v
|
||||
set_top i:/WORK/or1200_top
|
||||
|
||||
if ![verify] start_gui exit
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
if [ -n "$REMOTE_YOSYS_ROOT" ]; then
|
||||
rsync --exclude=".svn" --exclude="*.log" -rv -e "${REMOTE_YOSYS_SSH:-ssh} -C" "$REMOTE_YOSYS_ROOT"/tests/or1200/. .
|
||||
fi
|
||||
fm_shell -64 -file run-fm.do 2>&1 | tee run-fm.log
|
|
@ -1,2 +0,0 @@
|
|||
#!/bin/bash
|
||||
time ../../yosys -b "verilog -noexpr" -o synth.v -tl synth.log -s run-synth.ys rtl/or1200_*.v 2>&1 | egrep '^\[[0-9.]+\] (ERROR|--|[0-9]+\.)'
|
|
@ -1,11 +0,0 @@
|
|||
hierarchy -check -top or1200_top
|
||||
proc
|
||||
opt
|
||||
memory
|
||||
opt
|
||||
# fsm -norecode
|
||||
# opt
|
||||
techmap
|
||||
opt
|
||||
abc
|
||||
opt
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
time valgrind --leak-check=full --show-reachable=yes --log-file=valgrind.log \
|
||||
../../yosys -o synth.v -tl synth.log -p "hierarchy -check -top or1200_top" \
|
||||
-p opt_const -p proc -p memory -p opt -p techmap -p opt -p abc -p opt rtl/or1200_*.v
|
Loading…
Add table
Reference in a new issue