mirror of https://github.com/lnis-uofu/SOFA.git
add testcases for ap3 arch evaluation
This commit is contained in:
parent
255b29b59d
commit
60850586d4
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,225 @@
|
|||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Team: Virginia Tech Secure Embedded Systems (SES) Lab
|
||||
// Implementer: Ege Gulcan
|
||||
//
|
||||
// Create Date: 17:21:26 11/13/2013
|
||||
// Design Name:
|
||||
// Module Name: simon_datapath_shiftreg
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
module simon_datapath_shiftreg(clk,data_in,data_rdy,key_in,cipher_out,round_counter,bit_counter);
|
||||
|
||||
input clk,data_in,key_in;
|
||||
input [1:0] data_rdy;
|
||||
input round_counter;
|
||||
output cipher_out;
|
||||
output [5:0] bit_counter;
|
||||
|
||||
reg [55:0] shifter1;
|
||||
reg [63:0] shifter2;
|
||||
reg shift_in1,shift_in2;
|
||||
wire shift_out1,shift_out2;
|
||||
reg shifter_enable1,shifter_enable2;
|
||||
|
||||
reg fifo_ff63,fifo_ff62,fifo_ff61,fifo_ff60,fifo_ff59,fifo_ff58,fifo_ff57,fifo_ff56;
|
||||
reg lut_ff63,lut_ff62,lut_ff61,lut_ff60,lut_ff59,lut_ff58,lut_ff57,lut_ff56;
|
||||
|
||||
reg lut_ff_input,fifo_ff_input;
|
||||
reg lut_rol1,lut_rol2,lut_rol8;
|
||||
reg s1,s4,s5,s6,s7;
|
||||
reg [1:0] s3;
|
||||
reg [5:0] bit_counter;
|
||||
wire lut_out;
|
||||
|
||||
|
||||
|
||||
// Shift Register1 FIFO 56x1 Begin
|
||||
// 56x1 Shift register to store the upper word
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if(shifter_enable1)
|
||||
begin
|
||||
shifter1 <= {shift_in1, shifter1[55:1]};
|
||||
end
|
||||
end
|
||||
|
||||
assign shift_out1 = shifter1[0];
|
||||
// Shift Register1 End
|
||||
|
||||
// Shift Register2 FIFO 64x1 Begin
|
||||
// 64x1 Shift register to store the lower word
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if(shifter_enable2)
|
||||
begin
|
||||
shifter2 <= {shift_in2, shifter2[63:1]};
|
||||
end
|
||||
end
|
||||
|
||||
assign shift_out2 = shifter2[0];
|
||||
// Shift Register2 End
|
||||
|
||||
|
||||
// 8 Flip-Flops to store the most significant 8 bits of the upper word at even rounds
|
||||
// Denoted as Shift Register Up (SRU) in Figure 5
|
||||
always@(posedge clk)
|
||||
begin
|
||||
if(shifter_enable1)
|
||||
begin
|
||||
fifo_ff63 <= fifo_ff_input;
|
||||
fifo_ff62 <= fifo_ff63;
|
||||
fifo_ff61 <= fifo_ff62;
|
||||
fifo_ff60 <= fifo_ff61;
|
||||
fifo_ff59 <= fifo_ff60;
|
||||
fifo_ff58 <= fifo_ff59;
|
||||
fifo_ff57 <= fifo_ff58;
|
||||
fifo_ff56 <= fifo_ff57;
|
||||
end
|
||||
end
|
||||
|
||||
// 8 Flip-Flops to store the most significant 8 bits of the upper word at odd rounds
|
||||
// Denoted as Shift Register Down (SRD) in Figure 5
|
||||
always@(posedge clk)
|
||||
begin
|
||||
lut_ff63 <= lut_ff_input;
|
||||
lut_ff62 <= lut_ff63;
|
||||
lut_ff61 <= lut_ff62;
|
||||
lut_ff60 <= lut_ff61;
|
||||
lut_ff59 <= lut_ff60;
|
||||
lut_ff58 <= lut_ff59;
|
||||
lut_ff57 <= lut_ff58;
|
||||
lut_ff56 <= lut_ff57;
|
||||
end
|
||||
|
||||
// FIFO 64x1 Input MUX
|
||||
// Input of the lower FIFO is always the output of the upper FIFO
|
||||
always@(*)
|
||||
begin
|
||||
shift_in2 = shift_out1;
|
||||
end
|
||||
|
||||
// FIFO 56x1 Input MUX
|
||||
// Input of the upper FIFO depends on the select line S1
|
||||
always@(*)
|
||||
begin
|
||||
if(s1==0)
|
||||
shift_in1 = lut_ff56;
|
||||
else
|
||||
shift_in1 = fifo_ff56;
|
||||
end
|
||||
|
||||
// FIFO FF Input MUX
|
||||
// The input of FIFO_FF can be the input plaintext, output of 56x1 FIFO or the output of LUT
|
||||
always@(*)
|
||||
begin
|
||||
if(s3==0)
|
||||
fifo_ff_input = data_in;
|
||||
else if(s3==1)
|
||||
fifo_ff_input = shift_out1;
|
||||
else if(s3==2)
|
||||
fifo_ff_input = lut_out;
|
||||
else
|
||||
fifo_ff_input = 1'bx; // Debugging
|
||||
end
|
||||
|
||||
// LUT FF Input MUX
|
||||
// The input of the LUT_FF is either the output of 56x1 FIFO or the output of LUT
|
||||
always@(*)
|
||||
begin
|
||||
if(s5==0)
|
||||
lut_ff_input = shift_out1;
|
||||
else
|
||||
lut_ff_input = lut_out;
|
||||
end
|
||||
|
||||
// LUT Input MUX
|
||||
always@(*)
|
||||
begin
|
||||
if(s7==0)
|
||||
lut_rol1 = fifo_ff63;
|
||||
else
|
||||
lut_rol1 = lut_ff63;
|
||||
|
||||
if(s4==0)
|
||||
lut_rol2 = fifo_ff62;
|
||||
else
|
||||
lut_rol2 = lut_ff62;
|
||||
|
||||
if(s6==0)
|
||||
lut_rol8 = fifo_ff56;
|
||||
else
|
||||
lut_rol8 = lut_ff56;
|
||||
end
|
||||
|
||||
//Selection MUX
|
||||
always@(*)
|
||||
begin
|
||||
// For the first 8 bits of each even round OR for all the bits after the first 8 bits in odd rounds OR loading the plaintext
|
||||
if((round_counter==0 && bit_counter<8)||(round_counter==1 && bit_counter>7)||(data_rdy==1))
|
||||
s1 = 1;
|
||||
else
|
||||
s1 = 0;
|
||||
|
||||
if(data_rdy==1) // Loading plaintext
|
||||
s3 = 0;
|
||||
else if(round_counter==0) // Even rounds
|
||||
s3 = 1;
|
||||
else if(round_counter==1) // Odd rounds
|
||||
s3 = 2;
|
||||
else
|
||||
s3 = 1'bx; // For debugging
|
||||
|
||||
if(round_counter==0) // Even rounds
|
||||
s6 = 0;
|
||||
else
|
||||
s6 = 1;
|
||||
|
||||
s4 = s6;
|
||||
s7 = s6;
|
||||
s5 = ~s6;
|
||||
end
|
||||
|
||||
// SHIFTER ENABLES
|
||||
// Two shift registers are enabled when the plaintext is being loaded (1) or when the block cipher is running (3)
|
||||
always@(*)
|
||||
begin
|
||||
if(data_rdy==1 || data_rdy==3)
|
||||
begin
|
||||
shifter_enable1 = 1;
|
||||
shifter_enable2 = 1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
shifter_enable1 = 0;
|
||||
shifter_enable2 = 0;
|
||||
end
|
||||
end
|
||||
|
||||
// The bit_counter value is incremented in each clock cycle when the block cipher is running
|
||||
always@(posedge clk)
|
||||
begin
|
||||
if(data_rdy==0)
|
||||
bit_counter <= 0;
|
||||
else if(data_rdy==3)
|
||||
bit_counter <= bit_counter + 1;
|
||||
else
|
||||
bit_counter <= bit_counter;
|
||||
end
|
||||
|
||||
// The new computed value
|
||||
assign lut_out = (lut_rol1 & lut_rol8) ^ shift_out2 ^ lut_rol2 ^ key_in;
|
||||
|
||||
// The global output that gives the ciphertext value
|
||||
assign cipher_out = lut_out;
|
||||
endmodule
|
|
@ -0,0 +1,241 @@
|
|||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Team: Virginia Tech Secure Embedded Systems (SES) Lab
|
||||
// Implementer: Ege Gulcan
|
||||
//
|
||||
// Create Date: 16:55:06 11/12/2013
|
||||
// Design Name:
|
||||
// Module Name: simon_key_expansion_shiftreg
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module simon_key_expansion_shiftreg(clk,data_in,key_out,data_rdy,bit_counter,round_counter_out);
|
||||
|
||||
input clk;
|
||||
input data_in;
|
||||
input [1:0] data_rdy;
|
||||
input [5:0] bit_counter;
|
||||
output key_out;
|
||||
output round_counter_out;
|
||||
|
||||
|
||||
reg [59:0] shifter1;
|
||||
reg [63:0] shifter2;
|
||||
reg shift_in1,shift_in2;
|
||||
wire shift_out1,shift_out2;
|
||||
reg shifter_enable1,shifter_enable2;
|
||||
|
||||
reg lut_ff_enable,fifo_ff_enable;
|
||||
wire lut_out;
|
||||
reg lut_in3;
|
||||
reg s2,s3;
|
||||
reg [1:0] s1;
|
||||
reg [6:0] round_counter;
|
||||
reg z_value;
|
||||
|
||||
reg fifo_ff0,fifo_ff1,fifo_ff2,fifo_ff3;
|
||||
|
||||
//(* shreg_extract = "no" *)
|
||||
reg lut_ff0,lut_ff1,lut_ff2,lut_ff3;
|
||||
//Constant value Z ROM
|
||||
reg [0:67] Z = 68'b10101111011100000011010010011000101000010001111110010110110011101011;
|
||||
reg c;
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
//// BEGIN CODE ////////////////////////
|
||||
///////////////////////////////////////
|
||||
|
||||
// Least bit of the round counter is sent to the datapath to check if it is even or odd
|
||||
assign round_counter_out = round_counter[0];
|
||||
|
||||
// Shift Register1 FIFO 60x1 Begin
|
||||
// 60x1 shift register storing the 60 most significant bits of the upper word of the key
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if(shifter_enable1)
|
||||
begin
|
||||
shifter1 <= {shift_in1, shifter1[59:1]};
|
||||
end
|
||||
end
|
||||
|
||||
assign shift_out1 = shifter1[0];
|
||||
// Shift Register1 End
|
||||
|
||||
// Shift Register2 FIFO 64x1 Begin
|
||||
// 64x1 shift register storing the lower word of the key
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if(shifter_enable2)
|
||||
begin
|
||||
shifter2 <= {shift_in2, shifter2[63:1]};
|
||||
end
|
||||
end
|
||||
|
||||
assign shift_out2 = shifter2[0];
|
||||
// Shift Register2 End
|
||||
|
||||
// 4 flip-flops storing the least significant 4 bits of the upper word in the first round
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if(fifo_ff_enable)
|
||||
begin
|
||||
fifo_ff3 <= shift_out1;
|
||||
fifo_ff2 <= fifo_ff3;
|
||||
fifo_ff1 <= fifo_ff2;
|
||||
fifo_ff0 <= fifo_ff1;
|
||||
end
|
||||
end
|
||||
|
||||
// 4 flip-flops storing the least significant 4 bits of the upper word after the first round
|
||||
always@(posedge clk)
|
||||
begin
|
||||
if(lut_ff_enable)
|
||||
begin
|
||||
lut_ff3 <= lut_out;
|
||||
lut_ff2 <= lut_ff3;
|
||||
lut_ff1 <= lut_ff2;
|
||||
lut_ff0 <= lut_ff1;
|
||||
end
|
||||
end
|
||||
|
||||
//FIFO 64x1 Input MUX
|
||||
always@(*)
|
||||
begin
|
||||
if(data_rdy==2)
|
||||
shift_in2 = fifo_ff0;
|
||||
else if(data_rdy==3 && (round_counter<1 || bit_counter>3))
|
||||
shift_in2 = fifo_ff0;
|
||||
else if(data_rdy==3 && bit_counter<4 && round_counter>0)
|
||||
shift_in2 = lut_ff0;
|
||||
else
|
||||
shift_in2 = 1'bx;
|
||||
end
|
||||
|
||||
//LUT >>3 Input MUX
|
||||
always@(*)
|
||||
begin
|
||||
if(s2==0)
|
||||
lut_in3 = fifo_ff3;
|
||||
else
|
||||
lut_in3 = lut_ff3;
|
||||
end
|
||||
|
||||
//FIFO 60x1 Input MUX
|
||||
always@(*)
|
||||
begin
|
||||
if(s1==0)
|
||||
shift_in1 = fifo_ff0;
|
||||
else if(s1==1)
|
||||
shift_in1 = data_in;
|
||||
else if(s1==2)
|
||||
shift_in1 = lut_out;
|
||||
else if(s1==3)
|
||||
shift_in1 = lut_ff0;
|
||||
else
|
||||
shift_in1 = 1'bx;
|
||||
end
|
||||
|
||||
//S2 MUX
|
||||
always@(*)
|
||||
begin
|
||||
if(bit_counter==0 && round_counter!=0)
|
||||
s2 = 1;
|
||||
else
|
||||
s2 = 0;
|
||||
end
|
||||
|
||||
//S1 MUX
|
||||
always@(*)
|
||||
begin
|
||||
if(data_rdy==2)
|
||||
s1 = 1;
|
||||
else if(data_rdy==3 && bit_counter<4 && round_counter==0)
|
||||
s1 = 0;
|
||||
else if(data_rdy==3 && bit_counter<4 && round_counter>0)
|
||||
s1 = 3;
|
||||
else
|
||||
s1 = 2;
|
||||
end
|
||||
|
||||
// LUT FF ENABLE MUX
|
||||
// LUT FFs are used only at the first four clock cycles of each round
|
||||
always@(*)
|
||||
begin
|
||||
if(data_rdy==3 && bit_counter<4)
|
||||
lut_ff_enable = 1;
|
||||
else
|
||||
lut_ff_enable = 0;
|
||||
end
|
||||
|
||||
//FIFO FF ENABLE MUX
|
||||
always@(*)
|
||||
begin
|
||||
if(data_rdy==2 || data_rdy==3)
|
||||
fifo_ff_enable = 1;
|
||||
else
|
||||
fifo_ff_enable = 0;
|
||||
end
|
||||
|
||||
//SHIFTER ENABLES
|
||||
// Shifters are enabled when the key is loaded or block cipher is running
|
||||
always@(*)
|
||||
begin
|
||||
if(data_rdy==2 || data_rdy==3)
|
||||
shifter_enable1 = 1;
|
||||
else
|
||||
shifter_enable1 = 0;
|
||||
|
||||
if(data_rdy==2 || data_rdy==3)
|
||||
shifter_enable2 = 1;
|
||||
else
|
||||
shifter_enable2 = 0;
|
||||
|
||||
end
|
||||
|
||||
//Round Counter
|
||||
always@(posedge clk)
|
||||
begin
|
||||
if(data_rdy==3 && bit_counter==63)
|
||||
round_counter <= round_counter + 1;
|
||||
else if(data_rdy==0)
|
||||
round_counter <= 0;
|
||||
else
|
||||
round_counter <= round_counter;
|
||||
end
|
||||
|
||||
// The necessary bit of the constant Z is selected by the round counter
|
||||
always @(*)
|
||||
begin
|
||||
if(bit_counter==0)
|
||||
z_value = Z[round_counter];
|
||||
else
|
||||
z_value = 0;
|
||||
end
|
||||
|
||||
// The value of c is 1 at the first two cycles of each round only
|
||||
always @(*)
|
||||
begin
|
||||
if(bit_counter==0 || bit_counter==1)
|
||||
c = 0;
|
||||
else
|
||||
c = 1;
|
||||
end
|
||||
|
||||
// New computed key bit
|
||||
assign lut_out = shift_out2 ^ lut_in3 ^ shift_out1 ^ z_value ^ c;
|
||||
|
||||
// Output key bit that is connected to the datapath
|
||||
assign key_out = shift_out2;
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,45 @@
|
|||
`timescale 1ns / 1ps
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Team: Virginia Tech Secure Embedded Systems (SES) Lab
|
||||
// Implementer: Ege Gulcan
|
||||
//
|
||||
// Create Date: 19:14:37 11/13/2013
|
||||
// Design Name:
|
||||
// Module Name: top_module
|
||||
// Project Name:
|
||||
// Target Devices:
|
||||
// Tool versions:
|
||||
// Description:
|
||||
//
|
||||
// Dependencies:
|
||||
//
|
||||
// Revision:
|
||||
// Revision 0.01 - File Created
|
||||
// Additional Comments:
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
module Simon_bit_serial_top(clk,data_in,data_rdy,cipher_out);
|
||||
|
||||
input clk,data_in;
|
||||
input [1:0] data_rdy;
|
||||
output cipher_out;
|
||||
|
||||
wire key;
|
||||
wire [5:0] bit_counter;
|
||||
wire round_counter_out;
|
||||
|
||||
/*
|
||||
data_rdy=0 -> Reset, Idle
|
||||
data_rdy=1 -> Load Plaintext
|
||||
data_rdy=2 -> Load Key
|
||||
data_rdy=3 -> Run (keep at 3 while the block cipher is running)
|
||||
*/
|
||||
|
||||
simon_datapath_shiftreg datapath(.clk(clk), .data_in(data_in), .data_rdy(data_rdy), .key_in(key),
|
||||
. cipher_out(cipher_out), .round_counter(round_counter_out), .bit_counter(bit_counter));
|
||||
|
||||
simon_key_expansion_shiftreg key_exp(.clk(clk), .data_in(data_in), .data_rdy(data_rdy), .key_out(key), .bit_counter(bit_counter),
|
||||
.round_counter_out(round_counter_out));
|
||||
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,143 @@
|
|||
/*-------------------------------------------------------------------
|
||||
CM_FIFO_1x
|
||||
Communication Manager (CM) FIFO, using 1 RAM block.
|
||||
18-bit write port (512 deep), 9-bit read port (1024 deep).
|
||||
|
||||
The LSB on the write port will be the first byte to appear on
|
||||
the read port.
|
||||
|
||||
Valid data appears on the output data port without first
|
||||
having to do a pop.
|
||||
|
||||
Over-run and under-run protection are both implemented:
|
||||
reads when empty will be ignored and provide invalid data,
|
||||
writes when full will be ignored.
|
||||
|
||||
-------------------------------------------------------------------*/
|
||||
|
||||
|
||||
`timescale 1ns / 10ps
|
||||
|
||||
module CM_FIFO_1x (
|
||||
rst,
|
||||
|
||||
push_clk,
|
||||
push,
|
||||
din,
|
||||
full,
|
||||
push_flag,
|
||||
overflow,
|
||||
|
||||
pop_clk,
|
||||
pop,
|
||||
dout,
|
||||
empty,
|
||||
pop_flag,
|
||||
|
||||
CM_FIFO_1x_din_o ,
|
||||
CM_FIFO_1x_push_int_o ,
|
||||
CM_FIFO_1x_pop_int_o ,
|
||||
CM_FIFO_1x_push_clk_o ,
|
||||
CM_FIFO_1x_pop_clk_o ,
|
||||
CM_FIFO_1x_rst_o ,
|
||||
|
||||
CM_FIFO_1x_almost_full_i ,
|
||||
CM_FIFO_1x_almost_empty_i ,
|
||||
CM_FIFO_1x_push_flag_i ,
|
||||
CM_FIFO_1x_pop_flag_i ,
|
||||
CM_FIFO_1x_dout_i
|
||||
|
||||
|
||||
);
|
||||
|
||||
input rst;
|
||||
|
||||
input push_clk;
|
||||
input push;
|
||||
input [17:0] din;
|
||||
output full;
|
||||
output [3:0] push_flag;
|
||||
output overflow;
|
||||
|
||||
input pop_clk;
|
||||
input pop;
|
||||
output [8:0] dout;
|
||||
output empty;
|
||||
output [3:0] pop_flag;
|
||||
|
||||
output [17:0] CM_FIFO_1x_din_o ;
|
||||
output CM_FIFO_1x_push_int_o ;
|
||||
output CM_FIFO_1x_pop_int_o ;
|
||||
output CM_FIFO_1x_push_clk_o ;
|
||||
output CM_FIFO_1x_pop_clk_o ;
|
||||
output CM_FIFO_1x_rst_o ;
|
||||
|
||||
input CM_FIFO_1x_almost_full_i ;
|
||||
input CM_FIFO_1x_almost_empty_i ;
|
||||
input [3:0] CM_FIFO_1x_push_flag_i ;
|
||||
input [3:0] CM_FIFO_1x_pop_flag_i ;
|
||||
input [8:0] CM_FIFO_1x_dout_i ;
|
||||
|
||||
|
||||
|
||||
reg overflow;
|
||||
|
||||
|
||||
wire push_int;
|
||||
wire pop_int;
|
||||
reg pop_r1, pop_r2, pop_r3;
|
||||
|
||||
|
||||
// over-run/under-run protection
|
||||
assign push_int = full ? 1'b0 : push;
|
||||
|
||||
// changed to match the current S2 functionality
|
||||
//assign pop_int = empty ? 1'b0 : pop;
|
||||
assign pop_int = empty ? 1'b0 : (pop_r2 ^ pop_r3);
|
||||
|
||||
|
||||
assign CM_FIFO_1x_din_o = din;
|
||||
assign CM_FIFO_1x_push_int_o = push_int;
|
||||
assign CM_FIFO_1x_pop_int_o = pop_int;
|
||||
assign CM_FIFO_1x_push_clk_o = push_clk;
|
||||
assign CM_FIFO_1x_pop_clk_o = pop_clk;
|
||||
assign CM_FIFO_1x_rst_o = rst;
|
||||
assign almost_full = CM_FIFO_1x_almost_full_i;
|
||||
assign almost_empty = CM_FIFO_1x_almost_empty_i;
|
||||
assign push_flag = CM_FIFO_1x_push_flag_i;
|
||||
assign pop_flag = CM_FIFO_1x_pop_flag_i;
|
||||
assign dout = CM_FIFO_1x_dout_i;
|
||||
|
||||
|
||||
|
||||
|
||||
assign full = (push_flag == 4'h0);
|
||||
assign empty = (pop_flag == 4'h0);
|
||||
|
||||
|
||||
// overflow detection
|
||||
always @(posedge push_clk or posedge rst)
|
||||
if (rst)
|
||||
overflow <= 0;
|
||||
else
|
||||
if (push && full)
|
||||
overflow <= 1;
|
||||
else
|
||||
overflow <= 0;
|
||||
|
||||
/// Synchronize SPI FIFO Read to SPI CLock due to delay
|
||||
always @(posedge pop_clk or posedge rst)
|
||||
if (rst) begin
|
||||
pop_r1 <= 1'b0;
|
||||
pop_r2 <= 1'b0;
|
||||
pop_r3 <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
pop_r1 <= pop;
|
||||
pop_r2 <= pop_r1;
|
||||
pop_r3 <= pop_r2;
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
/*-----------------------------------------------------------------------------
|
||||
CM_FIFO_autodrain
|
||||
This module will auto-drain (read from) the CM FIFO when RingBufferMode
|
||||
is enabled. It will stop on packet boundaries (designated by bit 8 of
|
||||
the FIFO data).
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
`timescale 1ns / 10ps
|
||||
|
||||
|
||||
module CM_FIFO_autodrain (
|
||||
input rst,
|
||||
input FFE_CLK_gclk,
|
||||
|
||||
input RingBufferMode,
|
||||
input [3:0] CM_FIFO_PushFlags,
|
||||
input CM_FIFO_Empty,
|
||||
input CM_FIFO_PopFromTLC,
|
||||
input [8:0] CM_FIFO_ReadData,
|
||||
|
||||
output CM_FIFO_Pop,
|
||||
output busy,
|
||||
output TP1,
|
||||
output TP2
|
||||
);
|
||||
|
||||
|
||||
// state definitions
|
||||
localparam ST_IDLE = 3'b000;
|
||||
localparam ST_SETBUSY1 = 3'b001;
|
||||
localparam ST_SETBUSY2 = 3'b010;
|
||||
localparam ST_WAIT = 3'b011;
|
||||
localparam ST_READ = 3'b100;
|
||||
|
||||
|
||||
wire SOP_Marker;
|
||||
wire FIFO_AutoRead_Threshold;
|
||||
reg RingBufferMode_r1;
|
||||
reg RingBufferMode_r2;
|
||||
reg [2:0] state;
|
||||
reg busy_reg;
|
||||
reg CM_FIFO_PopAutoDrain;
|
||||
|
||||
|
||||
assign SOP_Marker = CM_FIFO_ReadData[8];
|
||||
|
||||
|
||||
/* PUSH_FLAG:
|
||||
0x0: full
|
||||
0x1: empty
|
||||
0x2: room for 1/2 to (full - 1)
|
||||
0x3: room for 1/4 to (1/2 -1)
|
||||
0x4: room for 64 to (1/4 - 1)
|
||||
0xA: room for 32 to 63
|
||||
0xB: room for 16 to 31
|
||||
0xC: room for 8 to 15
|
||||
0xD: room for 4 to 7
|
||||
0xE: room for 2 to 3
|
||||
0xF: room for 1
|
||||
others: reserved */
|
||||
|
||||
assign FIFO_AutoRead_Threshold = ((CM_FIFO_PushFlags == 4'h0) || (CM_FIFO_PushFlags[3])); // full or (63 or less) 16-bit words
|
||||
|
||||
|
||||
// sync RingBufferMode to the FFE clk
|
||||
always @(posedge rst or posedge FFE_CLK_gclk)
|
||||
if (rst) begin
|
||||
RingBufferMode_r1 <= 0;
|
||||
RingBufferMode_r2 <= 0;
|
||||
end
|
||||
else begin
|
||||
RingBufferMode_r1 <= RingBufferMode;
|
||||
RingBufferMode_r2 <= RingBufferMode_r1;
|
||||
end
|
||||
|
||||
|
||||
// state machine
|
||||
always @(posedge rst or posedge FFE_CLK_gclk)
|
||||
if (rst)
|
||||
state <= ST_IDLE;
|
||||
else
|
||||
case (state)
|
||||
ST_IDLE: if (RingBufferMode_r2)
|
||||
state <= ST_SETBUSY1;
|
||||
else
|
||||
state <= ST_IDLE;
|
||||
|
||||
ST_SETBUSY1: state <= ST_SETBUSY2; // allow time for the FIFO read clock to switch safely
|
||||
|
||||
ST_SETBUSY2: state <= ST_WAIT;
|
||||
|
||||
ST_WAIT: if (!RingBufferMode_r2)
|
||||
state <= ST_IDLE;
|
||||
else
|
||||
state <= ST_READ;
|
||||
|
||||
ST_READ: if (SOP_Marker && !RingBufferMode_r2)
|
||||
state <= ST_SETBUSY1; // goto ST_SETBUSY1 to allow time to switch to SPI_SCLK
|
||||
else
|
||||
state <= ST_READ;
|
||||
endcase
|
||||
|
||||
|
||||
// busy
|
||||
wire busy_reg_reset;
|
||||
assign busy_reg_reset = rst || !RingBufferMode;
|
||||
always @(posedge busy_reg_reset or posedge FFE_CLK_gclk)
|
||||
if (busy_reg_reset)
|
||||
busy_reg <= 0;
|
||||
else
|
||||
case (busy_reg)
|
||||
1'b0: if ((state == ST_IDLE) && (RingBufferMode_r2))
|
||||
busy_reg <= 1;
|
||||
else
|
||||
busy_reg <= 0;
|
||||
1'b1: if (((state == ST_SETBUSY1) && !RingBufferMode_r2) || (state == ST_IDLE))
|
||||
busy_reg <= 0;
|
||||
else
|
||||
busy_reg <= 1;
|
||||
endcase
|
||||
|
||||
|
||||
|
||||
// FIFO Read control
|
||||
always @(*)
|
||||
if (state == ST_READ) // pop only allowed in ST_READ state...
|
||||
if (!CM_FIFO_Empty) // ...and FIFO not empty
|
||||
if (!SOP_Marker) // if not on SOP marker, keep reading
|
||||
CM_FIFO_PopAutoDrain <= 1;
|
||||
else // (SOP_Marker)
|
||||
if (FIFO_AutoRead_Threshold && RingBufferMode_r2) // if SOP marker, read next packet if FIFO is at or past threshold and RingBufferMode still on
|
||||
CM_FIFO_PopAutoDrain <= 1;
|
||||
else
|
||||
CM_FIFO_PopAutoDrain <= 0; // else pop=0
|
||||
else // (CM_FIFO_Empty)
|
||||
CM_FIFO_PopAutoDrain <= 0;
|
||||
else // (state != ST_READ)
|
||||
CM_FIFO_PopAutoDrain <= 0;
|
||||
|
||||
|
||||
assign CM_FIFO_Pop = busy_reg ? CM_FIFO_PopAutoDrain : CM_FIFO_PopFromTLC;
|
||||
|
||||
assign busy = busy_reg;
|
||||
|
||||
|
||||
assign TP1 = FIFO_AutoRead_Threshold;
|
||||
assign TP2 = 0;
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,291 @@
|
|||
|
||||
// 4k deep CM
|
||||
// This module bypasses the FFEControlMememoryMux since the addressing of the individual RAM blocks
|
||||
// is not the same when coming from the TLC vs. FFE, and dynamic code updates must be supported for
|
||||
// the fabric RAM's.
|
||||
|
||||
// Note: in order for this to work correctly, RdClk and WrClk must be the same (tied together externally).
|
||||
|
||||
|
||||
`timescale 1ns / 10ps
|
||||
|
||||
`include "ulpsh_rtl_defines.v"
|
||||
|
||||
module FFEControlMemory_4k (
|
||||
// General Interface
|
||||
input ResetIn,
|
||||
input SPI_clk,
|
||||
input TLC_FFE_clk2x_muxed, // already muxed based on UseFastClock from TLC
|
||||
|
||||
input MemSelect_en, // MemorySelect and enable from TLC
|
||||
input [2:0] MemSelect,
|
||||
|
||||
input FFE_clock_halfperiod,
|
||||
|
||||
input [11:0] Address_TLC, // TLC address is used for both TLC reads and writes
|
||||
|
||||
input [35:0] MemoryMux_in,
|
||||
output [35:0] MemoryMux_out,
|
||||
|
||||
//Read Interface
|
||||
input [11:0] ReadAddress_FFE,
|
||||
output [35:0] ReadData,
|
||||
input ReadEnable_TLC,
|
||||
input ReadEnable_FFE,
|
||||
|
||||
//Write Interface
|
||||
input [35:0] WriteData_TLC,
|
||||
input WriteEnable_TLC,
|
||||
|
||||
// ASSP RAM interface - left bank
|
||||
output assp_lb_ram0_clk,
|
||||
output [8:0] assp_lb_ram0_addr,
|
||||
output [35:0] assp_lb_ram0_wr_data,
|
||||
input [35:0] assp_lb_ram0_rd_data,
|
||||
output assp_lb_ram0_wr_en,
|
||||
output assp_lb_ram0_rd_en,
|
||||
output [3:0] assp_lb_ram0_wr_be,
|
||||
|
||||
// ASSP RAM interface - right bank
|
||||
output assp_rb_ram1_clk,
|
||||
output [8:0] assp_rb_ram1_addr,
|
||||
output [35:0] assp_rb_ram1_wr_data,
|
||||
input [35:0] assp_rb_ram1_rd_data,
|
||||
output assp_rb_ram1_wr_en,
|
||||
output assp_rb_ram1_rd_en,
|
||||
output [3:0] assp_rb_ram1_wr_be,
|
||||
|
||||
// ASSP RAM interface - 8k - left bank
|
||||
output assp_lb_ram8k_clk,
|
||||
output [11:0] assp_lb_ram8k_addr,
|
||||
output [16:0] assp_lb_ram8k_wr_data,
|
||||
input [16:0] assp_lb_ram8k_rd_data,
|
||||
output assp_lb_ram8k_wr_en,
|
||||
output assp_lb_ram8k_rd_en,
|
||||
output [1:0] assp_lb_ram8k_wr_be,
|
||||
|
||||
//AP2
|
||||
output [8:0] FFEControlMemory_4k_Address_TLC_o ,
|
||||
output [8:0] FFEControlMemory_4k_ReadAddress_muxed_o ,
|
||||
output FFEControlMemory_4k_ram5_wr_en_o,
|
||||
output FFEControlMemory_4k_ram5_rd_en_o,
|
||||
output FFEControlMemory_4k_SPI_clk_o,
|
||||
output FFEControlMemory_4k_TLC_FFE_clk2x_muxed_o,
|
||||
output [35:0] FFEControlMemory_4k_WriteData_TLC_o ,
|
||||
input [35:0] FFEControlMemory_4k_ram5_rd_data_i ,
|
||||
output FFEControlMemory_4k_ram4_wr_en_o ,
|
||||
output FFEControlMemory_4k_ram4_rd_en_o,
|
||||
input [35:0] FFEControlMemory_4k_ram4_rd_data_i,
|
||||
output [9:0] FFEControlMemory_4k_fabric_ram1Kx9_addr_o,
|
||||
output FFEControlMemory_4k_ram1_wr_en_o ,
|
||||
output FFEControlMemory_4k_ram1_rd_en_o ,
|
||||
input [8:0] FFEControlMemory_4k_ram1_rd_data_i
|
||||
|
||||
|
||||
|
||||
);
|
||||
|
||||
wire [11:0] ReadAddress_muxed;
|
||||
|
||||
wire Select_from_TLC;
|
||||
|
||||
wire ram0_wr_en;
|
||||
wire ram1_wr_en;
|
||||
wire ram2_wr_en;
|
||||
wire ram3_wr_en;
|
||||
wire ram4_wr_en;
|
||||
wire ram5_wr_en;
|
||||
|
||||
wire ram0_rd_en;
|
||||
wire ram1_rd_en;
|
||||
wire ram2_rd_en;
|
||||
wire ram3_rd_en;
|
||||
wire ram4_rd_en;
|
||||
wire ram5_rd_en;
|
||||
|
||||
wire [11:0] assp_ram8k_addr;
|
||||
wire [9:0] fabric_ram1Kx9_addr;
|
||||
|
||||
wire [16:0] ram0_rd_data;
|
||||
wire [8:0] ram1_rd_data;
|
||||
wire [35:0] ram2_rd_data;
|
||||
wire [35:0] ram3_rd_data;
|
||||
wire [35:0] ram4_rd_data;
|
||||
wire [35:0] ram5_rd_data;
|
||||
reg [35:0] lower2k_rd_data;
|
||||
reg [16:0] lower2k_rd_data_phase0, lower2k_rd_data_phase1;
|
||||
reg ReadAddress_muxed_bit0_r1;
|
||||
|
||||
reg [2:0] ram_rd_select;
|
||||
reg [35:0] ram_rd_data;
|
||||
wire [8:0] assp_ram_addr;
|
||||
|
||||
|
||||
// RAM blocks are arranged as follows:
|
||||
// RAM 0: 0-2k: 4Kx17 (double-clocked to create the lower 34 bits of each uInstruction)
|
||||
// RAM 1: 0-2k: 1024x9 (one-half of the 1024x9 word is used for the remaining 2 bits of each uInstruction)
|
||||
// RAM 2,3: 2k-3k: ASSP RAM's (formerly 0k-1k in the 2k CM)
|
||||
// RAM 4,5: 3k-4k: fabric RAM's (formerly 1k-2k in the 2k CM)
|
||||
|
||||
|
||||
assign Select_from_TLC = (MemSelect_en && (MemSelect == 3'h0 || MemSelect == 3'h4 || MemSelect == 3'h5));
|
||||
|
||||
// memory mux to pass data back to TLC
|
||||
assign MemoryMux_out = Select_from_TLC ? ReadData : MemoryMux_in;
|
||||
|
||||
|
||||
// mux between the TLC and FFE control signals
|
||||
assign ReadAddress_muxed = Select_from_TLC ? Address_TLC : ReadAddress_FFE;
|
||||
assign ReadEnable_muxed = Select_from_TLC ? ReadEnable_TLC : ReadEnable_FFE;
|
||||
|
||||
|
||||
// generate the read address for the 4Kx17 ASSP RAM
|
||||
assign assp_ram8k_addr = Select_from_TLC ? Address_TLC : {ReadAddress_FFE[10:0], FFE_clock_halfperiod};
|
||||
|
||||
/// generate the read address for the 1Kx9 fabric RAM
|
||||
assign fabric_ram1Kx9_addr = Select_from_TLC ? Address_TLC : ReadAddress_FFE[10:1];
|
||||
|
||||
// write enables for each RAM block
|
||||
// note: fabric RAM's cannot use MemSelect_en since these RAM's may be updated during run-time.
|
||||
assign ram0_wr_en = (MemSelect_en && MemSelect == 3'h4 && WriteEnable_TLC);
|
||||
assign ram1_wr_en = (MemSelect_en && MemSelect == 3'h5 && WriteEnable_TLC);
|
||||
assign ram2_wr_en = (MemSelect_en && MemSelect == 3'h0 && WriteEnable_TLC && Address_TLC[10:9] == 2'b00);
|
||||
assign ram3_wr_en = (MemSelect_en && MemSelect == 3'h0 && WriteEnable_TLC && Address_TLC[10:9] == 2'b01);
|
||||
assign ram4_wr_en = ( MemSelect == 3'h0 && WriteEnable_TLC && Address_TLC[10:9] == 2'b10);
|
||||
assign ram5_wr_en = ( MemSelect == 3'h0 && WriteEnable_TLC && Address_TLC[10:9] == 2'b11);
|
||||
|
||||
// read enables for each RAM block
|
||||
assign ram0_rd_en = (MemSelect_en && MemSelect == 3'h4) ? ReadEnable_TLC : (ReadEnable_FFE && ReadAddress_FFE[11] == 1'b0);
|
||||
assign ram1_rd_en = (MemSelect_en && MemSelect == 3'h5) ? ReadEnable_TLC : (ReadEnable_FFE && ReadAddress_FFE[11] == 1'b0 && FFE_clock_halfperiod);
|
||||
assign ram2_rd_en = (MemSelect_en && MemSelect == 3'h0) ? (ReadEnable_TLC && Address_TLC[10:9] == 2'b00) : (ReadEnable_FFE && FFE_clock_halfperiod && ReadAddress_FFE[11:9] == 3'b100 && FFE_clock_halfperiod);
|
||||
assign ram3_rd_en = (MemSelect_en && MemSelect == 3'h0) ? (ReadEnable_TLC && Address_TLC[10:9] == 2'b01) : (ReadEnable_FFE && FFE_clock_halfperiod && ReadAddress_FFE[11:9] == 3'b101 && FFE_clock_halfperiod);
|
||||
assign ram4_rd_en = (MemSelect_en && MemSelect == 3'h0) ? (ReadEnable_TLC && Address_TLC[10:9] == 2'b10) : (ReadEnable_FFE && FFE_clock_halfperiod && ReadAddress_FFE[11:9] == 3'b110 && FFE_clock_halfperiod);
|
||||
assign ram5_rd_en = (MemSelect_en && MemSelect == 3'h0) ? (ReadEnable_TLC && Address_TLC[10:9] == 2'b11) : (ReadEnable_FFE && FFE_clock_halfperiod && ReadAddress_FFE[11:9] == 3'b111 && FFE_clock_halfperiod);
|
||||
|
||||
|
||||
// RAM 5 (fabric)
|
||||
assign FFEControlMemory_4k_Address_TLC_o[8:0] = Address_TLC[8:0];
|
||||
assign FFEControlMemory_4k_ReadAddress_muxed_o[8:0] = ReadAddress_muxed[8:0];
|
||||
assign FFEControlMemory_4k_ram5_wr_en_o = ram5_wr_en ;
|
||||
assign FFEControlMemory_4k_ram5_rd_en_o = ram5_rd_en;
|
||||
assign FFEControlMemory_4k_SPI_clk_o = SPI_clk;
|
||||
assign FFEControlMemory_4k_TLC_FFE_clk2x_muxed_o = TLC_FFE_clk2x_muxed;
|
||||
assign FFEControlMemory_4k_WriteData_TLC_o = WriteData_TLC;
|
||||
assign ram5_rd_data = FFEControlMemory_4k_ram5_rd_data_i;
|
||||
|
||||
|
||||
assign FFEControlMemory_4k_ram4_wr_en_o = ram4_wr_en ;
|
||||
assign FFEControlMemory_4k_ram4_rd_en_o = ram4_rd_en;
|
||||
assign ram4_rd_data = FFEControlMemory_4k_ram4_rd_data_i;
|
||||
|
||||
|
||||
// mappings to the ASSP RAM's
|
||||
|
||||
assign assp_ram_addr = (MemSelect_en && MemSelect == 3'h0) ? Address_TLC[8:0] : ReadAddress_muxed[8:0];
|
||||
|
||||
// RAM 3 (ASSP right bank)
|
||||
// note: the port names are still called "ram1" to maintain compatibility with the 2k CM variant
|
||||
assign assp_rb_ram1_clk = TLC_FFE_clk2x_muxed;
|
||||
assign assp_rb_ram1_addr = assp_ram_addr;
|
||||
assign assp_rb_ram1_wr_data = WriteData_TLC;
|
||||
assign ram3_rd_data = assp_rb_ram1_rd_data;
|
||||
assign assp_rb_ram1_wr_en = ram3_wr_en;
|
||||
assign assp_rb_ram1_rd_en = ram3_rd_en;
|
||||
assign assp_rb_ram1_wr_be = 4'b1111;
|
||||
|
||||
// RAM 2 (ASSP left bank)
|
||||
// note: the port names are still called "ram0" to maintain compatibility with the 2k CM variant
|
||||
assign assp_lb_ram0_clk = TLC_FFE_clk2x_muxed;
|
||||
assign assp_lb_ram0_addr = assp_ram_addr;
|
||||
assign assp_lb_ram0_wr_data = WriteData_TLC;
|
||||
assign ram2_rd_data = assp_lb_ram0_rd_data;
|
||||
assign assp_lb_ram0_wr_en = ram2_wr_en;
|
||||
assign assp_lb_ram0_rd_en = ram2_rd_en;
|
||||
assign assp_lb_ram0_wr_be = 4'b1111;
|
||||
|
||||
assign FFEControlMemory_4k_fabric_ram1Kx9_addr_o = fabric_ram1Kx9_addr;
|
||||
assign FFEControlMemory_4k_ram1_wr_en_o = ram1_wr_en ;
|
||||
assign FFEControlMemory_4k_ram1_rd_en_o = ram1_rd_en;
|
||||
assign FFEControlMemory_4k_SPI_clk_o = SPI_clk;
|
||||
assign ram1_rd_data = FFEControlMemory_4k_ram1_rd_data_i;
|
||||
|
||||
|
||||
// RAM 0 (ASSP 8k left bank)
|
||||
assign assp_lb_ram8k_clk = TLC_FFE_clk2x_muxed;
|
||||
assign assp_lb_ram8k_addr = assp_ram8k_addr;
|
||||
assign assp_lb_ram8k_wr_data = WriteData_TLC;
|
||||
assign ram0_rd_data = assp_lb_ram8k_rd_data;
|
||||
assign assp_lb_ram8k_wr_en = ram0_wr_en;
|
||||
assign assp_lb_ram8k_rd_en = ram0_rd_en;
|
||||
assign assp_lb_ram8k_wr_be = 2'b11;
|
||||
|
||||
|
||||
// latch the 4Kx17 read data
|
||||
always @(posedge TLC_FFE_clk2x_muxed) begin
|
||||
if (FFE_clock_halfperiod)
|
||||
lower2k_rd_data_phase0 <= ram0_rd_data;
|
||||
if (!FFE_clock_halfperiod)
|
||||
lower2k_rd_data_phase1 <= ram0_rd_data;
|
||||
if (FFE_clock_halfperiod)
|
||||
ReadAddress_muxed_bit0_r1 <= ReadAddress_muxed[0];
|
||||
end
|
||||
|
||||
// assemble the read data for the lower 2k (ram0/ram1)
|
||||
always @(*)
|
||||
if (FFE_clock_halfperiod == 0)
|
||||
if (ReadAddress_muxed_bit0_r1 == 0)
|
||||
lower2k_rd_data <= {ram1_rd_data[1:0], ram0_rd_data[16:0], lower2k_rd_data_phase0[16:0]};
|
||||
else
|
||||
lower2k_rd_data <= {ram1_rd_data[3:2], ram0_rd_data[16:0], lower2k_rd_data_phase0[16:0]};
|
||||
else
|
||||
if (ReadAddress_muxed_bit0_r1 == 0)
|
||||
lower2k_rd_data <= {ram1_rd_data[1:0], lower2k_rd_data_phase1[16:0], lower2k_rd_data_phase0[16:0]};
|
||||
else
|
||||
lower2k_rd_data <= {ram1_rd_data[3:2], lower2k_rd_data_phase1[16:0], lower2k_rd_data_phase0[16:0]};
|
||||
|
||||
|
||||
|
||||
// mux the read data from each RAM block, for the FFE
|
||||
always @(posedge TLC_FFE_clk2x_muxed)
|
||||
if (FFE_clock_halfperiod)
|
||||
ram_rd_select <= ReadAddress_muxed[11:9];
|
||||
|
||||
always @(*)
|
||||
if (MemSelect_en)
|
||||
// TLC is reading
|
||||
if (MemSelect == 3'h0)
|
||||
case (ram_rd_select[1:0])
|
||||
2'b00: ram_rd_data <= ram2_rd_data;
|
||||
2'b01: ram_rd_data <= ram3_rd_data;
|
||||
2'b10: ram_rd_data <= ram4_rd_data;
|
||||
2'b11: ram_rd_data <= ram5_rd_data;
|
||||
endcase
|
||||
else
|
||||
if (MemSelect == 3'h4)
|
||||
ram_rd_data <= ram0_rd_data;
|
||||
else
|
||||
// assume select=5 to reduce logic
|
||||
|
||||
//if (MemSelect == 3'h5)
|
||||
ram_rd_data <= ram1_rd_data;
|
||||
//else
|
||||
// ram_rd_data <= 0;
|
||||
else
|
||||
// FFE is reading
|
||||
if (ram_rd_select[2])
|
||||
// upper 2k
|
||||
case(ram_rd_select[1:0])
|
||||
2'b00: ram_rd_data <= ram2_rd_data;
|
||||
2'b01: ram_rd_data <= ram3_rd_data;
|
||||
2'b10: ram_rd_data <= ram4_rd_data;
|
||||
2'b11: ram_rd_data <= ram5_rd_data;
|
||||
endcase
|
||||
else
|
||||
// lower 2k
|
||||
ram_rd_data <= lower2k_rd_data;
|
||||
|
||||
assign ReadData = ram_rd_data;
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
`timescale 1ns / 10ps
|
||||
|
||||
module FFEDataMemoryMux (
|
||||
input Select,
|
||||
|
||||
input [9:0] ReadAddressIn0,
|
||||
input [9:0] ReadAddressIn1,
|
||||
output[9:0] ReadAddressOut,
|
||||
|
||||
input [9:0] WriteAddressIn0,
|
||||
input [9:0] WriteAddressIn1,
|
||||
output[9:0] WriteAddressOut,
|
||||
|
||||
input [35:0] DataToMemoryIn0,
|
||||
input [35:0] DataToMemoryIn1,
|
||||
output[35:0] DataToMemoryOut,
|
||||
|
||||
input [35:0] DataFromMemoryIn0,
|
||||
input [35:0] DataFromMemoryIn1,
|
||||
output[35:0] DataFromMemoryOut,
|
||||
|
||||
input ReadEnable0,
|
||||
input ReadEnable1,
|
||||
output ReadEnable,
|
||||
|
||||
input WriteEnable0,
|
||||
input WriteEnable1,
|
||||
output WriteEnable
|
||||
);
|
||||
|
||||
assign ReadAddressOut = (Select) ? ReadAddressIn1 : ReadAddressIn0;
|
||||
assign WriteAddressOut = (Select) ? WriteAddressIn1 : WriteAddressIn0;
|
||||
assign DataToMemoryOut = (Select) ? DataToMemoryIn1 : DataToMemoryIn0;
|
||||
assign DataFromMemoryOut = (Select) ? DataFromMemoryIn1 : DataFromMemoryIn0;
|
||||
assign ReadEnable = (Select) ? ReadEnable1 : ReadEnable0;
|
||||
assign WriteEnable = (Select) ? WriteEnable1 : WriteEnable0;
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,476 @@
|
|||
// -----------------------------------------------------------------------------
|
||||
// title : FFE_ALU.v
|
||||
// project : ULP Sensor Hub
|
||||
// description : 32-bit ALU
|
||||
// -----------------------------------------------------------------------------
|
||||
// copyright (c) 2013, QuickLogic Corporation
|
||||
// -----------------------------------------------------------------------------
|
||||
// History :
|
||||
// date version author description
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// date version author description
|
||||
// 10-31-2013 1.1 Anthony Le Add AND function to code
|
||||
// Details:
|
||||
// 1. Add new bus signal xT30 as 32-bit for output of AND function
|
||||
// 2. Assign a temporary 32bit bus to hold the concatenation of MailBox bit:
|
||||
// Mailbox32bit = {8'b0, MailBox[7:0], 16'h0};
|
||||
// 3. Add code to perform AND function between Mailbox32bit and xT23
|
||||
// 4. Add mux function between xT30 and MailBox in using signal[38]
|
||||
// 5. Expected the Synthesis to remove all unused logics
|
||||
//
|
||||
// 11-29-2013 1.2 Anthony Le Add additional comparison functions
|
||||
// Details:
|
||||
// 1. Current system supports only three jump functions:
|
||||
// a. JMP: jump
|
||||
// b. JMPNEZ: jump when result is not equal to zero
|
||||
// c. JMPGEZ: jump when result is greater or equal to zero
|
||||
// 2. Add four more compriason jump functions
|
||||
// a. JMPEQZ: jump when result is equal to zero
|
||||
// b. JMPLTZ: jump when result is less than zero
|
||||
// c. JMPLEZ: jump when result is less than or equal to zero
|
||||
// d. JMPGTZ: jump when result is greater than zero
|
||||
// 3. Re-use the three control signals[19:17]
|
||||
// 4. Use an 8-to-1 mux for JUMP logic
|
||||
// 5. Update xJumpFlag from wire to reg type
|
||||
//
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
`timescale 1ns / 10ps
|
||||
|
||||
`include "ulpsh_rtl_defines.v"
|
||||
|
||||
module FFE_ALU (
|
||||
input [31:0] xReadData1,
|
||||
input [31:0] xReadData2,
|
||||
input [63:0] signals,
|
||||
input ClockIn,
|
||||
input Clock_x2In,
|
||||
input FFE_clock_halfperiod,
|
||||
input [15:0] TimeStampIn,
|
||||
input [31:0] MailboxIn,
|
||||
input [3:0] SM_InterruptIn,
|
||||
input MultClockIn,
|
||||
input [3:0] MultStateIn,
|
||||
output [8:0] xIndexRegister,
|
||||
output [31:0] xWriteData,
|
||||
output reg xJumpFlag,
|
||||
input Save_BG_registers,
|
||||
input Restore_BG_registers,
|
||||
|
||||
output [31:0] mult_in1,
|
||||
output [31:0] mult_in2,
|
||||
output mult_enable,
|
||||
input [63:0] mult_out
|
||||
);
|
||||
|
||||
|
||||
wire [31:0] xT0, xT1, xT2;
|
||||
//wire [31:0] xT3; // defined below, depending on the multiplier implementation
|
||||
wire [31:0] xT4;
|
||||
reg [31:0] xT5;
|
||||
wire [31:0] xT6, xT7, xT8, xT9;
|
||||
wire [31:0] xT10, xT11, xT12, xT13, xT14, xT15, xT16, xT17, xT18, xT19, xT20, xT21, xT22;
|
||||
reg [31:0] xT23;
|
||||
wire [31:0] xT24, xT25;
|
||||
wire [8:0] xT26, xT27, xT28;
|
||||
reg [8:0] xT29;
|
||||
wire [31:0] xT30;
|
||||
wire signed [31:0] xT12_signed;
|
||||
wire f0;
|
||||
reg f2, f5, f2_BG, f5_BG;
|
||||
wire f3, f6;
|
||||
reg f2_latched, f2_BG_latched;
|
||||
reg [31:0] xT5_latched;
|
||||
reg f5_latched, f5_BG_latched;
|
||||
reg [8:0] xT29_latched;
|
||||
|
||||
// compiler options, from rtl_defines.v
|
||||
// ENABLE_FFE_F0_EXTENDED_DM
|
||||
// ENABLE_FFE_F0_SINGLE_DM
|
||||
// ENABLE_FFE_F0_PROGRAMMABLE_SEG0_OFFSET
|
||||
// FFE_F0_SEG0_OFFSET [value]
|
||||
|
||||
// compiler directives related to CM size:
|
||||
// ENABLE_FFE_F0_CM_SIZE_2K
|
||||
// ENABLE_FFE_F0_CM_SIZE_4K
|
||||
// ENABLE_FFE_F0_CM_SIZE_3K (future support if needed)
|
||||
|
||||
|
||||
|
||||
// select the multiplier implementation
|
||||
`define ASSP_MULT
|
||||
|
||||
`ifdef FullSingleCycle
|
||||
wire [63:0] xT3;
|
||||
wire [63:0] xT1extended, xT2extended;
|
||||
|
||||
assign xT1extended[63:0] = { {32{xT1[31]}}, xT1[31:0] };
|
||||
assign xT2extended[63:0] = { {32{xT2[31]}}, xT2[31:0] };
|
||||
assign xT3 = xT1extended * xT2extended;
|
||||
assign xT4 = (xT3 >> 16);
|
||||
|
||||
`elsif Handicapped
|
||||
wire [31:0] xT3;
|
||||
assign xT3 = xT1 + xT2; // replace multiplier with adder
|
||||
assign xT4 = xT3;
|
||||
|
||||
`elsif MultiCycle
|
||||
wire [31:0] xT3;
|
||||
Multiplier Multiplier_1 (
|
||||
.ClockIn ( MultClockIn ),
|
||||
.StateIn ( MultStateIn ),
|
||||
.Arg1In ( xT1 ),
|
||||
.Arg2In ( xT2 ),
|
||||
.ResultOut ( xT3 )
|
||||
);
|
||||
assign xT4 = xT3;
|
||||
|
||||
`elsif ASSP_MULT
|
||||
wire [63:0] xT3;
|
||||
|
||||
assign xT3 = mult_out;
|
||||
assign xT4 = (xT3 >> 16);
|
||||
|
||||
`else
|
||||
wire [31:0] xT3;
|
||||
|
||||
assign xT3 = 0;
|
||||
assign xT4 = 0;
|
||||
|
||||
`endif
|
||||
|
||||
|
||||
// drive the outputs for the ASSP multiplier
|
||||
assign mult_in1 = xT1;
|
||||
assign mult_in2 = xT2;
|
||||
assign mult_enable = signals[5];
|
||||
|
||||
|
||||
|
||||
assign xT22 = signals[2] ? (xReadData1<<16) : xReadData1;
|
||||
|
||||
always @(*)
|
||||
case (signals[1:0])
|
||||
2'b00: xT23 <= xReadData2;
|
||||
2'b01: xT23 <= MailboxIn;
|
||||
2'b10: xT23 <= {TimeStampIn[15:0], 16'b0};
|
||||
2'b11: xT23 <= {7'b0, xT29[8:0], 16'b0}; // IndexReg
|
||||
endcase
|
||||
|
||||
assign xT24 = signals[3] ? {12'b0, SM_InterruptIn[3:0], 16'b0} : xT23;
|
||||
assign xT30 = xReadData1 & xT24;
|
||||
assign xT9 = signals[38] ? xT30 : xT24;
|
||||
assign xT21 = xReadData1 | xT24;
|
||||
assign xT25 = signals[39] ? xT21 : xT9;
|
||||
|
||||
assign xT0 = signals[4] ? xT25 : xT22;
|
||||
|
||||
assign xT12_signed = xT12;
|
||||
// remove these muxes to save space
|
||||
//assign xT1 = signals[5] ? xT0 : xT1; // this mux (latch) keeps the multiplier inputs stable, to save power
|
||||
//assign xT2 = signals[5] ? xT25 : xT2; // this mux (latch) keeps the multiplier inputs stable, to save power
|
||||
assign xT1 = xT0;
|
||||
assign xT2 = xT25;
|
||||
|
||||
assign xT7 = signals[5] ? xT4 : xT25;
|
||||
assign xT10 = signals[8] ? ~xT7 : xT7;
|
||||
assign xT11 = signals[8] ? 32'b1 : 32'b0;
|
||||
assign xT13 = signals[9] ? xT7 : xT10;
|
||||
assign xT6 = signals[6] ? xT22 : xT5;
|
||||
assign xT8 = signals[7] ? xT6 : 32'b0;
|
||||
assign xT12 = xT8 + xT10 + xT11;
|
||||
assign xT14 = (xT12_signed >>> 1);
|
||||
assign xT16 = signals[11] ? xT14 : xT12;
|
||||
assign xT19 = signals[12] ? xT16 : xT6;
|
||||
assign f0 = xT12[31];
|
||||
|
||||
// Sign bit
|
||||
`ifndef ENABLE_FFE_F0_SINGLE_DM
|
||||
// double DM, default behavior
|
||||
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
// 4k CM
|
||||
always @(posedge Clock_x2In) begin
|
||||
if (FFE_clock_halfperiod) begin
|
||||
if (Restore_BG_registers)
|
||||
f2 <= f2_BG;
|
||||
else
|
||||
f2 <= signals[10] ? f0 : f2;
|
||||
|
||||
if (Save_BG_registers)
|
||||
f2_BG <= f2;
|
||||
else
|
||||
f2_BG <= f2_BG;
|
||||
end
|
||||
end
|
||||
|
||||
`else
|
||||
// 2k CM
|
||||
always @(posedge ClockIn) begin
|
||||
if (Restore_BG_registers)
|
||||
f2 <= f2_BG;
|
||||
else
|
||||
f2 <= signals[10] ? f0 : f2;
|
||||
|
||||
if (Save_BG_registers)
|
||||
f2_BG <= f2;
|
||||
else
|
||||
f2_BG <= f2_BG;
|
||||
end
|
||||
|
||||
`endif
|
||||
|
||||
`else
|
||||
// single DM
|
||||
|
||||
always @(posedge Clock_x2In) begin
|
||||
if (!FFE_clock_halfperiod) begin
|
||||
if (Restore_BG_registers)
|
||||
f2_latched <= f2_BG;
|
||||
else
|
||||
f2_latched <= signals[10] ? f0 : f2;
|
||||
|
||||
if (Save_BG_registers)
|
||||
f2_BG_latched <= f2;
|
||||
else
|
||||
f2_BG_latched <= f2_BG;
|
||||
end
|
||||
end
|
||||
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In) begin
|
||||
if (FFE_clock_halfperiod) begin
|
||||
f2 <= f2_latched;
|
||||
f2_BG <= f2_BG_latched;
|
||||
end
|
||||
end
|
||||
`else
|
||||
always @(posedge ClockIn) begin
|
||||
f2 <= f2_latched;
|
||||
f2_BG <= f2_BG_latched;
|
||||
end
|
||||
`endif
|
||||
|
||||
`endif
|
||||
|
||||
|
||||
assign f6 = signals[33] ? (f2) : (f0);
|
||||
assign f3 = signals[35] ? !f5 : f6;
|
||||
|
||||
assign xT15 = (f3) ? xT13 : xT19;
|
||||
assign xT17 = signals[13] ? xT15 : xT16;
|
||||
assign xT18 = (xT17 << 1);
|
||||
assign xT20 = signals[14] ? xT18 : xT17;
|
||||
|
||||
assign xWriteData = xT20;
|
||||
|
||||
// accumulator
|
||||
`ifndef ENABLE_FFE_F0_SINGLE_DM
|
||||
// double DM, default behavior
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In) begin
|
||||
if (FFE_clock_halfperiod)
|
||||
xT5 <= signals[16] ? xT20 : xT5;
|
||||
end
|
||||
`else
|
||||
always @(posedge ClockIn) begin
|
||||
xT5 <= signals[16] ? xT20 : xT5;
|
||||
end
|
||||
`endif
|
||||
`else
|
||||
// single DM
|
||||
always @(posedge Clock_x2In) begin
|
||||
if (!FFE_clock_halfperiod)
|
||||
xT5_latched <= signals[16] ? xT20 : xT5;
|
||||
end
|
||||
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In)
|
||||
if (FFE_clock_halfperiod)
|
||||
xT5 <= xT5_latched;
|
||||
`else
|
||||
always @(posedge ClockIn)
|
||||
xT5 <= xT5_latched;
|
||||
`endif
|
||||
`endif
|
||||
|
||||
|
||||
// NEZ flag
|
||||
`ifndef ENABLE_FFE_F0_SINGLE_DM
|
||||
// double DM, default behavior
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In) begin
|
||||
if (FFE_clock_halfperiod) begin
|
||||
if (Restore_BG_registers)
|
||||
f5 <= f5_BG;
|
||||
else
|
||||
f5 <= signals[15] ? f5 : (xT20 != 32'b0);
|
||||
|
||||
if (Save_BG_registers)
|
||||
f5_BG <= f5;
|
||||
else
|
||||
f5_BG <= f5_BG;
|
||||
end
|
||||
end
|
||||
`else
|
||||
always @(posedge ClockIn) begin
|
||||
if (Restore_BG_registers)
|
||||
f5 <= f5_BG;
|
||||
else
|
||||
f5 <= signals[15] ? f5 : (xT20 != 32'b0);
|
||||
|
||||
if (Save_BG_registers)
|
||||
f5_BG <= f5;
|
||||
else
|
||||
f5_BG <= f5_BG;
|
||||
end
|
||||
`endif
|
||||
`else
|
||||
// single DM
|
||||
always @(posedge Clock_x2In) begin
|
||||
if (!FFE_clock_halfperiod) begin
|
||||
if (Restore_BG_registers)
|
||||
f5_latched <= f5_BG;
|
||||
//f5_latched <= f5_BG_latched;
|
||||
else
|
||||
f5_latched <= signals[15] ? f5 : (xT20 != 32'b0);
|
||||
//f5_latched <= signals[15] ? f5_latched : (xT20 != 32'b0);
|
||||
|
||||
if (Save_BG_registers)
|
||||
f5_BG_latched <= f5;
|
||||
//f5_BG_latched <= f5_latched;
|
||||
else
|
||||
f5_BG_latched <= f5_BG;
|
||||
//f5_BG_latched <= f5_BG_latched;
|
||||
end
|
||||
end
|
||||
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In) begin
|
||||
if (FFE_clock_halfperiod) begin
|
||||
f5 <= f5_latched;
|
||||
f5_BG <= f5_BG_latched;
|
||||
end
|
||||
end
|
||||
`else
|
||||
always @(posedge ClockIn) begin
|
||||
f5 <= f5_latched;
|
||||
f5_BG <= f5_BG_latched;
|
||||
end
|
||||
`endif
|
||||
`endif
|
||||
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
case ({signals[19], signals[18], signals[17]})
|
||||
3'b000: xJumpFlag = 1'b0; // no jump
|
||||
3'b001: xJumpFlag = 1'b1; // JMP (unconditional jump)
|
||||
3'b010: xJumpFlag = f5; // JMPNEZ (jump if NEZflag)
|
||||
3'b011: xJumpFlag = !f5; // JMPEQZ (jump if !NEZflag)
|
||||
3'b100: xJumpFlag = !f2; // JMPGEZ (jump if !SignBit)
|
||||
3'b101: xJumpFlag = f2; // JMPLTZ (jump if SignBit)
|
||||
3'b110: xJumpFlag = !(!f2 && f5); // JMPLEZ (jump if SignBit or !NEZflag)
|
||||
3'b111: xJumpFlag = !f2 && f5; // JMPGTZ (jump if !SignBit and NEZflag)
|
||||
default: xJumpFlag = 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// Index register code
|
||||
assign xT26 = xT29 + 1;
|
||||
assign xT27 = signals[24] ? xT26 : 9'b0;
|
||||
assign xT28 = signals[26] ? xT20[24:16] : xT27; // assign the integer portion of xT20, or xT27
|
||||
|
||||
// Index Register
|
||||
`ifndef ENABLE_FFE_F0_SINGLE_DM
|
||||
// double DM, default behavior
|
||||
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In) begin
|
||||
if (FFE_clock_halfperiod) begin
|
||||
if (signals[25])
|
||||
xT29 <= xT28;
|
||||
else
|
||||
xT29 <= xT29;
|
||||
end
|
||||
end
|
||||
`else
|
||||
always @(posedge ClockIn) begin
|
||||
if (signals[25])
|
||||
xT29 <= xT28;
|
||||
else
|
||||
xT29 <= xT29;
|
||||
end
|
||||
`endif
|
||||
`else
|
||||
// single DM
|
||||
|
||||
always @(posedge Clock_x2In) begin
|
||||
if (!FFE_clock_halfperiod) begin
|
||||
if (signals[25])
|
||||
xT29_latched <= xT28;
|
||||
else
|
||||
xT29_latched <= xT29;
|
||||
end
|
||||
end
|
||||
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In)
|
||||
if (FFE_clock_halfperiod)
|
||||
xT29 <= xT29_latched;
|
||||
`else
|
||||
always @(posedge ClockIn)
|
||||
xT29 <= xT29_latched;
|
||||
`endif
|
||||
|
||||
`endif
|
||||
|
||||
assign xIndexRegister = xT29;
|
||||
|
||||
|
||||
// prevent logic duplication
|
||||
//pragma attribute xT0 preserve_driver true
|
||||
//pragma attribute xT1 preserve_driver true
|
||||
//pragma attribute xT2 preserve_driver true
|
||||
//pragma attribute xT3 preserve_driver true
|
||||
//pragma attribute xT4 preserve_driver true
|
||||
//pragma attribute xT5 preserve_driver true
|
||||
//pragma attribute xT6 preserve_driver true
|
||||
//pragma attribute xT7 preserve_driver true
|
||||
//pragma attribute xT8 preserve_driver true
|
||||
//pragma attribute xT9 preserve_driver true
|
||||
//pragma attribute xT10 preserve_driver true
|
||||
//pragma attribute xT11 preserve_driver true
|
||||
//pragma attribute xT12 preserve_driver true
|
||||
//pragma attribute xT13 preserve_driver true
|
||||
//pragma attribute xT14 preserve_driver true
|
||||
//pragma attribute xT15 preserve_driver true
|
||||
//pragma attribute xT16 preserve_driver true
|
||||
//pragma attribute xT17 preserve_driver true
|
||||
//pragma attribute xT18 preserve_driver true
|
||||
//pragma attribute xT19 preserve_driver true
|
||||
//pragma attribute xT20 preserve_driver true
|
||||
//pragma attribute xT20 preserve_driver true
|
||||
//pragma attribute xT21 preserve_driver true
|
||||
//pragma attribute xT22 preserve_driver true
|
||||
//pragma attribute xT23 preserve_driver true
|
||||
//pragma attribute xT24 preserve_driver true
|
||||
//pragma attribute xT25 preserve_driver true
|
||||
//pragma attribute xT26 preserve_driver true
|
||||
//pragma attribute xT27 preserve_driver true
|
||||
//pragma attribute xT28 preserve_driver true
|
||||
//pragma attribute xT29 preserve_driver true
|
||||
//pragma attribute xT30 preserve_driver true
|
||||
//pragma attribute xT12_signed preserve_driver true
|
||||
//pragma attribute f0 preserve_driver true
|
||||
//pragma attribute f2 preserve_driver true
|
||||
//pragma attribute f5 preserve_driver true
|
||||
//pragma attribute f3 preserve_driver true
|
||||
//pragma attribute f6 preserve_driver true
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,964 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
title : FlexFusionEngine Control
|
||||
project : Jim-Bob Hardware Sensor Hub
|
||||
-----------------------------------------------------------------------------
|
||||
platform : Alabama test chip
|
||||
standard : Verilog 2001
|
||||
-----------------------------------------------------------------------------
|
||||
description: Module for controlling the FlexFusionEngine
|
||||
-----------------------------------------------------------------------------
|
||||
copyright (c) 2013, QuickLogic Corporation
|
||||
-----------------------------------------------------------------------------
|
||||
History :
|
||||
Date Version Author Description
|
||||
2013/03/21 1.0 Jason Lew Created
|
||||
2013/05/02 1.1 Jason Lew Migrated from FFEAT v21d
|
||||
2013/06/14 1.2 Randy O. Corrected assignment to DataMemReadAddr's b/c it wasn't using IndexReg properly.
|
||||
Corrected assignment to MemReadData's b/c it shouldn't use IndexReg.
|
||||
2013/06/26 1.3 Randy O. Made the Signals bus 64 bits wide instead of 32, since it needs to be at least as wide as the one in microopdecodes.v
|
||||
2013/07/01 1.4 Randy O. Cosmetic changes to improve readability.
|
||||
Removed DataMem1WriteData_int & DataMem2WriteData_int since they were unused.
|
||||
2013/07/08 1.5 Randy O. Added unit delays to aid in functional sim.
|
||||
2014/05/21 1.6 Glen G. Added ability to read/write expanded Sensor Manager Memory
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Comments: This solution is specifically for implementing into the Alabama
|
||||
test chip. Verification will be done using the Jim-Bob Sensor Board
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
`include "ulpsh_rtl_defines.v"
|
||||
|
||||
|
||||
`timescale 1ns / 10ps
|
||||
|
||||
module FFE_Control ( // named RunFlexFusionEngine in C source
|
||||
input ClockIn,
|
||||
input Clock_x2In,
|
||||
input ResetIn,
|
||||
input StartIn,
|
||||
output StartSMOut,
|
||||
input [15:0] TimeStampIn,
|
||||
input [31:0] MailboxIn,
|
||||
input [3:0] SM_InterruptIn,
|
||||
output [11:0] ControlMemAddressOut,
|
||||
output reg ControlMemReadEnableOut,
|
||||
output [9:0] SensorMemReadAddressOut, // Expanded for Rel 0 on 6/18
|
||||
output SensorMemReadEnableOut,
|
||||
output [9:0] SensorMemWriteAddressOut, // New for Rel 0 on 6/18
|
||||
output SensorMemWriteEnableOut, // New for Rel 0 on 6/18
|
||||
input [35:0] ControlMemDataIn,
|
||||
input [35:0] Mem1ReadData,
|
||||
input [35:0] Mem2ReadData,
|
||||
input [17:0] SensorMemReadDataIn,
|
||||
input SensorMemBusyIn,
|
||||
|
||||
output [8:0] SensorMemWriteDataOut, // New for Rel 0 on 6/18
|
||||
output BusyOut,
|
||||
output DataMem1ReadEnable,
|
||||
output DataMem2ReadEnable,
|
||||
output DataMem1WriteEnable,
|
||||
output DataMem2WriteEnable,
|
||||
output [9:0] DataMem1ReadAddressOut,
|
||||
output [9:0] DataMem1WriteAddressOut,
|
||||
output [35:0] DataMem1WriteDataOut,
|
||||
output [9:0] DataMem2ReadAddressOut,
|
||||
output [9:0] DataMem2WriteAddressOut,
|
||||
output [35:0] DataMem2WriteDataOut,
|
||||
|
||||
output reg FFE_clock_halfperiod,
|
||||
|
||||
input MultClockIn,
|
||||
input [3:0] MultStateIn,
|
||||
|
||||
// Status data
|
||||
input SMBusyIn,
|
||||
output reg SMOverrunOut,
|
||||
|
||||
// CM FIFO controls
|
||||
output [17:0] CMWriteDataOut,
|
||||
output CMWriteEnableOut,
|
||||
|
||||
output [7:0] InterruptMsgOut,
|
||||
|
||||
// interface to ASSP multiplier
|
||||
output [31:0] mult_in1,
|
||||
output [31:0] mult_in2,
|
||||
output mult_enable,
|
||||
input [63:0] mult_out,
|
||||
|
||||
|
||||
output TP1,
|
||||
output TP2,
|
||||
output TP3
|
||||
);
|
||||
|
||||
|
||||
// compiler directives related to CM size:
|
||||
// ENABLE_FFE_F0_CM_SIZE_2K
|
||||
// ENABLE_FFE_F0_CM_SIZE_4K
|
||||
// ENABLE_FFE_F0_CM_SIZE_3K (future support if needed)
|
||||
|
||||
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
// 4k CM
|
||||
reg [11:0] xPC;
|
||||
wire [11:0] xJumpAddress;
|
||||
reg [11:0] PC_BG;
|
||||
`else
|
||||
// 2k CM (3k CM support may be added in the future)
|
||||
reg [10:0] xPC;
|
||||
wire [10:0] xJumpAddress;
|
||||
reg [10:0] PC_BG;
|
||||
`endif
|
||||
|
||||
|
||||
reg BusyOut_reg, BusyOut_r1;
|
||||
|
||||
reg Start_r1, Start_r2, Start_r3;
|
||||
wire [31:0] Mem1ReadDataToALU;
|
||||
wire [31:0] Mem2ReadDataToALU;
|
||||
wire [8:0] MicroOpCode;
|
||||
wire [63:0] Signals; // the width of Signals is defined to be way larger than it needs to be (today), extra bits should get optimized out.
|
||||
wire [8:0] xIndexRegister;
|
||||
wire [31:0] xWriteData;
|
||||
wire xJumpFlag;
|
||||
wire [35:0] Mem1ReadDataX;
|
||||
wire [35:0] Mem2ReadDataX;
|
||||
|
||||
reg [7:0] InterruptMsg_reg;
|
||||
reg StartSM_reg;
|
||||
|
||||
reg [15:0] TimeStamp_r1, TimeStamp_r2, TimeStamp_synced;
|
||||
|
||||
|
||||
reg f5_BG;
|
||||
reg f2_BG;
|
||||
reg BGcontinue_pending;
|
||||
reg BGsave_pending;
|
||||
reg BGstop_pending;
|
||||
reg BG_active;
|
||||
reg Start_pending;
|
||||
wire Start_detected;
|
||||
wire Save_BG_registers;
|
||||
wire Restore_BG_registers;
|
||||
wire Clear_PC;
|
||||
wire Disable_DataMem_WrEn;
|
||||
|
||||
reg [2:0] Thread_switch_cnt;
|
||||
parameter [2:0] THREAD_SWITCH_CNT_DONE = 3'b111;
|
||||
|
||||
|
||||
// standard-depth DM addresses (9 bits)
|
||||
wire [8:0] DataMem1ReadAddressOut_std;
|
||||
wire [8:0] DataMem1WriteAddressOut_std;
|
||||
wire [8:0] DataMem2ReadAddressOut_std;
|
||||
wire [8:0] DataMem2WriteAddressOut_std;
|
||||
|
||||
wire [9:0] DataMem1WriteAddressOut_trans;
|
||||
wire [9:0] DataMem2WriteAddressOut_trans;
|
||||
wire [9:0] DataMem1ReadAddressOut_trans;
|
||||
wire [9:0] DataMem2ReadAddressOut_trans;
|
||||
reg [9:0] DataMem2ReadAddressOut_trans_hold;
|
||||
reg DataMem1ReadAddressOut_trans_MSB_r1;
|
||||
|
||||
wire [9:0] DataMem1WriteAddressOut_mux;
|
||||
wire [9:0] DataMem1ReadAddressOut_mux;
|
||||
|
||||
wire DataMem1ReadEnable_mux;
|
||||
wire DataMem1WriteEnable_mux;
|
||||
|
||||
wire [9:0] DataMem1WriteAddressOut_split;
|
||||
wire [9:0] DataMem2WriteAddressOut_split;
|
||||
wire [9:0] DataMem1ReadAddressOut_split;
|
||||
wire [9:0] DataMem2ReadAddressOut_split;
|
||||
|
||||
wire DataMem1ReadEnable_split;
|
||||
wire DataMem1WriteEnable_split;
|
||||
wire DataMem2ReadEnable_split;
|
||||
wire DataMem2WriteEnable_split;
|
||||
|
||||
//reg FFE_clock_halfperiod;
|
||||
|
||||
wire DataMem1ReadEnable_std;
|
||||
wire DataMem2ReadEnable_std;
|
||||
reg DataMem2ReadEnable_std_hold;
|
||||
wire DataMem1WriteEnable_std;
|
||||
wire DataMem2WriteEnable_std;
|
||||
|
||||
reg [31:0] Mem1ReadData_latched;
|
||||
reg [31:0] Mem2ReadData_latched;
|
||||
|
||||
wire ClockIn_dly1;
|
||||
wire ClockIn_dly2;
|
||||
wire ClockIn_dly3;
|
||||
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
reg SensorMemReadEnable_reg;
|
||||
reg SensorMemWriteEnable_reg;
|
||||
reg [9:0] SensorMemReadAddress_reg;
|
||||
reg [9:0] SensorMemWriteAddress_reg;
|
||||
reg CMWriteEnable_reg;
|
||||
`endif
|
||||
|
||||
// compiler options, from rtl_defines.v
|
||||
// ENABLE_FFE_F0_EXTENDED_DM
|
||||
// ENABLE_FFE_F0_SINGLE_DM
|
||||
// ENABLE_FFE_F0_PROGRAMMABLE_SEG0_OFFSET
|
||||
// FFE_F0_SEG0_OFFSET [value]
|
||||
|
||||
`ifdef FFE_F0_SEG0_OFFSET
|
||||
parameter [8:0] Segment0_offset = `FFE_F0_SEG0_OFFSET;
|
||||
`endif
|
||||
|
||||
`ifdef ENABLE_FFE_F0_EXTENDED_DM
|
||||
reg [9:0] CurrentSegment_offset;
|
||||
reg DataMem2ReadAddress_MSB_r1;
|
||||
`endif
|
||||
|
||||
`ifdef ENABLE_FFE_F0_SINGLE_DM
|
||||
reg [31:16] WriteData_latched;
|
||||
reg sig37_latched;
|
||||
`endif
|
||||
|
||||
|
||||
// sync the timestamp to this clock domain
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In) begin
|
||||
`else
|
||||
always @(posedge ClockIn) begin
|
||||
`endif
|
||||
TimeStamp_r1 <= TimeStampIn;
|
||||
TimeStamp_r2 <= TimeStamp_r1;
|
||||
if (TimeStamp_r1 == TimeStamp_r2)
|
||||
TimeStamp_synced <= TimeStamp_r2;
|
||||
else
|
||||
TimeStamp_synced <= TimeStamp_synced;
|
||||
end
|
||||
|
||||
|
||||
FFE_ALU u_FFE_ALU (
|
||||
.xReadData1 ( Mem1ReadDataToALU[31:0] ),
|
||||
.xReadData2 ( Mem2ReadDataToALU[31:0] ),
|
||||
.signals ( Signals ),
|
||||
.ClockIn ( ClockIn ),
|
||||
.Clock_x2In ( Clock_x2In ),
|
||||
.FFE_clock_halfperiod ( FFE_clock_halfperiod ),
|
||||
.MultClockIn ( MultClockIn ),
|
||||
.MultStateIn ( MultStateIn ),
|
||||
.TimeStampIn ( TimeStamp_synced ),
|
||||
.MailboxIn ( MailboxIn ),
|
||||
.SM_InterruptIn ( SM_InterruptIn ),
|
||||
.xIndexRegister ( xIndexRegister ),
|
||||
.xWriteData ( xWriteData ),
|
||||
.xJumpFlag ( xJumpFlag ),
|
||||
.Save_BG_registers ( Save_BG_registers ),
|
||||
.Restore_BG_registers ( Restore_BG_registers ),
|
||||
|
||||
.mult_in1 ( mult_in1 ),
|
||||
.mult_in2 ( mult_in2 ),
|
||||
.mult_enable ( mult_enable ),
|
||||
.mult_out ( mult_out )
|
||||
);
|
||||
|
||||
decodeMicroOpCode U_decodeMicroOpCode (
|
||||
.MicroOpCode ( MicroOpCode ),
|
||||
.Signals ( Signals )
|
||||
);
|
||||
|
||||
// Fetch Micro OpCode from Control Memory
|
||||
// then needs to be decoded for the various control signals to the ALU (these are called 'signals')
|
||||
assign MicroOpCode = BusyOut_reg ? ControlMemDataIn[8:0] : 9'b0; // xMicroOpCode (hold at zero if FFE is not running because of single port ASSP RAMs
|
||||
|
||||
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
// 4k CM
|
||||
assign xJumpAddress = ControlMemDataIn[20:9];
|
||||
`else
|
||||
// 2k CM
|
||||
assign xJumpAddress = ControlMemDataIn[19:9];
|
||||
`endif
|
||||
|
||||
|
||||
// standard (legacy) control/address signals for the DM's
|
||||
|
||||
assign DataMem1ReadEnable_std = Signals[20];
|
||||
assign DataMem2ReadEnable_std = Signals[21];
|
||||
assign DataMem1WriteEnable_std = Disable_DataMem_WrEn ? 1'b0 : (Signals[22] && BusyOut_reg);
|
||||
assign DataMem2WriteEnable_std = Disable_DataMem_WrEn ? 1'b0 : (Signals[23] && BusyOut_reg);
|
||||
|
||||
assign DataMem1WriteAddressOut_std = Signals[34] ? (ControlMemDataIn[17:9] + xIndexRegister) : ControlMemDataIn[17:9];
|
||||
assign DataMem2WriteAddressOut_std = Signals[34] ? (ControlMemDataIn[17:9] + xIndexRegister) : ControlMemDataIn[17:9];
|
||||
assign DataMem1ReadAddressOut_std = Signals[28] ? (ControlMemDataIn[26:18] + xIndexRegister) : ControlMemDataIn[26:18];
|
||||
assign DataMem2ReadAddressOut_std = Signals[29] ? (ControlMemDataIn[35:27] + xIndexRegister) : ControlMemDataIn[35:27];
|
||||
|
||||
|
||||
// translate DM read/write addresses if an extended-length DM is specified
|
||||
`ifdef ENABLE_FFE_F0_EXTENDED_DM
|
||||
// extended-length DM
|
||||
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
if (ResetIn)
|
||||
CurrentSegment_offset <= 0;
|
||||
else
|
||||
if (Signals[44] && FFE_clock_halfperiod) // seg_offset being written
|
||||
CurrentSegment_offset <= ControlMemDataIn[32:23];
|
||||
`else
|
||||
always @(posedge ClockIn or posedge ResetIn)
|
||||
if (ResetIn)
|
||||
CurrentSegment_offset <= 0;
|
||||
else
|
||||
if (Signals[44]) // seg_offset being written
|
||||
CurrentSegment_offset <= ControlMemDataIn[32:23];
|
||||
`endif
|
||||
|
||||
// translate addresses to handle extended data memory(ies)
|
||||
assign DataMem1WriteAddressOut_trans = (DataMem1WriteAddressOut_std < Segment0_offset) ?
|
||||
{1'b0, DataMem1WriteAddressOut_std[8:0]} :
|
||||
({1'b0, DataMem1WriteAddressOut_std} + {1'b0, CurrentSegment_offset});
|
||||
assign DataMem2WriteAddressOut_trans = (DataMem2WriteAddressOut_std < Segment0_offset) ?
|
||||
{1'b0, DataMem2WriteAddressOut_std[8:0]} :
|
||||
({1'b0, DataMem2WriteAddressOut_std} + {1'b0, CurrentSegment_offset});
|
||||
assign DataMem1ReadAddressOut_trans = (DataMem1ReadAddressOut_std < Segment0_offset) ?
|
||||
{1'b0, DataMem1ReadAddressOut_std[8:0]} :
|
||||
({1'b0, DataMem1ReadAddressOut_std} + {1'b0, CurrentSegment_offset});
|
||||
assign DataMem2ReadAddressOut_trans = (DataMem2ReadAddressOut_std < Segment0_offset) ?
|
||||
{1'b0, DataMem2ReadAddressOut_std[8:0]} :
|
||||
({1'b0, DataMem2ReadAddressOut_std} + {1'b0, CurrentSegment_offset});
|
||||
|
||||
`else
|
||||
// standard-length DM (could be single or double)
|
||||
|
||||
assign DataMem1WriteAddressOut_trans = {1'b0, DataMem1WriteAddressOut_std};
|
||||
assign DataMem2WriteAddressOut_trans = {1'b0, DataMem2WriteAddressOut_std};
|
||||
assign DataMem1ReadAddressOut_trans = {1'b0, DataMem1ReadAddressOut_std};
|
||||
assign DataMem2ReadAddressOut_trans = {1'b0, DataMem2ReadAddressOut_std};
|
||||
|
||||
`endif
|
||||
|
||||
|
||||
// mux the DM1/DM2 addresses into a single logical DM1 address if a single-DM design is specified
|
||||
`ifdef ENABLE_FFE_F0_SINGLE_DM
|
||||
// single DM
|
||||
|
||||
// keep track of the half-period (0 or 1) within a single FFE clock, by using the 2x FFE clock.
|
||||
// FFE_clock_halfperiod should be 0 when the 1x clock is low, 1 when the 1x clock is high (it's registered here to help eliminate timing issues).
|
||||
buff buff_clockin_dly1 (.A(ClockIn), .Q(ClockIn_dly1));
|
||||
buff buff_clockin_dly2 (.A(ClockIn_dly1), .Q(ClockIn_dly2));
|
||||
buff buff_clockin_dly3 (.A(ClockIn_dly2), .Q(ClockIn_dly3));
|
||||
//pragma attribute buff_clockin_dly1 dont_touch true
|
||||
//pragma attribute buff_clockin_dly2 dont_touch true
|
||||
//pragma attribute buff_clockin_dly3 dont_touch true
|
||||
assign #3 ClockIn_dly4 = ClockIn_dly3;
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
if (ResetIn)
|
||||
FFE_clock_halfperiod <= 0;
|
||||
else
|
||||
FFE_clock_halfperiod <= #1 ClockIn_dly4;
|
||||
/*
|
||||
if (BusyOut_reg)
|
||||
FFE_clock_halfperiod <= !FFE_clock_halfperiod;
|
||||
else
|
||||
FFE_clock_halfperiod <= 0;
|
||||
*/
|
||||
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
if (ResetIn) begin
|
||||
DataMem2ReadAddressOut_trans_hold <= 0;
|
||||
DataMem2ReadEnable_std_hold <= 0;
|
||||
end
|
||||
else begin
|
||||
if (!FFE_clock_halfperiod) begin
|
||||
DataMem2ReadAddressOut_trans_hold <= DataMem2ReadAddressOut_trans;
|
||||
DataMem2ReadEnable_std_hold <= DataMem2ReadEnable_std;
|
||||
end
|
||||
end
|
||||
|
||||
// on half-period 0, drive the DM1 read address and read enable
|
||||
// on half-period 1, drive the DM2 read address and read enable
|
||||
// drive the write address on both half-periods, and the write enable on half-period 0
|
||||
assign DataMem1ReadAddressOut_mux = FFE_clock_halfperiod ? DataMem2ReadAddressOut_trans_hold : DataMem1ReadAddressOut_trans;
|
||||
assign DataMem1ReadEnable_mux = FFE_clock_halfperiod ? DataMem2ReadEnable_std_hold : DataMem1ReadEnable_std;
|
||||
assign DataMem1WriteAddressOut_mux = DataMem1WriteAddressOut_trans; // note: DM1 write address = DM2 write address
|
||||
assign DataMem1WriteEnable_mux = FFE_clock_halfperiod ? 0 : DataMem1WriteEnable_std;
|
||||
|
||||
`else
|
||||
// double DM
|
||||
|
||||
// FFE_clock_halfperiod should never be used in this case. Assign it to 0.
|
||||
always @(*)
|
||||
FFE_clock_halfperiod <= 0;
|
||||
`endif
|
||||
|
||||
|
||||
// split the muxed RAM control signals across both physical memories if an extended-depth DM is specified.
|
||||
// (if an extended-depth DM is specified, it must also be a single DM)
|
||||
`ifdef ENABLE_FFE_F0_EXTENDED_DM
|
||||
// extended-length DM
|
||||
// note that the DM2 "_mux" signals are not defined, since it's assumed that an extended-length DM is also a single-DM
|
||||
|
||||
assign DataMem1ReadAddressOut_split = DataMem1ReadAddressOut_mux;
|
||||
assign DataMem1ReadEnable_split = (DataMem1ReadAddressOut_mux[9] == 1'b0) ? DataMem1ReadEnable_mux : 1'b0;
|
||||
assign DataMem1WriteAddressOut_split = DataMem1WriteAddressOut_mux;
|
||||
// assign DataMem1WriteEnable_split = (DataMem1WriteAddressOut_mux[9] == 1'b0) ? DataMem1WriteEnable_split : 1'b0; // original
|
||||
assign DataMem1WriteEnable_split = (DataMem1WriteAddressOut_mux[9] == 1'b0) ? DataMem1WriteEnable_mux : 1'b0; // Anthony Le 11-01-2014
|
||||
|
||||
assign DataMem2ReadAddressOut_split = DataMem1ReadAddressOut_mux;
|
||||
assign DataMem2ReadEnable_split = (DataMem1ReadAddressOut_mux[9] == 1'b1) ? DataMem1ReadEnable_mux : 1'b0;
|
||||
assign DataMem2WriteAddressOut_split = DataMem1WriteAddressOut_mux;
|
||||
// assign DataMem2WriteEnable_split = (DataMem1WriteAddressOut_mux[9] == 1'b1) ? DataMem1WriteEnable_split : 1'b0; // original
|
||||
assign DataMem2WriteEnable_split = (DataMem1WriteAddressOut_mux[9] == 1'b1) ? DataMem1WriteEnable_mux : 1'b0; // Anthony Le 11-01-2014
|
||||
`endif
|
||||
|
||||
|
||||
// drive the outputs for the DM control/address
|
||||
`ifdef ENABLE_FFE_F0_EXTENDED_DM
|
||||
// extended-length DM (must be single DM as well)
|
||||
|
||||
// must use the translated then muxed then split signals...
|
||||
|
||||
assign DataMem1ReadEnable = DataMem1ReadEnable_split;
|
||||
assign DataMem1WriteEnable = DataMem1WriteEnable_split;
|
||||
assign DataMem1WriteAddressOut = DataMem1WriteAddressOut_split;
|
||||
assign DataMem1ReadAddressOut = DataMem1ReadAddressOut_split;
|
||||
|
||||
assign DataMem2ReadEnable = DataMem2ReadEnable_split;
|
||||
assign DataMem2WriteEnable = DataMem2WriteEnable_split;
|
||||
assign DataMem2WriteAddressOut = DataMem2WriteAddressOut_split;
|
||||
assign DataMem2ReadAddressOut = DataMem2ReadAddressOut_split;
|
||||
|
||||
`else
|
||||
// standard-length DM
|
||||
|
||||
`ifdef ENABLE_FFE_F0_SINGLE_DM
|
||||
// standard-length single DM
|
||||
|
||||
// must use the non-translated then muxed signals
|
||||
// note that physical DM2 is unused, so those outputs are grounded.
|
||||
|
||||
assign DataMem1ReadEnable = DataMem1ReadEnable_mux;
|
||||
assign DataMem1WriteEnable = DataMem1WriteEnable_mux;
|
||||
assign DataMem1WriteAddressOut = DataMem1WriteAddressOut_mux;
|
||||
assign DataMem1ReadAddressOut = DataMem1ReadAddressOut_mux;
|
||||
|
||||
assign DataMem2ReadEnable = 0;
|
||||
assign DataMem2WriteEnable = 0;
|
||||
assign DataMem2WriteAddressOut = 0;
|
||||
assign DataMem2ReadAddressOut = 0;
|
||||
|
||||
`else
|
||||
// standard-length double DM (legacy)
|
||||
|
||||
// use the standard signals
|
||||
|
||||
assign DataMem1WriteAddressOut = {1'b0, DataMem1WriteAddressOut_std};
|
||||
assign DataMem2WriteAddressOut = {1'b0, DataMem2WriteAddressOut_std};
|
||||
assign DataMem1ReadAddressOut = {1'b0, DataMem1ReadAddressOut_std};
|
||||
assign DataMem2ReadAddressOut = {1'b0, DataMem2ReadAddressOut_std};
|
||||
|
||||
assign DataMem1ReadEnable = DataMem1ReadEnable_std;
|
||||
assign DataMem2ReadEnable = DataMem2ReadEnable_std;
|
||||
assign DataMem1WriteEnable = DataMem1WriteEnable_std;
|
||||
assign DataMem2WriteEnable = DataMem2WriteEnable_std;
|
||||
|
||||
`endif
|
||||
|
||||
`endif
|
||||
|
||||
|
||||
`ifdef ENABLE_FFE_F0_SINGLE_DM
|
||||
// single DM, extended or standard length
|
||||
|
||||
// hold the write data so it can be written to the CM FIFO or SM Mem correctly, when a single DM is used
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
if (ResetIn) begin
|
||||
WriteData_latched <= 0;
|
||||
sig37_latched <= 0;
|
||||
end
|
||||
else begin
|
||||
if (!FFE_clock_halfperiod) begin
|
||||
sig37_latched <= Signals[37];
|
||||
//if (!FFE_clock_halfperiod && (CMWriteEnableOut || SensorMemWriteEnableOut || Signals[36]))
|
||||
if (Signals[30] || Signals[40] || Signals[36]) // CM write or SM write or Interrupt msg write
|
||||
WriteData_latched <= xWriteData[31:16];
|
||||
end
|
||||
end
|
||||
|
||||
//assign CMWriteDataOut = {1'b0, WriteData_latched[31:24], Signals[37], WriteData_latched[23:16]};
|
||||
assign CMWriteDataOut = {1'b0, WriteData_latched[31:24], sig37_latched, WriteData_latched[23:16]};
|
||||
assign SensorMemWriteDataOut = WriteData_latched[24:16];
|
||||
|
||||
`else
|
||||
// double DM (legacy)
|
||||
|
||||
assign CMWriteDataOut = {1'b0, xWriteData[31:24], Signals[37], xWriteData[23:16]};
|
||||
assign SensorMemWriteDataOut = xWriteData[24:16];
|
||||
`endif
|
||||
|
||||
|
||||
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
// 4k CM
|
||||
|
||||
// this is done to make sure that all of these signals are stable when the 1x clock occurs.
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
if (ResetIn) begin
|
||||
SensorMemReadEnable_reg <= 0;
|
||||
SensorMemWriteEnable_reg <= 0;
|
||||
SensorMemReadAddress_reg <= 0;
|
||||
SensorMemWriteAddress_reg <= 0;
|
||||
CMWriteEnable_reg <= 0;
|
||||
end
|
||||
else begin
|
||||
if (!FFE_clock_halfperiod ) begin
|
||||
SensorMemReadEnable_reg <= DataMem1ReadEnable_std;
|
||||
SensorMemWriteEnable_reg <= Disable_DataMem_WrEn ? 1'b0 : (Signals[40] && BusyOut_reg);
|
||||
SensorMemReadAddress_reg <= Signals[28] ? (ControlMemDataIn[27:18] + xIndexRegister) : ControlMemDataIn[27:18];
|
||||
SensorMemWriteAddress_reg <= Signals[34] ? (ControlMemDataIn[18:9] + xIndexRegister) : ControlMemDataIn[18:9];
|
||||
CMWriteEnable_reg <= Disable_DataMem_WrEn ? 1'b0 : (Signals[30] && BusyOut_reg); // Write enable to CM FIFO
|
||||
end
|
||||
end
|
||||
|
||||
assign SensorMemReadEnableOut = SensorMemReadEnable_reg;
|
||||
assign SensorMemWriteEnableOut = SensorMemWriteEnable_reg;
|
||||
assign SensorMemReadAddressOut = SensorMemReadAddress_reg;
|
||||
assign SensorMemWriteAddressOut = SensorMemWriteAddress_reg;
|
||||
assign CMWriteEnableOut = CMWriteEnable_reg;
|
||||
|
||||
`else
|
||||
// 2k CM
|
||||
|
||||
assign SensorMemReadEnableOut = DataMem1ReadEnable_std;
|
||||
assign SensorMemWriteEnableOut = Disable_DataMem_WrEn ? 1'b0 : (Signals[40] && BusyOut_reg);
|
||||
assign SensorMemReadAddressOut = (Signals[28] ? (ControlMemDataIn[27:18] + xIndexRegister) : ControlMemDataIn[27:18]);
|
||||
assign SensorMemWriteAddressOut = Signals[34] ? (ControlMemDataIn[18:9] + xIndexRegister) : ControlMemDataIn[18:9];
|
||||
|
||||
assign CMWriteEnableOut = Disable_DataMem_WrEn ? 1'b0 : (Signals[30] && BusyOut_reg); // Write enable to CM FIFO
|
||||
`endif
|
||||
|
||||
|
||||
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
// 4k CM
|
||||
assign ControlMemAddressOut = xPC;
|
||||
`else
|
||||
// 2k CM
|
||||
assign ControlMemAddressOut = {1'b0, xPC};
|
||||
`endif
|
||||
|
||||
assign DataMem1WriteDataOut = {4'b0000,xWriteData};
|
||||
assign DataMem2WriteDataOut = {4'b0000,xWriteData};
|
||||
|
||||
|
||||
|
||||
// latch the read data from the DM(s)
|
||||
`ifdef ENABLE_FFE_F0_SINGLE_DM
|
||||
`ifdef ENABLE_FFE_F0_EXTENDED_DM
|
||||
// extended-length single-DM
|
||||
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
if (ResetIn)
|
||||
DataMem1ReadAddressOut_trans_MSB_r1 <= 0;
|
||||
else
|
||||
if (!FFE_clock_halfperiod)
|
||||
DataMem1ReadAddressOut_trans_MSB_r1 <= DataMem1ReadAddressOut_trans[9];
|
||||
|
||||
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
if (ResetIn)
|
||||
Mem1ReadData_latched <= 0;
|
||||
else
|
||||
if (FFE_clock_halfperiod)
|
||||
Mem1ReadData_latched <= DataMem1ReadAddressOut_trans_MSB_r1 ? Mem2ReadData : Mem1ReadData; // read from the correct physical DM
|
||||
|
||||
// store the (logical) DM2 read address' MSB, so it can be used on the following clock to select the correct physical DM
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
if (ResetIn)
|
||||
DataMem2ReadAddress_MSB_r1 <= 0;
|
||||
else
|
||||
if (FFE_clock_halfperiod)
|
||||
DataMem2ReadAddress_MSB_r1 <= DataMem2ReadAddressOut_trans[9];
|
||||
`else
|
||||
always @(posedge ClockIn or posedge ResetIn)
|
||||
if (ResetIn)
|
||||
DataMem2ReadAddress_MSB_r1 <= 0;
|
||||
else
|
||||
DataMem2ReadAddress_MSB_r1 <= DataMem2ReadAddressOut_trans[9];
|
||||
`endif
|
||||
|
||||
|
||||
|
||||
|
||||
always @(*)
|
||||
Mem2ReadData_latched <= DataMem2ReadAddress_MSB_r1 ? Mem2ReadData : Mem1ReadData; // read from the correct physical DM
|
||||
// note that Mem2ReadData_latched will only be valid on the first half-period
|
||||
// note that ReadData2 can be registered as well, to make FFE clock-to-clock timing easier (at the cost of more FFs).
|
||||
|
||||
`else
|
||||
// standard-length single-DM, latch & hold at the appropriate half-periods
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
if (ResetIn)
|
||||
Mem1ReadData_latched <= 0;
|
||||
else
|
||||
if (FFE_clock_halfperiod)
|
||||
Mem1ReadData_latched <= Mem1ReadData;
|
||||
else
|
||||
Mem1ReadData_latched <= Mem1ReadData_latched;
|
||||
|
||||
always @(*)
|
||||
Mem2ReadData_latched <= Mem1ReadData;
|
||||
// note that ReadData2 can be registered as well, to make FFE clock-to-clock timing easier (at the cost of more FFs).
|
||||
`endif
|
||||
|
||||
`else
|
||||
// standard-length double-DM, pass-thru
|
||||
always @(*) begin
|
||||
Mem1ReadData_latched <= Mem1ReadData;
|
||||
Mem2ReadData_latched <= Mem2ReadData;
|
||||
end
|
||||
`endif
|
||||
|
||||
|
||||
assign Mem1ReadDataX = Mem1ReadData_latched[31:0];
|
||||
//a mux that switches between data read from FFEDM2 or SMSM
|
||||
assign Mem2ReadDataX = Signals[27] ? {SensorMemReadDataIn[16:9], SensorMemReadDataIn[7:0], 16'b0} : Mem2ReadData_latched[31:0];
|
||||
|
||||
|
||||
assign Mem1ReadDataToALU = Mem1ReadDataX;
|
||||
assign Mem2ReadDataToALU = Mem2ReadDataX;
|
||||
|
||||
|
||||
|
||||
|
||||
// toggle StartSM each time Signals[31] is active
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
if (ResetIn)
|
||||
StartSM_reg <= 0;
|
||||
else
|
||||
if (FFE_clock_halfperiod && Signals[31])
|
||||
StartSM_reg <= !StartSM_reg;
|
||||
else
|
||||
StartSM_reg <= StartSM_reg;
|
||||
|
||||
`else
|
||||
always @(posedge ClockIn or posedge ResetIn)
|
||||
if (ResetIn)
|
||||
StartSM_reg <= 0;
|
||||
else
|
||||
if (Signals[31])
|
||||
StartSM_reg <= !StartSM_reg;
|
||||
else
|
||||
StartSM_reg <= StartSM_reg;
|
||||
|
||||
`endif
|
||||
|
||||
assign StartSMOut = StartSM_reg;
|
||||
|
||||
|
||||
// de-glitch the interrupt msg signal since it comes out of the decoder and data mem
|
||||
`ifdef ENABLE_FFE_F0_SINGLE_DM
|
||||
// single DM
|
||||
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
// 4k CM
|
||||
always @(posedge Clock_x2In)
|
||||
InterruptMsg_reg <= (FFE_clock_halfperiod && Signals[36]) ? WriteData_latched[23:16] : 8'b0;
|
||||
`else
|
||||
// 2k CM
|
||||
always @(posedge ClockIn)
|
||||
InterruptMsg_reg <= Signals[36] ? WriteData_latched[23:16] : 8'b0;
|
||||
`endif
|
||||
|
||||
`else
|
||||
// double DM, legacy behavior
|
||||
always @(posedge ClockIn)
|
||||
InterruptMsg_reg <= Signals[36] ? xWriteData[23:16] : 8'b0;
|
||||
`endif
|
||||
|
||||
assign InterruptMsgOut = InterruptMsg_reg;
|
||||
|
||||
|
||||
// sync to local clock
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In) begin
|
||||
`else
|
||||
always @(posedge ClockIn) begin
|
||||
`endif
|
||||
Start_r1 <= StartIn;
|
||||
Start_r2 <= Start_r1;
|
||||
Start_r3 <= Start_r2;
|
||||
end
|
||||
|
||||
assign Start_detected = (Start_r1 != Start_r2) || (Start_r2 != Start_r3);
|
||||
|
||||
|
||||
// Program Counter to step through the Control Memory
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In or posedge ResetIn) begin
|
||||
`else
|
||||
always @(posedge ClockIn or posedge ResetIn) begin
|
||||
`endif
|
||||
|
||||
if (ResetIn) begin
|
||||
xPC <= 0;
|
||||
BusyOut_reg <= 1'b0;
|
||||
BusyOut_r1 <= 1'b0;
|
||||
ControlMemReadEnableOut <= 1'b0;
|
||||
SMOverrunOut <= 1'b0;
|
||||
end else
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
if (FFE_clock_halfperiod)
|
||||
`endif
|
||||
begin
|
||||
BusyOut_r1 <= BusyOut_reg;
|
||||
if (BusyOut_reg && BusyOut_r1) begin // make sure the 1st control word appears on the RAM outputs... requires one clock cycle after the read enable is turned on.
|
||||
if (!Signals[32]) begin // !Signals[32] = continue running = !STOP
|
||||
if (Restore_BG_registers)
|
||||
xPC <= PC_BG;
|
||||
else
|
||||
if (Clear_PC)
|
||||
xPC <= 0;
|
||||
else
|
||||
// hold the PC while switching threads
|
||||
if (BG_active &&
|
||||
((Start_detected || BGsave_pending) ||
|
||||
(BGcontinue_pending && (Thread_switch_cnt != THREAD_SWITCH_CNT_DONE))))
|
||||
xPC <= xPC;
|
||||
else
|
||||
if (xJumpFlag)
|
||||
xPC <= xJumpAddress;
|
||||
else
|
||||
xPC <= xPC + 1;
|
||||
end else begin // Signals[32] = STOP
|
||||
xPC <= 0;
|
||||
if (!BG_active) begin // FG mode
|
||||
BusyOut_reg <= 1'b0;
|
||||
ControlMemReadEnableOut <= 1'b0;
|
||||
end else begin // BG mode
|
||||
ControlMemReadEnableOut <= 1'b1;
|
||||
if (BGstop_pending && (Thread_switch_cnt == THREAD_SWITCH_CNT_DONE) && !Start_pending && !Start_detected)
|
||||
BusyOut_reg <= 1'b0;
|
||||
else
|
||||
BusyOut_reg <= 1'b1;
|
||||
end
|
||||
end
|
||||
end else // new start condition not detected, keep running
|
||||
if (Start_detected) begin
|
||||
if (SMBusyIn) begin
|
||||
SMOverrunOut <= 1'b1;
|
||||
end else begin
|
||||
BusyOut_reg <= 1'b1;
|
||||
ControlMemReadEnableOut <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
assign BusyOut = BusyOut_reg;
|
||||
|
||||
|
||||
|
||||
// --- BG thread support
|
||||
|
||||
// Signals[42] = SetBGflag (instruction modifier)
|
||||
// Signals[43] = BGcontinue (instruction)
|
||||
|
||||
|
||||
// Start_pending, flag to latch the start event, in case it happens right as we're switching to the BG thread or while running the BG thread.
|
||||
// This needs to be latched so the FG thread can be started immediately once we've switched out of the BG thread.
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
`else
|
||||
always @(posedge ClockIn or posedge ResetIn)
|
||||
`endif
|
||||
if (ResetIn)
|
||||
Start_pending <= 0;
|
||||
else
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
if (FFE_clock_halfperiod)
|
||||
`endif
|
||||
case (Start_pending)
|
||||
1'b0: if (Start_detected && // start detected AND...
|
||||
(Signals[42] || // ...SetBGflag active (about to start or continue BG)...OR...
|
||||
BG_active)) // ...BG active (switching to BG, running BG, about to stop/end BG, stopping BG)
|
||||
Start_pending <= 1;
|
||||
1'b1: if (!BG_active) // clear this flag when BG_active goes away
|
||||
Start_pending <= 0;
|
||||
endcase
|
||||
|
||||
|
||||
// BG_pending counter, used instead of individual state machines for each type of context switch
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
`else
|
||||
always @(posedge ClockIn or posedge ResetIn)
|
||||
`endif
|
||||
if (ResetIn)
|
||||
Thread_switch_cnt <= 0;
|
||||
else
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
if (FFE_clock_halfperiod)
|
||||
`endif
|
||||
if (BGsave_pending || BGcontinue_pending || BGstop_pending)
|
||||
if (Thread_switch_cnt == THREAD_SWITCH_CNT_DONE)
|
||||
Thread_switch_cnt <= 0;
|
||||
else
|
||||
Thread_switch_cnt <= Thread_switch_cnt + 1;
|
||||
else
|
||||
Thread_switch_cnt <= 0;
|
||||
|
||||
|
||||
// BGcontinue_pending, flag that goes active while resuming the BG thread (BGcontinue instruction)
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
`else
|
||||
always @(posedge ClockIn or posedge ResetIn)
|
||||
`endif
|
||||
if (ResetIn)
|
||||
BGcontinue_pending <= 0;
|
||||
else
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
if (FFE_clock_halfperiod)
|
||||
`endif
|
||||
case (BGcontinue_pending)
|
||||
1'b0: if (Signals[43])
|
||||
BGcontinue_pending <= 1;
|
||||
1'b1: if (Thread_switch_cnt == THREAD_SWITCH_CNT_DONE)
|
||||
BGcontinue_pending <= 0;
|
||||
endcase
|
||||
|
||||
|
||||
// BGsave_pending, flag that goes active while saving the state of the BG thread (BG_continue or BG thread interrupted by the sample timer)
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
`else
|
||||
always @(posedge ClockIn or posedge ResetIn)
|
||||
`endif
|
||||
if (ResetIn)
|
||||
BGsave_pending <= 0;
|
||||
else
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
if (FFE_clock_halfperiod)
|
||||
`endif
|
||||
case (BGsave_pending)
|
||||
1'b0: if (BG_active && // in the BG thread...AND...
|
||||
(Start_detected || // ...started detected...OR...
|
||||
(BGcontinue_pending && (Thread_switch_cnt == THREAD_SWITCH_CNT_DONE) && Start_pending))) // ...about to complete BGcontinue AND start was detected
|
||||
BGsave_pending <= 1;
|
||||
1'b1: if (Thread_switch_cnt == THREAD_SWITCH_CNT_DONE)
|
||||
BGsave_pending <= 0;
|
||||
endcase
|
||||
|
||||
|
||||
// BGstop_pending, flag that goes active while stopping the BG thread (normal completion)
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
`else
|
||||
always @(posedge ClockIn or posedge ResetIn)
|
||||
`endif
|
||||
if (ResetIn)
|
||||
BGstop_pending <= 0;
|
||||
else
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
if (FFE_clock_halfperiod)
|
||||
`endif
|
||||
case (BGstop_pending)
|
||||
1'b0: if (BG_active && Signals[32])
|
||||
BGstop_pending <= 1;
|
||||
1'b1: if (Thread_switch_cnt == THREAD_SWITCH_CNT_DONE)
|
||||
BGstop_pending <= 0;
|
||||
endcase
|
||||
|
||||
|
||||
|
||||
// BG_active, flag that is active while switching to, in, or switching from, the BG thread
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
`else
|
||||
always @(posedge ClockIn or posedge ResetIn)
|
||||
`endif
|
||||
if (ResetIn)
|
||||
BG_active <= 0;
|
||||
else
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
if (FFE_clock_halfperiod)
|
||||
`endif
|
||||
case (BG_active)
|
||||
1'b0: if (Signals[42]) // SetBGactive (entering BG mode, either via start BG or continue BG)
|
||||
BG_active <= 1;
|
||||
1'b1: if ((BGsave_pending || BGstop_pending) && (Thread_switch_cnt == THREAD_SWITCH_CNT_DONE)) // done switching out of BG mode
|
||||
BG_active <= 0;
|
||||
endcase
|
||||
|
||||
|
||||
// Control signal used to save the BG copy of the PC and ALU flags
|
||||
assign Save_BG_registers = (BGsave_pending && (Thread_switch_cnt == 1));
|
||||
// clock-by-clock sequence of events:
|
||||
// {BGsave_pending,Thread_switch_cnt}
|
||||
// 0,0 - Start detected, last BG instruction, hold PC
|
||||
// 1,0 - hold PC, disable DataMemWrEn
|
||||
// 1,1 - hold PC, save PC & flags (Save_BG_registers active), disable DataMemWrEn
|
||||
// 1,2 - clear PC, disable DataMemWrEn
|
||||
// 1,3 - hold PC (driving into CodeMem), disable DataMemWrEn
|
||||
// 1,4 - hold PC (CodeMem available, driving DataMem), disable DataMemWrEn
|
||||
// 1,5 - hold PC (DataMem available), disable DataMemWrEn
|
||||
// 1,6 - hold PC (extraneous), disable DataMemWrEn
|
||||
// 1,7 - hold PC (extraneous), disable DataMemWrEn
|
||||
// 0,0 - continue running normally (now in FG thread)
|
||||
|
||||
// Control signal used to restore the BG state of the PC and ALU flags
|
||||
assign Restore_BG_registers = (BGcontinue_pending && (Thread_switch_cnt == 1));
|
||||
// clock-by-clock sequence of events:
|
||||
// {BGcontinue_pending,Thread_switch_cnt} - action(s)
|
||||
// 0,0 - BGcontinue();
|
||||
// 1,0 - NOP;, disable DataMemWrEn
|
||||
// 1,1 - load PC & flags (Restore_BG_registers active), disable DataMemWrEn
|
||||
// 1,2 - hold PC (driving into CodeMem), disable DataMemWrEn
|
||||
// 1,3 - hold PC (CodeMem available, driving DataMem), disable DataMemWrEn
|
||||
// 1,4 - hold PC (DataMem available), disable DataMemWrEn
|
||||
// 1,5 - hold PC (extraneous), disable DataMemWrEn
|
||||
// 1,6 - hold PC (extraneous), disable DataMemWrEn
|
||||
// 1,7 - increment PC, disable DataMemWrEn
|
||||
// 0,0 - continue running normally (now in BG thread)
|
||||
|
||||
|
||||
// Control signal used to reset the PC (during BGstop or BGsave)
|
||||
assign Clear_PC = ((BGsave_pending && (Thread_switch_cnt == 2)) || (BGstop_pending));
|
||||
|
||||
// Control signal used to disable the FFE DataMem write enable, while resuming the BG thread
|
||||
assign Disable_DataMem_WrEn = (BGcontinue_pending);
|
||||
|
||||
|
||||
// BG copy of the PC
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
always @(posedge Clock_x2In or posedge ResetIn)
|
||||
`else
|
||||
always @(posedge ClockIn or posedge ResetIn)
|
||||
`endif
|
||||
if (ResetIn)
|
||||
PC_BG <= 0;
|
||||
else
|
||||
`ifdef ENABLE_FFE_F0_CM_SIZE_4K
|
||||
if (FFE_clock_halfperiod)
|
||||
`endif
|
||||
if (Save_BG_registers)
|
||||
PC_BG <= xPC;
|
||||
else
|
||||
PC_BG <= PC_BG;
|
||||
|
||||
|
||||
|
||||
// test points
|
||||
assign TP1 = 0;
|
||||
assign TP2 = 0;
|
||||
assign TP3 = 0;
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
`timescale 1ns / 10ps
|
||||
// algorithm file = 'ulpsh_s2_main_JB4_BMI160_AK09911_PD.alg'
|
||||
// UlpshType = S2_1KDM
|
||||
|
||||
module decodeMicroOpCode (MicroOpCode, Signals);
|
||||
|
||||
input [8:0] MicroOpCode;
|
||||
output [45:0] Signals;
|
||||
wire [45:0] Signals;
|
||||
|
||||
assign Signals[0] = (MicroOpCode == 9'h00e) || 0;
|
||||
assign Signals[1] = (MicroOpCode == 9'h012) || (MicroOpCode == 9'h013) || 0;
|
||||
assign Signals[2] = 0;
|
||||
assign Signals[3] = 0;
|
||||
assign Signals[4] = (MicroOpCode == 9'h038) || 0;
|
||||
assign Signals[5] = (MicroOpCode == 9'h016) || (MicroOpCode == 9'h017) || (MicroOpCode == 9'h021) || (MicroOpCode == 9'h034) || (MicroOpCode == 9'h035) || (MicroOpCode == 9'h036) || (MicroOpCode == 9'h038) || (MicroOpCode == 9'h040) || (MicroOpCode == 9'h041) || (MicroOpCode == 9'h042) || (MicroOpCode == 9'h045) || (MicroOpCode == 9'h04a) || (MicroOpCode == 9'h04e) || (MicroOpCode == 9'h04f) || 0;
|
||||
assign Signals[6] = (MicroOpCode == 9'h00a) || (MicroOpCode == 9'h014) || (MicroOpCode == 9'h020) || (MicroOpCode == 9'h024) || (MicroOpCode == 9'h026) || (MicroOpCode == 9'h027) || (MicroOpCode == 9'h028) || (MicroOpCode == 9'h02d) || (MicroOpCode == 9'h033) || (MicroOpCode == 9'h037) || (MicroOpCode == 9'h038) || (MicroOpCode == 9'h039) || (MicroOpCode == 9'h03e) || (MicroOpCode == 9'h03f) || (MicroOpCode == 9'h044) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h049) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04c) || (MicroOpCode == 9'h050) || 0;
|
||||
assign Signals[7] = (MicroOpCode == 9'h00a) || (MicroOpCode == 9'h014) || (MicroOpCode == 9'h020) || (MicroOpCode == 9'h024) || (MicroOpCode == 9'h026) || (MicroOpCode == 9'h027) || (MicroOpCode == 9'h028) || (MicroOpCode == 9'h02d) || (MicroOpCode == 9'h033) || (MicroOpCode == 9'h035) || (MicroOpCode == 9'h036) || (MicroOpCode == 9'h037) || (MicroOpCode == 9'h038) || (MicroOpCode == 9'h039) || (MicroOpCode == 9'h03e) || (MicroOpCode == 9'h03f) || (MicroOpCode == 9'h044) || (MicroOpCode == 9'h049) || (MicroOpCode == 9'h04a) || (MicroOpCode == 9'h050) || 0;
|
||||
assign Signals[8] = (MicroOpCode == 9'h00a) || (MicroOpCode == 9'h024) || (MicroOpCode == 9'h026) || (MicroOpCode == 9'h033) || (MicroOpCode == 9'h037) || (MicroOpCode == 9'h038) || (MicroOpCode == 9'h03b) || (MicroOpCode == 9'h03f) || (MicroOpCode == 9'h043) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h049) || (MicroOpCode == 9'h04a) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04c) || 0;
|
||||
assign Signals[9] = (MicroOpCode == 9'h027) || (MicroOpCode == 9'h028) || (MicroOpCode == 9'h039) || (MicroOpCode == 9'h03b) || (MicroOpCode == 9'h03e) || (MicroOpCode == 9'h043) || (MicroOpCode == 9'h044) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04c) || 0;
|
||||
assign Signals[10] = (MicroOpCode == 9'h007) || (MicroOpCode == 9'h008) || (MicroOpCode == 9'h009) || (MicroOpCode == 9'h00a) || (MicroOpCode == 9'h00d) || (MicroOpCode == 9'h00e) || (MicroOpCode == 9'h010) || (MicroOpCode == 9'h012) || (MicroOpCode == 9'h013) || (MicroOpCode == 9'h014) || (MicroOpCode == 9'h020) || (MicroOpCode == 9'h022) || (MicroOpCode == 9'h024) || (MicroOpCode == 9'h025) || (MicroOpCode == 9'h026) || (MicroOpCode == 9'h036) || (MicroOpCode == 9'h038) || (MicroOpCode == 9'h03a) || (MicroOpCode == 9'h03c) || (MicroOpCode == 9'h03d) || (MicroOpCode == 9'h03f) || (MicroOpCode == 9'h040) || (MicroOpCode == 9'h041) || (MicroOpCode == 9'h042) || (MicroOpCode == 9'h046) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h049) || (MicroOpCode == 9'h04a) || (MicroOpCode == 9'h04e) || (MicroOpCode == 9'h04f) || (MicroOpCode == 9'h050) || 0;
|
||||
assign Signals[11] = (MicroOpCode == 9'h037) || (MicroOpCode == 9'h049) || 0;
|
||||
assign Signals[12] = (MicroOpCode == 9'h03b) || (MicroOpCode == 9'h043) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04c) || 0;
|
||||
assign Signals[13] = (MicroOpCode == 9'h027) || (MicroOpCode == 9'h028) || (MicroOpCode == 9'h039) || (MicroOpCode == 9'h03b) || (MicroOpCode == 9'h03e) || (MicroOpCode == 9'h043) || (MicroOpCode == 9'h044) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04c) || 0;
|
||||
assign Signals[14] = 0;
|
||||
assign Signals[15] = (MicroOpCode == 9'h038) || (MicroOpCode == 9'h039) || (MicroOpCode == 9'h04a) || 0;
|
||||
assign Signals[16] = (MicroOpCode == 9'h034) || (MicroOpCode == 9'h035) || (MicroOpCode == 9'h048) || 0;
|
||||
assign Signals[17] = (MicroOpCode == 9'h00f) || (MicroOpCode == 9'h011) || (MicroOpCode == 9'h015) || (MicroOpCode == 9'h01c) || (MicroOpCode == 9'h029) || 0;
|
||||
assign Signals[18] = (MicroOpCode == 9'h00b) || (MicroOpCode == 9'h00f) || (MicroOpCode == 9'h01f) || (MicroOpCode == 9'h029) || 0;
|
||||
assign Signals[19] = (MicroOpCode == 9'h015) || (MicroOpCode == 9'h01f) || (MicroOpCode == 9'h029) || (MicroOpCode == 9'h031) || 0;
|
||||
assign Signals[20] = (MicroOpCode == 9'h001) || (MicroOpCode == 9'h002) || (MicroOpCode == 9'h009) || (MicroOpCode == 9'h00c) || (MicroOpCode == 9'h016) || (MicroOpCode == 9'h020) || (MicroOpCode == 9'h025) || (MicroOpCode == 9'h026) || (MicroOpCode == 9'h02c) || (MicroOpCode == 9'h02d) || (MicroOpCode == 9'h032) || (MicroOpCode == 9'h033) || (MicroOpCode == 9'h034) || (MicroOpCode == 9'h035) || (MicroOpCode == 9'h037) || (MicroOpCode == 9'h038) || (MicroOpCode == 9'h03c) || (MicroOpCode == 9'h03f) || (MicroOpCode == 9'h042) || (MicroOpCode == 9'h043) || (MicroOpCode == 9'h044) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h048) || (MicroOpCode == 9'h049) || (MicroOpCode == 9'h04a) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04d) || (MicroOpCode == 9'h04f) || 0;
|
||||
assign Signals[21] = (MicroOpCode == 9'h004) || (MicroOpCode == 9'h008) || (MicroOpCode == 9'h009) || (MicroOpCode == 9'h00c) || (MicroOpCode == 9'h010) || (MicroOpCode == 9'h013) || (MicroOpCode == 9'h016) || (MicroOpCode == 9'h019) || (MicroOpCode == 9'h01b) || (MicroOpCode == 9'h020) || (MicroOpCode == 9'h023) || (MicroOpCode == 9'h026) || (MicroOpCode == 9'h028) || (MicroOpCode == 9'h02a) || (MicroOpCode == 9'h02c) || (MicroOpCode == 9'h02d) || (MicroOpCode == 9'h02e) || (MicroOpCode == 9'h030) || (MicroOpCode == 9'h032) || (MicroOpCode == 9'h033) || (MicroOpCode == 9'h034) || (MicroOpCode == 9'h035) || (MicroOpCode == 9'h037) || (MicroOpCode == 9'h038) || (MicroOpCode == 9'h03a) || (MicroOpCode == 9'h03c) || (MicroOpCode == 9'h03d) || (MicroOpCode == 9'h03f) || (MicroOpCode == 9'h041) || (MicroOpCode == 9'h042) || (MicroOpCode == 9'h043) || (MicroOpCode == 9'h044) || (MicroOpCode == 9'h045) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h048) || (MicroOpCode == 9'h049) || (MicroOpCode == 9'h04a) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04d) || (MicroOpCode == 9'h04f) || (MicroOpCode == 9'h050) || 0;
|
||||
assign Signals[22] = (MicroOpCode == 9'h002) || (MicroOpCode == 9'h003) || (MicroOpCode == 9'h007) || (MicroOpCode == 9'h008) || (MicroOpCode == 9'h009) || (MicroOpCode == 9'h00d) || (MicroOpCode == 9'h00e) || (MicroOpCode == 9'h010) || (MicroOpCode == 9'h012) || (MicroOpCode == 9'h013) || (MicroOpCode == 9'h014) || (MicroOpCode == 9'h016) || (MicroOpCode == 9'h017) || (MicroOpCode == 9'h020) || (MicroOpCode == 9'h022) || (MicroOpCode == 9'h024) || (MicroOpCode == 9'h025) || (MicroOpCode == 9'h027) || (MicroOpCode == 9'h028) || (MicroOpCode == 9'h02a) || (MicroOpCode == 9'h02b) || (MicroOpCode == 9'h02c) || (MicroOpCode == 9'h02d) || (MicroOpCode == 9'h02e) || (MicroOpCode == 9'h02f) || (MicroOpCode == 9'h030) || (MicroOpCode == 9'h032) || (MicroOpCode == 9'h033) || (MicroOpCode == 9'h036) || (MicroOpCode == 9'h037) || (MicroOpCode == 9'h039) || (MicroOpCode == 9'h03a) || (MicroOpCode == 9'h03b) || (MicroOpCode == 9'h03c) || (MicroOpCode == 9'h03d) || (MicroOpCode == 9'h03e) || (MicroOpCode == 9'h03f) || (MicroOpCode == 9'h040) || (MicroOpCode == 9'h041) || (MicroOpCode == 9'h042) || (MicroOpCode == 9'h043) || (MicroOpCode == 9'h044) || (MicroOpCode == 9'h045) || (MicroOpCode == 9'h047) || (MicroOpCode == 9'h049) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04c) || (MicroOpCode == 9'h04e) || (MicroOpCode == 9'h04f) || (MicroOpCode == 9'h050) || 0;
|
||||
assign Signals[23] = 0;
|
||||
assign Signals[24] = 0;
|
||||
assign Signals[25] = (MicroOpCode == 9'h021) || 0;
|
||||
assign Signals[26] = (MicroOpCode == 9'h021) || 0;
|
||||
assign Signals[27] = (MicroOpCode == 9'h002) || (MicroOpCode == 9'h003) || 0;
|
||||
assign Signals[28] = (MicroOpCode == 9'h04d) || 0;
|
||||
assign Signals[29] = (MicroOpCode == 9'h023) || (MicroOpCode == 9'h02e) || (MicroOpCode == 9'h03d) || (MicroOpCode == 9'h04d) || 0;
|
||||
assign Signals[30] = (MicroOpCode == 9'h018) || (MicroOpCode == 9'h019) || (MicroOpCode == 9'h01a) || (MicroOpCode == 9'h01b) || 0;
|
||||
assign Signals[31] = (MicroOpCode == 9'h006) || 0;
|
||||
assign Signals[32] = (MicroOpCode == 9'h01e) || 0;
|
||||
assign Signals[33] = (MicroOpCode == 9'h039) || (MicroOpCode == 9'h03e) || (MicroOpCode == 9'h044) || (MicroOpCode == 9'h04b) || (MicroOpCode == 9'h04c) || 0;
|
||||
assign Signals[34] = (MicroOpCode == 9'h022) || (MicroOpCode == 9'h02a) || (MicroOpCode == 9'h02b) || (MicroOpCode == 9'h02c) || (MicroOpCode == 9'h03a) || (MicroOpCode == 9'h03c) || (MicroOpCode == 9'h03d) || (MicroOpCode == 9'h04e) || (MicroOpCode == 9'h04f) || 0;
|
||||
assign Signals[35] = (MicroOpCode == 9'h027) || (MicroOpCode == 9'h028) || 0;
|
||||
assign Signals[36] = (MicroOpCode == 9'h01d) || 0;
|
||||
assign Signals[37] = (MicroOpCode == 9'h018) || (MicroOpCode == 9'h019) || 0;
|
||||
assign Signals[38] = (MicroOpCode == 9'h00d) || (MicroOpCode == 9'h00e) || (MicroOpCode == 9'h010) || 0;
|
||||
assign Signals[39] = 0;
|
||||
assign Signals[40] = (MicroOpCode == 9'h005) || 0;
|
||||
assign Signals[41] = 0;
|
||||
assign Signals[42] = 0;
|
||||
assign Signals[43] = 0;
|
||||
assign Signals[44] = (MicroOpCode == 9'h01c) || 0;
|
||||
assign Signals[45] = 0;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
// -----------------------------------------------------------------------------
|
||||
// title : Sensor Manager Memory Module
|
||||
// project : ULP Sensor Hub
|
||||
// -----------------------------------------------------------------------------
|
||||
// file : SMEMemoryMux.v
|
||||
// author : OCTO
|
||||
// company : QuickLogic Corp
|
||||
// created : 2012/??/??
|
||||
// last update : 2014/05/20
|
||||
// platform : PolarPro III
|
||||
// standard : Verilog 2001
|
||||
// -----------------------------------------------------------------------------
|
||||
// description: The Sensor Manger Memory Mux selects between several sources
|
||||
// for passing both read and write information.
|
||||
// -----------------------------------------------------------------------------
|
||||
// copyright (c) 2013
|
||||
// -----------------------------------------------------------------------------
|
||||
// revisions :
|
||||
// date version author description
|
||||
// 2014/05/20 1.0 Glen Gomes Updated -> Added support for a second
|
||||
// memory block by adding
|
||||
// address bits.
|
||||
// -----------------------------------------------------------------------------
|
||||
// Comments: This solution is specifically for use with the QuickLogic
|
||||
// PolarPro III S2 device.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
`timescale 1ns / 10ps
|
||||
|
||||
module SMEMemoryMux (
|
||||
input Select,
|
||||
|
||||
input [9:0] ReadAddressIn0, // Expanded for Rel 0 on 6/18
|
||||
input [9:0] ReadAddressIn1, // Expanded for Rel 0 on 6/18
|
||||
output[9:0] ReadAddressOut, // Expanded for Rel 0 on 6/18
|
||||
|
||||
input [9:0] WriteAddressIn0,
|
||||
input [9:0] WriteAddressIn1,
|
||||
output[9:0] WriteAddressOut,
|
||||
|
||||
input [8:0] DataToMemoryIn0,
|
||||
input [8:0] DataToMemoryIn1,
|
||||
output[8:0] DataToMemoryOut,
|
||||
|
||||
input [17:0] DataFromMemoryIn0,
|
||||
input [17:0] DataFromMemoryIn1,
|
||||
output[17:0] DataFromMemoryOut,
|
||||
|
||||
input ReadEnableIn0,
|
||||
input ReadEnableIn1,
|
||||
output ReadEnableOut,
|
||||
|
||||
input WriteEnableIn0,
|
||||
input WriteEnableIn1,
|
||||
output WriteEnableOut,
|
||||
|
||||
input ReadClockIn0,
|
||||
input ReadClockIn1,
|
||||
output ReadClockOut
|
||||
);
|
||||
|
||||
assign ReadAddressOut = (Select) ? ReadAddressIn1 : ReadAddressIn0;
|
||||
assign WriteAddressOut = (Select) ? WriteAddressIn1 : WriteAddressIn0;
|
||||
assign DataToMemoryOut = (Select) ? DataToMemoryIn1 : DataToMemoryIn0;
|
||||
assign DataFromMemoryOut = (Select) ? DataFromMemoryIn1 : DataFromMemoryIn0;
|
||||
assign ReadEnableOut = (Select) ? ReadEnableIn1 : ReadEnableIn0;
|
||||
assign WriteEnableOut = (Select) ? WriteEnableIn1 : WriteEnableIn0;
|
||||
assign ReadClockOut = (Select) ? ReadClockIn1 : ReadClockIn0;
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,112 @@
|
|||
// -----------------------------------------------------------------------------
|
||||
// title : Sensor Manager Memory Module
|
||||
// project : ULP Sensor Hub
|
||||
// -----------------------------------------------------------------------------
|
||||
// file : SMMemory.v
|
||||
// author : OCTO
|
||||
// company : QuickLogic Corp
|
||||
// created : 2012/??/??
|
||||
// last update : 2014/05/20
|
||||
// platform : PolarPro III
|
||||
// standard : Verilog 2001
|
||||
// -----------------------------------------------------------------------------
|
||||
// description: The Sensor Manger Memory performs several tasks. These include
|
||||
// storing Sensor Manager Instructions, Sensor Data, and FFE mail
|
||||
// box data. This memory consists of several physical memory
|
||||
// blocks.
|
||||
// -----------------------------------------------------------------------------
|
||||
// copyright (c) 2013
|
||||
// -----------------------------------------------------------------------------
|
||||
// revisions :
|
||||
// date version author description
|
||||
// 2014/05/20 1.0 Glen Gomes Updated -> Added a second memory block
|
||||
// -----------------------------------------------------------------------------
|
||||
// Comments: This solution is specifically for use with the QuickLogic
|
||||
// PolarPro III S2 device.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
`timescale 1ns / 10ps
|
||||
|
||||
module SMMemory (
|
||||
// General Interface
|
||||
input ResetIn,
|
||||
input SMBusyIn,
|
||||
|
||||
//Read Interface
|
||||
input [9:0] ReadAddressIn,
|
||||
output [17:0] ReadDataOut,
|
||||
input ReadSelectIn,
|
||||
input ReadClockIn,
|
||||
|
||||
//Write Interface
|
||||
input [9:0] WriteAddressIn,
|
||||
input [8:0] WriteDataIn,
|
||||
input WriteSelectIn,
|
||||
|
||||
input [9:0] WriteAddressIn_TLC,
|
||||
input [8:0] WriteDataIn_TLC,
|
||||
input WriteSelectIn_TLC,
|
||||
|
||||
input WriteClockIn,
|
||||
|
||||
output [9:0] SMMemory_WriteAddressIn_TLC_o,
|
||||
output [8:0] SMMemory_ReadAddressIn_o,
|
||||
output SMMemory_WriteSelectIn_TLC_o,
|
||||
output SMMemory_ReadSelect_RAM0_o,
|
||||
output SMMemory_WriteClockIn_o,
|
||||
output SMMemory_ReadClockIn_o,
|
||||
output [8:0] SMMemory_WriteDataIn_TLC_o,
|
||||
input [17:0] SMMemory_ReadDataOut_SRAM_i,
|
||||
output [9:0] SMMemory_WriteAddressIn_o,
|
||||
output SMMemory_WriteSelectIn_o,
|
||||
output SMMemory_ReadSelect_RAM1_o,
|
||||
output SMMemory_WriteDataIn_o,
|
||||
input [17:0] SMMemory_ReadDataOut_SRAM1_i
|
||||
|
||||
|
||||
|
||||
|
||||
);
|
||||
|
||||
// Define local variables
|
||||
//
|
||||
wire [17:0] ReadDataOut_SRAM;
|
||||
wire [17:0] ReadDataOut_SRAM_1;
|
||||
|
||||
reg ReadDataSel;
|
||||
wire ReadSelect_RAM0;
|
||||
wire ReadSelect_RAM1;
|
||||
wire SMMemoryBankSelect;
|
||||
|
||||
|
||||
// generate individual read enables
|
||||
assign ReadSelect_RAM0 = ReadSelectIn && !ReadAddressIn[9];
|
||||
assign ReadSelect_RAM1 = ReadSelectIn && ReadAddressIn[9];
|
||||
|
||||
|
||||
// Mux the read data
|
||||
always @(posedge ReadClockIn)
|
||||
ReadDataSel <= ReadAddressIn[9];
|
||||
|
||||
assign SMMemoryBankSelect = SMBusyIn ? ReadAddressIn[9] : ReadDataSel;
|
||||
assign ReadDataOut = SMMemoryBankSelect ? ReadDataOut_SRAM_1: ReadDataOut_SRAM;
|
||||
|
||||
|
||||
// Instantiate the Memory Blocks
|
||||
//
|
||||
assign SMMemory_WriteAddressIn_TLC_o = WriteAddressIn_TLC;
|
||||
assign SMMemory_ReadAddressIn_o[8:0] = ReadAddressIn[8:0];
|
||||
assign SMMemory_WriteSelectIn_TLC_o = WriteSelectIn_TLC;
|
||||
assign SMMemory_ReadSelect_RAM0_o = ReadSelect_RAM0;
|
||||
assign SMMemory_WriteClockIn_o = WriteClockIn;
|
||||
assign SMMemory_ReadClockIn_o = ReadClockIn;
|
||||
assign SMMemory_WriteDataIn_TLC_o = WriteDataIn_TLC;
|
||||
assign ReadDataOut_SRAM = SMMemory_ReadDataOut_SRAM_i;
|
||||
|
||||
assign SMMemory_WriteAddressIn_o = WriteAddressIn;
|
||||
assign SMMemory_WriteSelectIn_o = WriteSelectIn;
|
||||
assign SMMemory_ReadSelect_RAM1_o = ReadSelect_RAM1;
|
||||
assign SMMemory_WriteDataIn_o = WriteDataIn;
|
||||
assign ReadDataOut_SRAM1 = SMMemory_ReadDataOut_SRAM1_i;
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,292 @@
|
|||
|
||||
/*------------------------------------------------------------------------------
|
||||
SPI_slave
|
||||
SPI slave interface, designed for the ULP Sensor Hub.
|
||||
This module is designed to be as small and simple as possible, while
|
||||
supporting the ULP Sensor Hub. Only supports SPI Mode 0 (CPOL=CPHA=0)...
|
||||
which means that input data is latched on the positive edge of SPI_SCLK,
|
||||
and driven out on the negative edge of SPI_SCLK, with the base value of
|
||||
SPI_SCLK being 0.
|
||||
|
||||
|
||||
SPI Protocol:
|
||||
Writes: MOSI: A0 + D0 + D1 + ... + Dn
|
||||
MISO: xx + xx + xx + ... + xx
|
||||
|
||||
Reads: MOSI: A0 + xx + xx + ... + xx
|
||||
MISO: xx + xx + D0 + ... + Dn
|
||||
|
||||
A0 = [1-bit R/W: 1=write, 0=read] + [7-bit address]
|
||||
Dn = valid data byte
|
||||
xx = don't-care data byte
|
||||
|
||||
It is assumed that the MSb is transmitted first, and the LSb last.
|
||||
|
||||
The address is latched, and auto-incremented to support burst reads/writes.
|
||||
The address, when 0d11, jumps back to 0d07, to support repeated (burst)
|
||||
reads to/from the memory data port. The logic to re-map addresses above
|
||||
0d11, that previously was in TLC.v, can now be removed. New registers
|
||||
above 0d11 may now be added if needed.
|
||||
|
||||
This SPI slave requires extra edges on SPI_SCLK to complete any write
|
||||
operation. This may be accomplished in any one of several ways:
|
||||
1. A (non-destructive) read should be performed following the last
|
||||
write operation.
|
||||
2. SPI_SCLK should be toggled after SPI_SS goes inactive
|
||||
(a free-running SPI_SCLK would accomplish this).
|
||||
3. A few extra bits (totaling less than a full byte) should be
|
||||
transmitted by the master. These extra bits will be ignored by
|
||||
this core, but will provide the clocks needed to generated the
|
||||
wr_data_valid pulse.
|
||||
4. A "null" transaction should be performed following the last
|
||||
write transaction, during which the address byte is transmitted
|
||||
by the SPI master followed by 0 bytes of read/write data.
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
|
||||
`timescale 1ns / 1ns
|
||||
|
||||
`include "SensorHubDefines.v"
|
||||
|
||||
|
||||
module SPI_slave (
|
||||
input rst, // system/global reset (active-high)
|
||||
|
||||
// SPI interface
|
||||
input SPI_SCLK, // base value 0 (mode 0)
|
||||
input SPI_MOSI, // master out, slave in
|
||||
output SPI_MISO, // master in, slave out
|
||||
input SPI_SS, // slave select (active-low)
|
||||
|
||||
// internal interface
|
||||
output [6:0] addr,
|
||||
output [7:0] wr_data,
|
||||
output wr_data_valid, // active high
|
||||
input [7:0] rd_data,
|
||||
output rd_data_ack
|
||||
);
|
||||
|
||||
|
||||
parameter WR = 1'b1;
|
||||
parameter RD = 1'b0;
|
||||
|
||||
|
||||
wire rst_int;
|
||||
|
||||
reg [7:0] shift_in;
|
||||
reg [7:0] shift_out;
|
||||
|
||||
reg [2:0] bit_cnt, bit_cnt_neg;
|
||||
|
||||
reg rcv_byte_valid;
|
||||
reg addr_has_been_latched;
|
||||
reg first_data_has_been_latched;
|
||||
reg [6:0] addr_reg;
|
||||
reg write_readn;
|
||||
reg [7:0] write_data_reg;
|
||||
reg wr_data_valid_reg;
|
||||
reg write_pending;
|
||||
reg rd_data_ack_reg;
|
||||
|
||||
|
||||
|
||||
// rst_int is active when the global rst occurs or when the SPI interface is idle.
|
||||
// Some logic needs to remain active after a SPI transaction occurs, so rst will be used in those cases.
|
||||
assign rst_int = rst || SPI_SS;
|
||||
|
||||
// input shift register
|
||||
always @(posedge rst_int or posedge SPI_SCLK)
|
||||
if (rst_int)
|
||||
shift_in <= 8'b0;
|
||||
else
|
||||
if (!SPI_SS)
|
||||
shift_in <= {shift_in[6:0], SPI_MOSI};
|
||||
else
|
||||
shift_in <= shift_in;
|
||||
|
||||
|
||||
// bit counter
|
||||
always @(posedge rst_int or posedge SPI_SCLK)
|
||||
if (rst_int)
|
||||
bit_cnt <= 3'b0;
|
||||
else
|
||||
if (!SPI_SS)
|
||||
bit_cnt <= bit_cnt + 1;
|
||||
else
|
||||
bit_cnt <= 3'b0;
|
||||
|
||||
|
||||
// byte valid, active for 1 clk every time a full byte has been received from the master
|
||||
always @(posedge rst_int or posedge SPI_SCLK)
|
||||
if (rst_int)
|
||||
rcv_byte_valid <= 1'b0;
|
||||
else
|
||||
if (rcv_byte_valid) // added to guarantee that rcv_byte_valid is only active for 1 clock
|
||||
rcv_byte_valid <= 1'b0;
|
||||
else
|
||||
if (!SPI_SS && (bit_cnt == 3'b111))
|
||||
rcv_byte_valid <= 1'b1;
|
||||
else
|
||||
rcv_byte_valid <= 1'b0;
|
||||
|
||||
|
||||
// flags for keeping track of the address byte and 1st data byte
|
||||
always @(posedge rst_int or posedge SPI_SCLK)
|
||||
if (rst_int) begin
|
||||
addr_has_been_latched <= 1'b0; // flag that gets set after the addr has been received (and latched)
|
||||
first_data_has_been_latched <= 1'b0; // flag that gets set after the 1st data byte has been received (and latched)
|
||||
end
|
||||
else begin
|
||||
|
||||
// if (SPI_SS) // if SPI interface is idle
|
||||
// addr_has_been_latched <= 1'b0;
|
||||
// else
|
||||
// the above is not necessary since the async rst includes SPI_SS
|
||||
if (rcv_byte_valid)
|
||||
addr_has_been_latched <= 1'b1; // set flag after first byte (the address) is received, keep at 1 until transaction is over
|
||||
else
|
||||
addr_has_been_latched <= addr_has_been_latched;
|
||||
|
||||
// if (SPI_SS) // if SPI interface is idle
|
||||
// first_data_has_been_latched <= 1'b0;
|
||||
// else
|
||||
// the above is not necessary since the async rst includes SPI_SS
|
||||
if (addr_has_been_latched && rcv_byte_valid)
|
||||
first_data_has_been_latched <= 1'b1;
|
||||
else
|
||||
first_data_has_been_latched <= first_data_has_been_latched;
|
||||
|
||||
end
|
||||
|
||||
|
||||
// address register, direction control flag
|
||||
always @(posedge rst or posedge SPI_SCLK) // don't use rst_int so these signals will remain active even after SPI_SS has gone inactive
|
||||
if (rst) begin
|
||||
addr_reg <= 7'b0;
|
||||
write_readn <= 1'b0; // flag that signifies a write vs. read transaction
|
||||
end
|
||||
else begin
|
||||
|
||||
if (!addr_has_been_latched && rcv_byte_valid)
|
||||
write_readn <= shift_in[7]; // the direction (r/w) flag is in the MSb of the address byte.
|
||||
else
|
||||
write_readn <= write_readn;
|
||||
|
||||
if (!addr_has_been_latched)
|
||||
if (rcv_byte_valid)
|
||||
addr_reg <= shift_in[6:0]; // latch the new address, located in the lowest 7 bits of the address byte.
|
||||
else
|
||||
addr_reg <= addr_reg;
|
||||
else // addr_has_been_latched
|
||||
|
||||
// if (((write_readn == WR) && wr_data_valid_reg) || ((write_readn == RD) && rcv_byte_valid))
|
||||
// addr_reg <= addr_reg + 1;
|
||||
// else
|
||||
// addr_reg <= addr_reg;
|
||||
|
||||
// during writes, make addr_reg wrap back to MemDataByte0 after MemDataByte4
|
||||
if ((write_readn == WR) && wr_data_valid_reg)
|
||||
if (addr_reg == `MemDataByte4)
|
||||
addr_reg <= `MemDataByte0;
|
||||
else
|
||||
addr_reg <= addr_reg + 1;
|
||||
else
|
||||
// during reads, do not increment addr_reg when accessing CM_FIFO_Data
|
||||
//if ((write_readn == RD) && rcv_byte_valid)
|
||||
if ((write_readn == RD) && rd_data_ack_reg)
|
||||
if (addr_reg == `CM_FIFO_Data)
|
||||
addr_reg <= addr_reg;
|
||||
else
|
||||
addr_reg <= addr_reg + 1;
|
||||
else
|
||||
addr_reg <= addr_reg;
|
||||
|
||||
end
|
||||
|
||||
|
||||
// write_pending flag, so writes eventually get sent to the internal interface when more SPI_SCLK edges occur
|
||||
always @(posedge rst or posedge SPI_SCLK) // don't use rst_int since this may need to stay active after SPI_SS goes inactive
|
||||
if (rst)
|
||||
write_pending <= 1'b0;
|
||||
else
|
||||
if (wr_data_valid_reg)
|
||||
write_pending <= 1'b0;
|
||||
else
|
||||
if ((write_readn == WR) && !SPI_SS && addr_has_been_latched && (bit_cnt == 3'b111)) // can't use rcv_byte_valid since there may not be extra clocks after this byte is being written
|
||||
write_pending <= 1'b1;
|
||||
else
|
||||
write_pending <= write_pending;
|
||||
|
||||
|
||||
// write data valid signal
|
||||
always @(posedge rst or posedge SPI_SCLK) // don't use rst_int since this may need to be set after SPI_SS goes inactive
|
||||
if (rst)
|
||||
wr_data_valid_reg <= 1'b0;
|
||||
else
|
||||
if (wr_data_valid_reg)
|
||||
wr_data_valid_reg <= 1'b0;
|
||||
else
|
||||
if (write_pending)
|
||||
wr_data_valid_reg <= 1'b1;
|
||||
else
|
||||
wr_data_valid_reg <= wr_data_valid_reg;
|
||||
|
||||
|
||||
always @(posedge rst or posedge SPI_SCLK) // don't use rst_int since this needs to stay valid after SPI_SS goes inactive
|
||||
if (rst)
|
||||
write_data_reg <= 8'b0;
|
||||
else
|
||||
if (!SPI_SS && (bit_cnt == 3'b111))
|
||||
write_data_reg <= {shift_in[6:0], SPI_MOSI};
|
||||
else
|
||||
write_data_reg <= write_data_reg;
|
||||
|
||||
|
||||
// output shift register
|
||||
always @(posedge rst_int or negedge SPI_SCLK)
|
||||
if (rst_int) begin
|
||||
bit_cnt_neg <= 3'b0;
|
||||
shift_out <= 8'b0;
|
||||
end
|
||||
else begin
|
||||
if (!SPI_SS) begin
|
||||
bit_cnt_neg <= bit_cnt_neg + 1;
|
||||
|
||||
if (addr_has_been_latched && (bit_cnt_neg == 7))
|
||||
shift_out <= rd_data;
|
||||
else
|
||||
shift_out <= {shift_out[6:0], 1'b0};
|
||||
end
|
||||
else begin
|
||||
bit_cnt_neg <= 3'b0;
|
||||
shift_out <= shift_out;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// read data acknowledge. this is required to pop data from the CM FIFO
|
||||
always @(posedge rst_int or posedge SPI_SCLK)
|
||||
if (rst_int)
|
||||
rd_data_ack_reg <= 1'b0;
|
||||
else
|
||||
//if ( addr_has_been_latched && (write_readn == RD) && (bit_cnt == 3'b111) )
|
||||
if ( addr_has_been_latched && (write_readn == RD) && rcv_byte_valid)
|
||||
rd_data_ack_reg <= 1'b1;
|
||||
else
|
||||
rd_data_ack_reg <= 1'b0;
|
||||
|
||||
|
||||
|
||||
// assignments to the outputs
|
||||
//assign SPI_MISO = SPI_SS ? 1'bz : shift_out[7];
|
||||
assign SPI_MISO = shift_out[7];//AP2 doesn't support tristate
|
||||
assign addr = addr_reg;
|
||||
assign wr_data = write_data_reg;
|
||||
assign wr_data_valid = wr_data_valid_reg;
|
||||
assign rd_data_ack = rd_data_ack_reg;
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
|
||||
`ifndef SensorHub_Definitions
|
||||
|
||||
`define SensorHub_Definitions
|
||||
|
||||
// Communication Manager register offsets
|
||||
`define CommandReg 7'h00
|
||||
`define StatusReg 7'h01
|
||||
`define milSecSample 7'h02
|
||||
`define InterruptCtrl 7'h03
|
||||
`define InterruptStat 7'h04
|
||||
`define CalValueLow 7'h05
|
||||
`define CalValueHi 7'h06
|
||||
`define Reserved_10 7'h07
|
||||
`define Reserved_11 7'h08
|
||||
`define Reserved_12 7'h09
|
||||
`define Reserved_13 7'h0A
|
||||
`define Reserved_14 7'h0B
|
||||
`define CM_FIFO_Data 7'h0C
|
||||
`define CM_Control 7'h0D
|
||||
`define CM_Status 7'h0E
|
||||
`define CM_FIFO_Flags_0 7'h0F
|
||||
`define Reserved_1 7'h10 /* reserved for CM_FIFO_Flags_23 */
|
||||
`define MailboxToFFE_0 7'h11
|
||||
`define MailboxToFFE_1 7'h12
|
||||
`define MailboxToFFE_2 7'h13
|
||||
`define MailboxToFFE_3 7'h14
|
||||
`define InterruptFFEMsg 7'h15
|
||||
`define Reserved_5 7'h16
|
||||
`define Reserved_6 7'h17
|
||||
`define Reserved_7 7'h18
|
||||
`define RunTimeAdrReg 7'h19
|
||||
`define DemoLedCtrlReg 7'h1A /* Register to control demo LEDs */
|
||||
`define ClocksControl 7'h1B
|
||||
`define SleepControl 7'h1C
|
||||
`define RunTimeAdrReg_Upr 7'h1D /* New for Rel 0 on 6/18 */
|
||||
`define MemAddrLow 7'h20
|
||||
`define MemAddrHigh 7'h21
|
||||
`define MemSelect 7'h22
|
||||
`define MemDataByte0 7'h28
|
||||
`define MemDataByte1 7'h29
|
||||
`define MemDataByte2 7'h2A
|
||||
`define MemDataByte3 7'h2B
|
||||
`define MemDataByte4 7'h2C
|
||||
|
||||
|
||||
`define CtrlSensorManager 8'h00
|
||||
`define CtrlReceiveAddress 8'h01
|
||||
`define CtrlRunTimeAddress 8'h02
|
||||
`define MasterPreLo 8'h08
|
||||
`define MasterPreHi 8'h09
|
||||
`define MasterCTR 8'h0A
|
||||
`define MasterTXR 8'h0B
|
||||
`define MasterCR 8'h0C
|
||||
|
||||
|
||||
`define CR_START 8'b1000_0000
|
||||
`define CR_STOP 8'b0100_0000
|
||||
`define CR_READ 8'b0010_0000
|
||||
`define CR_WRITE 8'b0001_0000
|
||||
`define CR_NAK 8'b0000_1000
|
||||
// `define CR_POLL 8'b0000_0100
|
||||
`define CR_IACK 8'b0000_0001
|
||||
|
||||
`endif
|
|
@ -0,0 +1,960 @@
|
|||
// -----------------------------------------------------------------------------
|
||||
// title : Sensor Manager Main Routine
|
||||
// project : ULP Sensor Hub
|
||||
// -----------------------------------------------------------------------------
|
||||
// file : SensorManager.v
|
||||
// author : OCTO
|
||||
// company : QuickLogic Corp
|
||||
// created : 2012/??/??
|
||||
// last update : 2013/12/06
|
||||
// platform : PolarPro III
|
||||
// standard : Verilog 2001
|
||||
// -----------------------------------------------------------------------------
|
||||
// description: The Sensor Manger is responsible for controlling various
|
||||
// external sensors and storing the resulting data in Sensor
|
||||
// Manager Memory. These include performing transfers between
|
||||
// Sensor Memory and various registers.
|
||||
// -----------------------------------------------------------------------------
|
||||
// copyright (c) 2013
|
||||
// -----------------------------------------------------------------------------
|
||||
// revisions :
|
||||
// date version author description
|
||||
// 2013/12/06 1.0 Glen Gomes Updated -> Mostly re-written
|
||||
// -----------------------------------------------------------------------------
|
||||
// Comments: This solution is specifically for use with the QuickLogic
|
||||
// PolarPro III device.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
`timescale 1ns / 10ps
|
||||
|
||||
module SensorManager (
|
||||
|
||||
// General interface
|
||||
ClockIn,
|
||||
ResetIn,
|
||||
StartFromFFE,
|
||||
StartFromTLC,
|
||||
BusyOut,
|
||||
TimeStamp_Delta_i,
|
||||
TimeStamp_Delta_Tog_i,
|
||||
SensorInterrupt_0_i,
|
||||
SensorInterrupt_1_i,
|
||||
SensorInterrupt_2_i,
|
||||
SensorInterrupt_3_i,
|
||||
SensorInterrupt_0_o,
|
||||
SensorInterrupt_1_o,
|
||||
SensorInterrupt_2_o,
|
||||
SensorInterrupt_3_o,
|
||||
CtrlRunTimeAddressSM,
|
||||
CtrlRunTimeAddressOut,
|
||||
CtrlRunTimeAddressReg,
|
||||
MemReadAddressOut,
|
||||
MemReadEnableOut,
|
||||
MemReadDataIn,
|
||||
MemWriteAddressOut,
|
||||
MemWriteEnableOut,
|
||||
MemWriteDataOut,
|
||||
MemClockOut,
|
||||
I2C_wb_adr_o,
|
||||
I2C_wb_dat_o,
|
||||
I2C_wb_dat_i,
|
||||
I2C_wb_we_o,
|
||||
I2C_wb_stb_o,
|
||||
I2C_wb_cyc_o,
|
||||
I2C_wb_ack_i,
|
||||
I2C_tip_i,
|
||||
TP1,
|
||||
TP2,
|
||||
TP3,
|
||||
SmClockSelect_o
|
||||
);
|
||||
|
||||
//-----Port Signals--------------------
|
||||
//
|
||||
|
||||
input ClockIn;
|
||||
input ResetIn;
|
||||
input StartFromFFE;
|
||||
input StartFromTLC;
|
||||
output BusyOut;
|
||||
input [15:0] TimeStamp_Delta_i;
|
||||
input TimeStamp_Delta_Tog_i;
|
||||
input SensorInterrupt_0_i;
|
||||
input SensorInterrupt_1_i;
|
||||
input SensorInterrupt_2_i;
|
||||
input SensorInterrupt_3_i;
|
||||
output SensorInterrupt_0_o;
|
||||
output SensorInterrupt_1_o;
|
||||
output SensorInterrupt_2_o;
|
||||
output SensorInterrupt_3_o;
|
||||
input CtrlRunTimeAddressSM;
|
||||
input [9:0] CtrlRunTimeAddressOut;
|
||||
output [9:0] CtrlRunTimeAddressReg;
|
||||
output [9:0] MemReadAddressOut; // Expanded for Rel 0 on 6/18
|
||||
output MemReadEnableOut;
|
||||
input [17:0] MemReadDataIn;
|
||||
output [9:0] MemWriteAddressOut;
|
||||
output MemWriteEnableOut;
|
||||
output [8:0] MemWriteDataOut;
|
||||
output MemClockOut;
|
||||
output [2:0] I2C_wb_adr_o;
|
||||
output [7:0] I2C_wb_dat_o;
|
||||
input [7:0] I2C_wb_dat_i;
|
||||
output I2C_wb_we_o;
|
||||
output I2C_wb_stb_o;
|
||||
output I2C_wb_cyc_o;
|
||||
input I2C_wb_ack_i;
|
||||
input I2C_tip_i;
|
||||
output TP1;
|
||||
output TP2;
|
||||
output TP3;
|
||||
output SmClockSelect_o;
|
||||
|
||||
|
||||
wire ClockIn;
|
||||
wire ResetIn;
|
||||
wire StartFromFFE;
|
||||
wire StartFromTLC;
|
||||
wire BusyOut;
|
||||
wire [15:0] TimeStamp_Delta_i;
|
||||
wire TimeStamp_Delta_Tog_i;
|
||||
wire SensorInterrupt_0_i;
|
||||
wire SensorInterrupt_1_i;
|
||||
wire SensorInterrupt_2_i;
|
||||
wire SensorInterrupt_3_i;
|
||||
reg SensorInterrupt_0_o;
|
||||
reg SensorInterrupt_1_o;
|
||||
reg SensorInterrupt_2_o;
|
||||
reg SensorInterrupt_3_o;
|
||||
wire CtrlRunTimeAddressSM;
|
||||
wire [9:0] CtrlRunTimeAddressOut;
|
||||
reg [9:0] CtrlRunTimeAddressReg;
|
||||
wire [9:0] MemReadAddressOut; // Expanded for Rel 0 on 6/18
|
||||
wire MemReadEnableOut;
|
||||
wire [17:0] MemReadDataIn;
|
||||
wire [9:0] MemWriteAddressOut;
|
||||
wire MemWriteEnableOut;
|
||||
reg [8:0] MemWriteDataOut;
|
||||
wire [2:0] I2C_wb_adr_o;
|
||||
wire [7:0] I2C_wb_dat_o;
|
||||
wire [7:0] I2C_wb_dat_i;
|
||||
wire I2C_wb_we_o;
|
||||
wire I2C_wb_stb_o;
|
||||
wire I2C_wb_cyc_o;
|
||||
wire I2C_wb_ack_i;
|
||||
wire I2C_tip_i;
|
||||
wire MemClockOut;
|
||||
wire TP1;
|
||||
wire TP2;
|
||||
wire TP3;
|
||||
reg SmClockSelect_o;
|
||||
|
||||
|
||||
//-----Internal Signals--------------------
|
||||
//
|
||||
|
||||
wire wb_cyc;
|
||||
|
||||
wire wb_we;
|
||||
wire wb_stb;
|
||||
|
||||
wire wb_ack;
|
||||
reg wb_ack_sm;
|
||||
|
||||
wire wb_busy_poll;
|
||||
|
||||
reg [9:0] CtrlReceiveAddressReg;
|
||||
|
||||
reg [5:0] CtrlMailBoxSegmentCtr;
|
||||
reg CtrlMailBoxSegmentCtr_ce;
|
||||
|
||||
reg [9:2] CtrlMailBoxTablePtr;
|
||||
|
||||
reg [9:0] CtrlMailBoxJumpInstPtr;
|
||||
|
||||
reg CtrlMailBoxJumpInstCycle;
|
||||
reg CtrlMailBoxJumpInstCycle_ce;
|
||||
|
||||
wire [9:0] StateMachineCtrlMemAddr;
|
||||
wire [7:0] i2c_masterDataToMem;
|
||||
|
||||
wire save_reg_2_mem;
|
||||
|
||||
wire control_sensor_manager_reg_dcd;
|
||||
wire control_receive_reg_dcd;
|
||||
wire control_runtime_reg_dcd;
|
||||
wire control_jump_reg_dcd;
|
||||
wire control_mailbox_tbl_ptr_dcd;
|
||||
wire control_mailbox_jump_inst_ptr_dcd;
|
||||
|
||||
reg RunSM;
|
||||
wire BusySM;
|
||||
|
||||
wire StartIn_stb;
|
||||
|
||||
reg StartFromFFE_1ff;
|
||||
reg StartFromFFE_2ff;
|
||||
reg StartFromFFE_3ff;
|
||||
reg StartFromFFE_4ff;
|
||||
reg StartFromFFE_5ff;
|
||||
reg StartFromFFE_6ff;
|
||||
|
||||
reg StartFromTLC_1ff;
|
||||
reg StartFromTLC_2ff;
|
||||
|
||||
reg CtrlRunTimeAddressSM_1ff;
|
||||
reg CtrlRunTimeAddressSM_2ff;
|
||||
|
||||
reg s1_BusyOut, s2_BusyOut;
|
||||
|
||||
// Define write enable controls for each TimeStamp register
|
||||
//
|
||||
wire SensorInterrupt_event_reg_we_dcd;
|
||||
|
||||
wire SensorInterrupt_event_mask_we_dcd;
|
||||
|
||||
reg SensorInterrupt_event_mask_0;
|
||||
reg SensorInterrupt_event_mask_1;
|
||||
reg SensorInterrupt_event_mask_2;
|
||||
reg SensorInterrupt_event_mask_3;
|
||||
|
||||
|
||||
// Delta Time Stamp registers for each sensor
|
||||
//
|
||||
reg [7:0] TimeStamp_Delta_sensor_0;
|
||||
reg [7:0] TimeStamp_Delta_sensor_1;
|
||||
reg [7:0] TimeStamp_Delta_sensor_2;
|
||||
reg [7:0] TimeStamp_Delta_sensor_3;
|
||||
|
||||
reg [15:0] TimeStamp_Delta_capt;
|
||||
reg [15:0] TimeStamp_Delta_readback;
|
||||
|
||||
reg TimeStamp_Delta_Tog_1ff;
|
||||
reg TimeStamp_Delta_Tog_2ff;
|
||||
reg TimeStamp_Delta_Tog_3ff;
|
||||
|
||||
// Meta-state registers for each sensor interrupt
|
||||
//
|
||||
reg SensorInterrupt_0_1ff;
|
||||
reg SensorInterrupt_0_2ff;
|
||||
reg SensorInterrupt_0_3ff;
|
||||
|
||||
reg SensorInterrupt_1_1ff;
|
||||
reg SensorInterrupt_1_2ff;
|
||||
reg SensorInterrupt_1_3ff;
|
||||
|
||||
reg SensorInterrupt_2_1ff;
|
||||
reg SensorInterrupt_2_2ff;
|
||||
reg SensorInterrupt_2_3ff;
|
||||
|
||||
reg SensorInterrupt_3_1ff;
|
||||
reg SensorInterrupt_3_2ff;
|
||||
reg SensorInterrupt_3_3ff;
|
||||
|
||||
|
||||
// Wait Instruction Registers
|
||||
//
|
||||
wire control_wait_instr_reg_dcd;
|
||||
|
||||
reg [12:0] control_wait_instr_cntr;
|
||||
reg [12:0] control_wait_instr_cntr_nxt;
|
||||
|
||||
reg control_wait_instr_cntr_tc;
|
||||
reg control_wait_instr_cntr_tc_nxt;
|
||||
|
||||
reg control_wait_instr_busy;
|
||||
wire control_wait_instr_busy_nxt;
|
||||
|
||||
|
||||
|
||||
//------Define Parameters---------
|
||||
//
|
||||
|
||||
//
|
||||
// Define the various address spaces
|
||||
//
|
||||
// Note: These correspond to bits [7:3] of the register address field.
|
||||
//
|
||||
parameter SENSOR_MANAGER_ADR = 5'h0;
|
||||
parameter I2C_MASTER_ADR = 5'h1;
|
||||
parameter TIMESTAMP_DELTA_ADR = 5'h2;
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Define the available registers in the Sensor Manager
|
||||
//
|
||||
// Note: These correspond to bits [2:0] of the register address field.
|
||||
//
|
||||
parameter CONTROL_SENSOR_MANAGER_ADDRESS = 3'h0;
|
||||
parameter CONTROL_RECEIVE_ADDRESS = 3'h1;
|
||||
parameter CONTROL_RUNTIME_ADDRESS = 3'h2;
|
||||
parameter CONTROL_WAIT_INSTR_ADDRESS = 3'h4;
|
||||
parameter CONTROL_MAILBOX_TABLE_PTR = 3'h5;
|
||||
parameter CONTROL_MAILBOX_JUMP_INST_PTR = 3'h6;
|
||||
parameter CONTROL_JUMP_ADDRESS = 3'h7;
|
||||
|
||||
|
||||
//
|
||||
// Define the key registers in the I2C Master IP
|
||||
//
|
||||
// Note: These correspond to bits [2:0] of the register address field.
|
||||
//
|
||||
parameter I2C_MASTER_PRELO = 3'h0;
|
||||
parameter I2C_MASTER_PREHI = 3'h1;
|
||||
parameter I2C_MASTER_CTR = 3'h2;
|
||||
parameter I2C_MASTER_TXR = 3'h3;
|
||||
parameter I2C_MASTER_CR = 3'h4;
|
||||
|
||||
|
||||
// Define the available registers in the TimeStamp Logic
|
||||
//
|
||||
// Note: These correspond to bits [2:0] of the register address field.
|
||||
//
|
||||
parameter TIMESTAMP_DELTA_SENSOR_0 = 3'h0;
|
||||
parameter TIMESTAMP_DELTA_SENSOR_1 = 3'h1;
|
||||
parameter TIMESTAMP_DELTA_SENSOR_2 = 3'h2;
|
||||
parameter TIMESTAMP_DELTA_SENSOR_3 = 3'h3;
|
||||
parameter TIMESTAMP_DELTA_GENERIC_LSB = 3'h4;
|
||||
parameter TIMESTAMP_DELTA_GENERIC_MSB = 3'h5;
|
||||
parameter TIMESTAMP_DELTA_INT_EVENT = 3'h6;
|
||||
|
||||
|
||||
//
|
||||
// Define the default location of the Mail Box structure in SM Memory
|
||||
//
|
||||
parameter MAILBOX_SM_ADDRESS = 8'hFF; // Note: This is "3FC" shifted by two to the right
|
||||
|
||||
//------Logic Operations----------
|
||||
//
|
||||
|
||||
// I2C Interface to the Right Bank ASSP
|
||||
//
|
||||
assign I2C_wb_dat_o = MemReadDataIn[15:8];
|
||||
assign i2c_masterDataToMem = I2C_wb_dat_i;
|
||||
assign I2C_wb_we_o = wb_we;
|
||||
assign I2C_wb_stb_o = wb_stb;
|
||||
|
||||
// Decode the Wishbone bus address space(s)
|
||||
//
|
||||
assign I2C_wb_cyc_o = (MemReadDataIn[7:3] == I2C_MASTER_ADR) & wb_cyc & ~CtrlMailBoxJumpInstCycle;
|
||||
|
||||
|
||||
// Define the write enables controls for each register
|
||||
//
|
||||
assign control_sensor_manager_reg_dcd = (MemReadDataIn[7:0] == {SENSOR_MANAGER_ADR, CONTROL_SENSOR_MANAGER_ADDRESS}) & wb_cyc & wb_stb & wb_we & ~wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||
assign control_runtime_reg_dcd = (MemReadDataIn[7:0] == {SENSOR_MANAGER_ADR, CONTROL_RUNTIME_ADDRESS}) & wb_cyc & wb_stb & wb_we & ~wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||
|
||||
assign control_wait_instr_reg_dcd = (MemReadDataIn[7:0] == {SENSOR_MANAGER_ADR, CONTROL_WAIT_INSTR_ADDRESS}) & wb_cyc & wb_stb & wb_we & ~wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||
|
||||
assign control_receive_reg_dcd = ((MemReadDataIn[7:0] == { SENSOR_MANAGER_ADR, CONTROL_RECEIVE_ADDRESS})
|
||||
| (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_SENSOR_0})
|
||||
| (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_SENSOR_1})
|
||||
| (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_SENSOR_2})
|
||||
| (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_SENSOR_3})
|
||||
| (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_GENERIC_MSB})
|
||||
| (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_GENERIC_LSB})) & wb_cyc & wb_stb & wb_we & ~wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||
|
||||
|
||||
|
||||
// Define the write enable for the Interrupt event of the Time Stamp Logic
|
||||
//
|
||||
// Note: This write occurs after the write of interrupt data to SM Memory
|
||||
//
|
||||
assign SensorInterrupt_event_reg_we_dcd = (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_INT_EVENT}) & wb_cyc & wb_stb & ~wb_we & wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||
assign SensorInterrupt_event_mask_we_dcd = (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_INT_EVENT}) & wb_cyc & wb_stb & wb_we & ~wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||
assign TimeStamp_Delta_lsb_reg_we_dcd = (MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_GENERIC_LSB}) & wb_cyc & wb_stb & wb_we & ~wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||
|
||||
|
||||
// Deterimine if the current cycle is a write to the instruction pointer.
|
||||
//
|
||||
// Note: This only happens during the "jump" instruction
|
||||
//
|
||||
// This signals the Sensor Manager Statemachine that the current cycle
|
||||
// is a "jump" and to load the register data value into the instruction
|
||||
// pointer at the end of the current "register write" instruction.
|
||||
//
|
||||
assign control_jump_reg_dcd = (MemReadDataIn[7:0] == {SENSOR_MANAGER_ADR, CONTROL_JUMP_ADDRESS}) & ~CtrlMailBoxJumpInstCycle;
|
||||
|
||||
|
||||
// Determine if the current cycle is the start of a Mail Box based Jump
|
||||
// sequence.
|
||||
//
|
||||
// Note: The value of the bits in the Mail Box region of SM Memory determine
|
||||
// if the current jump address should be loaded into the instruction
|
||||
// pointer or if it should be ignored.
|
||||
//
|
||||
assign control_mailbox_tbl_ptr_dcd = (MemReadDataIn[7:0] == {SENSOR_MANAGER_ADR, CONTROL_MAILBOX_TABLE_PTR}) & wb_cyc & wb_stb & wb_we & ~wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||
assign control_mailbox_jump_inst_ptr_dcd = (MemReadDataIn[7:0] == {SENSOR_MANAGER_ADR, CONTROL_MAILBOX_JUMP_INST_PTR}) & wb_cyc & wb_stb & wb_we & wb_ack_sm & ~CtrlMailBoxJumpInstCycle;
|
||||
|
||||
|
||||
// Determine if the current address should include a write to the Sensor Manager's Memory
|
||||
//
|
||||
// Note: There is currently only one address but this may expand with, for
|
||||
// example, a TimeStamp function.
|
||||
//
|
||||
assign save_reg_2_mem = ((MemReadDataIn[7:0] == { I2C_MASTER_ADR, I2C_MASTER_CR}) & MemReadDataIn[13] & ~CtrlMailBoxJumpInstCycle)
|
||||
| ((MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_SENSOR_0}) & ~CtrlMailBoxJumpInstCycle)
|
||||
| ((MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_SENSOR_1}) & ~CtrlMailBoxJumpInstCycle)
|
||||
| ((MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_SENSOR_2}) & ~CtrlMailBoxJumpInstCycle)
|
||||
| ((MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_SENSOR_3}) & ~CtrlMailBoxJumpInstCycle)
|
||||
| ((MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_GENERIC_LSB}) & ~CtrlMailBoxJumpInstCycle)
|
||||
| ((MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_GENERIC_MSB}) & ~CtrlMailBoxJumpInstCycle)
|
||||
| ((MemReadDataIn[7:0] == {TIMESTAMP_DELTA_ADR, TIMESTAMP_DELTA_INT_EVENT}) & ~CtrlMailBoxJumpInstCycle);
|
||||
|
||||
|
||||
// Determine if the Wishbone device requires monitoring its busy signal
|
||||
//
|
||||
// Note: The only device currently supported is the I2C Master IP. This IP
|
||||
// will generate a I2C bus cycle when the "read" or "write"
|
||||
// bits are set in the control register.
|
||||
//
|
||||
assign wb_busy_poll = ((MemReadDataIn[7:0] == {I2C_MASTER_ADR, I2C_MASTER_CR }) & (MemReadDataIn[12] | MemReadDataIn[13]) & ~CtrlMailBoxJumpInstCycle)
|
||||
| ((MemReadDataIn[7:0] == {SENSOR_MANAGER_ADR, CONTROL_WAIT_INSTR_ADDRESS}) & ~CtrlMailBoxJumpInstCycle);
|
||||
|
||||
|
||||
// Determine when to start the Sensor Manager Statemachine
|
||||
//
|
||||
// Note: Use double-rank synchronization to resolve meta-stability issues.
|
||||
//
|
||||
// Simulation shows these signals toggle from TLC.v clock domain to
|
||||
// the Sensor Manager's.
|
||||
//
|
||||
assign StartIn_stb = (StartFromFFE_5ff ^ StartFromFFE_6ff)
|
||||
| (StartFromTLC_1ff ^ StartFromTLC_2ff);
|
||||
|
||||
|
||||
// Define the Sensor Manager Control Registers
|
||||
//
|
||||
always @(posedge ClockIn or posedge ResetIn)
|
||||
begin
|
||||
if (ResetIn)
|
||||
begin
|
||||
wb_ack_sm <= 1'b0;
|
||||
|
||||
StartFromFFE_1ff <= 1'b0;
|
||||
StartFromFFE_2ff <= 1'b0;
|
||||
StartFromFFE_3ff <= 1'b0;
|
||||
StartFromFFE_4ff <= 1'b0;
|
||||
StartFromFFE_5ff <= 1'b0;
|
||||
StartFromFFE_6ff <= 1'b0;
|
||||
|
||||
StartFromTLC_1ff <= 1'b0;
|
||||
StartFromTLC_2ff <= 1'b0;
|
||||
|
||||
RunSM <= 1'b0;
|
||||
|
||||
CtrlReceiveAddressReg <= 10'h0;
|
||||
CtrlRunTimeAddressReg <= 10'h0;
|
||||
|
||||
CtrlRunTimeAddressSM_1ff <= 1'b0;
|
||||
CtrlRunTimeAddressSM_2ff <= 1'b0;
|
||||
|
||||
TimeStamp_Delta_sensor_0 <= 8'h0;
|
||||
TimeStamp_Delta_sensor_1 <= 8'h0;
|
||||
TimeStamp_Delta_sensor_2 <= 8'h0;
|
||||
TimeStamp_Delta_sensor_3 <= 8'h0;
|
||||
|
||||
SensorInterrupt_0_1ff <= 4'h0;
|
||||
SensorInterrupt_0_2ff <= 4'h0;
|
||||
SensorInterrupt_0_3ff <= 4'h0;
|
||||
|
||||
SensorInterrupt_1_1ff <= 4'h0;
|
||||
SensorInterrupt_1_2ff <= 4'h0;
|
||||
SensorInterrupt_1_3ff <= 4'h0;
|
||||
|
||||
SensorInterrupt_2_1ff <= 4'h0;
|
||||
SensorInterrupt_2_2ff <= 4'h0;
|
||||
SensorInterrupt_2_3ff <= 4'h0;
|
||||
|
||||
SensorInterrupt_3_1ff <= 4'h0;
|
||||
SensorInterrupt_3_2ff <= 4'h0;
|
||||
SensorInterrupt_3_3ff <= 4'h0;
|
||||
|
||||
SensorInterrupt_0_o <= 1'b0;
|
||||
SensorInterrupt_1_o <= 1'b0;
|
||||
SensorInterrupt_2_o <= 1'b0;
|
||||
SensorInterrupt_3_o <= 1'b0;
|
||||
|
||||
SensorInterrupt_event_mask_0 <= 1'b0;
|
||||
SensorInterrupt_event_mask_1 <= 1'b0;
|
||||
SensorInterrupt_event_mask_2 <= 1'b0;
|
||||
SensorInterrupt_event_mask_3 <= 1'b0;
|
||||
|
||||
TimeStamp_Delta_capt <= 16'h0;
|
||||
TimeStamp_Delta_readback <= 16'h0;
|
||||
|
||||
TimeStamp_Delta_Tog_1ff <= 1'b0;
|
||||
TimeStamp_Delta_Tog_2ff <= 1'b0;
|
||||
TimeStamp_Delta_Tog_3ff <= 1'b0;
|
||||
|
||||
CtrlMailBoxSegmentCtr <= 6'h0;
|
||||
CtrlMailBoxSegmentCtr_ce <= 1'b0;
|
||||
|
||||
CtrlMailBoxTablePtr <= MAILBOX_SM_ADDRESS;
|
||||
CtrlMailBoxJumpInstPtr <= 10'h0;
|
||||
|
||||
CtrlMailBoxJumpInstCycle <= 1'b0;
|
||||
CtrlMailBoxJumpInstCycle_ce <= 1'b0;
|
||||
|
||||
control_wait_instr_cntr <= 13'h0;
|
||||
control_wait_instr_cntr_tc <= 1'b0;
|
||||
control_wait_instr_busy <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
wb_ack_sm <= ((MemReadDataIn[7:3] == SENSOR_MANAGER_ADR )
|
||||
| (MemReadDataIn[7:3] == TIMESTAMP_DELTA_ADR)
|
||||
| (CtrlMailBoxJumpInstCycle)) & wb_cyc & wb_stb & ~wb_ack_sm;
|
||||
|
||||
// Double-rank synchronization between clock domains to avoid meta-state issues
|
||||
//
|
||||
|
||||
StartFromFFE_1ff <= StartFromFFE;
|
||||
StartFromFFE_2ff <= StartFromFFE_1ff;
|
||||
StartFromFFE_3ff <= StartFromFFE_2ff;
|
||||
StartFromFFE_4ff <= StartFromFFE_3ff;
|
||||
StartFromFFE_5ff <= StartFromFFE_4ff;
|
||||
StartFromFFE_6ff <= StartFromFFE_5ff;
|
||||
|
||||
StartFromTLC_1ff <= StartFromTLC;
|
||||
StartFromTLC_2ff <= StartFromTLC_1ff;
|
||||
|
||||
CtrlRunTimeAddressSM_1ff <= CtrlRunTimeAddressSM;
|
||||
CtrlRunTimeAddressSM_2ff <= CtrlRunTimeAddressSM_1ff;
|
||||
|
||||
// Define the Sensor Manager Control Register
|
||||
//
|
||||
// Note: A write of "0" to bit "0" of Sensor Manager Register "0" stops execution.
|
||||
//
|
||||
// The remaining bits of the "control" register can be used for other purposes.
|
||||
//
|
||||
if (StartIn_stb)
|
||||
RunSM <= 1'b1;
|
||||
else if (control_sensor_manager_reg_dcd)
|
||||
RunSM <= MemReadDataIn[8];
|
||||
|
||||
// Define the Sensor Manager Receive Address Register
|
||||
//
|
||||
if (control_receive_reg_dcd)
|
||||
CtrlReceiveAddressReg <= MemReadDataIn[17:8];
|
||||
|
||||
// Define the Sensor Manager Run-time Address Register
|
||||
//
|
||||
if (control_runtime_reg_dcd)
|
||||
CtrlRunTimeAddressReg <= MemReadDataIn[17:8];
|
||||
else if ( CtrlRunTimeAddressSM_1ff ^ CtrlRunTimeAddressSM_2ff)
|
||||
CtrlRunTimeAddressReg <= CtrlRunTimeAddressOut;
|
||||
|
||||
|
||||
// Synchronize the interrupt inputs to avoid meta-state issues
|
||||
//
|
||||
SensorInterrupt_0_1ff <= SensorInterrupt_0_i;
|
||||
SensorInterrupt_0_2ff <= SensorInterrupt_0_1ff;
|
||||
SensorInterrupt_0_3ff <= SensorInterrupt_0_2ff;
|
||||
|
||||
SensorInterrupt_1_1ff <= SensorInterrupt_1_i;
|
||||
SensorInterrupt_1_2ff <= SensorInterrupt_1_1ff;
|
||||
SensorInterrupt_1_3ff <= SensorInterrupt_1_2ff;
|
||||
|
||||
SensorInterrupt_2_1ff <= SensorInterrupt_2_i;
|
||||
SensorInterrupt_2_2ff <= SensorInterrupt_2_1ff;
|
||||
SensorInterrupt_2_3ff <= SensorInterrupt_2_2ff;
|
||||
|
||||
SensorInterrupt_3_1ff <= SensorInterrupt_3_i;
|
||||
SensorInterrupt_3_2ff <= SensorInterrupt_3_1ff;
|
||||
SensorInterrupt_3_3ff <= SensorInterrupt_3_2ff;
|
||||
|
||||
TimeStamp_Delta_Tog_1ff <= TimeStamp_Delta_Tog_i;
|
||||
TimeStamp_Delta_Tog_2ff <= TimeStamp_Delta_Tog_1ff;
|
||||
TimeStamp_Delta_Tog_3ff <= TimeStamp_Delta_Tog_2ff;
|
||||
|
||||
|
||||
// Capture the external TimeStamp from the Communication Manager.
|
||||
//
|
||||
// Note: The Communication Manager uses the 32KHz clock for the
|
||||
// TimeStamp function. In the current application, this is not
|
||||
// the same clock used for the Sensor Manager. However, the
|
||||
// Sensor Manager's clock is currently significantly faster than
|
||||
// the 32KHz clock and can capture the TimeStamp value reliably
|
||||
// when is receives the TimeStamp toggle signal from the
|
||||
// Communication Manager.
|
||||
//
|
||||
// This scheme may need to be revisted if the clock assignments
|
||||
// change on future designs.
|
||||
//
|
||||
if (TimeStamp_Delta_Tog_2ff ^ TimeStamp_Delta_Tog_3ff)
|
||||
TimeStamp_Delta_capt <= TimeStamp_Delta_i;
|
||||
|
||||
// Capture the TimeStamp Value for a "generic" TimeStamp write to SM
|
||||
// Memory.
|
||||
//
|
||||
// Note: The entire TimeStamp value is captured when a write of the
|
||||
// LSB value to SM Memory is triggered. This allows for the
|
||||
// writting of the MSB bits without the danger of the TimeStamp
|
||||
// value changing between writes of each TimeStamp byte to
|
||||
// SM Memory.
|
||||
//
|
||||
if (TimeStamp_Delta_lsb_reg_we_dcd)
|
||||
TimeStamp_Delta_readback <= TimeStamp_Delta_capt;
|
||||
|
||||
|
||||
// Capture the time stamp delta when an interrupt is detected.
|
||||
//
|
||||
// Note: See below for the definition of the bit operations.
|
||||
//
|
||||
if (SensorInterrupt_0_2ff && (!SensorInterrupt_0_3ff))
|
||||
TimeStamp_Delta_sensor_0 <= TimeStamp_Delta_capt;
|
||||
|
||||
|
||||
if (SensorInterrupt_1_2ff && (!SensorInterrupt_1_3ff))
|
||||
TimeStamp_Delta_sensor_1 <= TimeStamp_Delta_capt;
|
||||
|
||||
|
||||
if (SensorInterrupt_2_2ff && (!SensorInterrupt_2_3ff))
|
||||
TimeStamp_Delta_sensor_2 <= TimeStamp_Delta_capt;
|
||||
|
||||
|
||||
if (SensorInterrupt_3_2ff && (!SensorInterrupt_3_3ff))
|
||||
TimeStamp_Delta_sensor_3 <= TimeStamp_Delta_capt;
|
||||
|
||||
// Set the Interrupt Status Mask bits
|
||||
//
|
||||
// Note: These bits are used "ANDed" with the write signal to clear
|
||||
// individual status bits.
|
||||
//
|
||||
// The alternate way is to write the interrupt status once
|
||||
// at the end of a series of SM code segments. However, there
|
||||
// may be a significant amount of time between TimeStamp value
|
||||
// capture and a single status being written to memory. This
|
||||
// can allow the interrupt status to change after the TimeStamp
|
||||
// is written to memory. This could result in the assumption
|
||||
// of a good TimeStamp when, in fact, the TimeStamp is not
|
||||
// valid.
|
||||
//
|
||||
if (SensorInterrupt_event_mask_we_dcd)
|
||||
begin
|
||||
SensorInterrupt_event_mask_0 <= MemReadDataIn[8];
|
||||
SensorInterrupt_event_mask_1 <= MemReadDataIn[9];
|
||||
SensorInterrupt_event_mask_2 <= MemReadDataIn[10];
|
||||
SensorInterrupt_event_mask_3 <= MemReadDataIn[11];
|
||||
end
|
||||
|
||||
// Set the interrupt event bit for each sensor when an interrupt is
|
||||
// detected.
|
||||
//
|
||||
// Note: Without this "interrupt event bit" is may not be possible to
|
||||
// know for certain if an interrupt happened. For example,
|
||||
// a value of "0" may be correct given the right
|
||||
// sampling period.
|
||||
//
|
||||
// These status bits assume a positive (i.e. low-to-high)
|
||||
// interrupt assertion.
|
||||
//
|
||||
// All interrupts are cleared when this register is read.
|
||||
//
|
||||
if (SensorInterrupt_event_reg_we_dcd && SensorInterrupt_event_mask_0)
|
||||
SensorInterrupt_0_o <= 1'h0;
|
||||
else if (SensorInterrupt_0_2ff && (!SensorInterrupt_0_3ff))
|
||||
SensorInterrupt_0_o <= 1'h1;
|
||||
|
||||
|
||||
if (SensorInterrupt_event_reg_we_dcd && SensorInterrupt_event_mask_1)
|
||||
SensorInterrupt_1_o <= 1'h0;
|
||||
else if (SensorInterrupt_1_2ff && (!SensorInterrupt_1_3ff))
|
||||
SensorInterrupt_1_o <= 1'h1;
|
||||
|
||||
|
||||
if (SensorInterrupt_event_reg_we_dcd && SensorInterrupt_event_mask_2)
|
||||
SensorInterrupt_2_o <= 1'h0;
|
||||
else if (SensorInterrupt_2_2ff && (!SensorInterrupt_2_3ff))
|
||||
SensorInterrupt_2_o <= 1'h1;
|
||||
|
||||
|
||||
if (SensorInterrupt_event_reg_we_dcd && SensorInterrupt_event_mask_3)
|
||||
SensorInterrupt_3_o <= 1'h0;
|
||||
else if (SensorInterrupt_3_2ff && (!SensorInterrupt_3_3ff))
|
||||
SensorInterrupt_3_o <= 1'h1;
|
||||
|
||||
|
||||
// Mail Box Bit Counter
|
||||
//
|
||||
// Note: Reset Bit Counter between SM Sessions.
|
||||
//
|
||||
// This counter selects the Mail Box bits corresponding to each
|
||||
// SM code segment.
|
||||
//
|
||||
if (!BusySM)
|
||||
CtrlMailBoxSegmentCtr <= 6'h0;
|
||||
else if (CtrlMailBoxSegmentCtr_ce)
|
||||
CtrlMailBoxSegmentCtr <= CtrlMailBoxSegmentCtr + 1'b1;
|
||||
|
||||
CtrlMailBoxSegmentCtr_ce <= wb_cyc & wb_stb & wb_we & ~wb_ack_sm & CtrlMailBoxJumpInstCycle;
|
||||
|
||||
// Mail Box Table Address Pointer
|
||||
//
|
||||
// Note: This is the location in SM Memory where the Mail Box is
|
||||
// located. Typically, the mail box will be in the last four
|
||||
// 18-bit words in SM Memory.
|
||||
//
|
||||
// This value can be dynamically changed by instructions in SM
|
||||
// memory.
|
||||
//
|
||||
if (control_mailbox_tbl_ptr_dcd)
|
||||
CtrlMailBoxTablePtr <= MemReadDataIn[17:10];
|
||||
|
||||
// Mail Box Jump Address
|
||||
//
|
||||
// Note: This address must be temporarily storged while the Mail Box
|
||||
// bits are being read from SM Memory.
|
||||
//
|
||||
// Based on the Mail Box bit for the current code segment, this
|
||||
// jump address may or may not be used for a jump.
|
||||
//
|
||||
if (control_mailbox_jump_inst_ptr_dcd)
|
||||
CtrlMailBoxJumpInstPtr <= MemReadDataIn[17:8];
|
||||
|
||||
// Mail Box Jump Decode Cycle Flag
|
||||
//
|
||||
// Note: This flags that the current SM write cycle is a Mail Box Jump
|
||||
// decode operation.
|
||||
//
|
||||
// The data from SM Memory consist of Mail Box bits and should
|
||||
// not be decoded as a SM "write" instruction would.
|
||||
//
|
||||
// The decode consists of selecting the correct bit from the
|
||||
// Mail Box for the current SM code segment. Based on the state
|
||||
// of this bit (i.e. 0 - No Jump; 1 - Jump), the SM instruction
|
||||
// pointer will either proceed with the next instruction address
|
||||
// or jump to a new code segment.
|
||||
//
|
||||
if (control_mailbox_jump_inst_ptr_dcd)
|
||||
CtrlMailBoxJumpInstCycle <= 1'b1;
|
||||
else if (CtrlMailBoxJumpInstCycle_ce)
|
||||
CtrlMailBoxJumpInstCycle <= 1'b0;
|
||||
|
||||
CtrlMailBoxJumpInstCycle_ce <= wb_cyc & wb_stb & wb_we & wb_ack_sm & ~control_mailbox_jump_inst_ptr_dcd;
|
||||
|
||||
|
||||
// Wait Instruction Register
|
||||
//
|
||||
if (control_wait_instr_reg_dcd || control_wait_instr_busy)
|
||||
begin
|
||||
control_wait_instr_cntr <= control_wait_instr_cntr_nxt;
|
||||
control_wait_instr_cntr_tc <= control_wait_instr_cntr_tc_nxt;
|
||||
end
|
||||
|
||||
control_wait_instr_busy <= control_wait_instr_busy_nxt;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Define the Wait Instruction Busy signal
|
||||
//
|
||||
// Note: This busy starts with the first write and ends when the counter is done.
|
||||
//
|
||||
// This is an N-1 counter. Therefore, a value of "0" means an "N" of "1".
|
||||
// Therefore, there should be one cycle of busy even with a value of "0".
|
||||
//
|
||||
assign control_wait_instr_busy_nxt = (~control_wait_instr_busy & control_wait_instr_reg_dcd)
|
||||
| ( control_wait_instr_busy & ~control_wait_instr_cntr_tc);
|
||||
|
||||
|
||||
// Define the operation of the Wait Instruction Counter
|
||||
//
|
||||
always @(MemReadDataIn or
|
||||
control_wait_instr_busy or
|
||||
control_wait_instr_cntr
|
||||
)
|
||||
begin
|
||||
|
||||
case({control_wait_instr_busy, MemReadDataIn[17]})
|
||||
2'b00: // MSB == 0 then count 1-to-1
|
||||
begin
|
||||
control_wait_instr_cntr_nxt <= {4'h0, MemReadDataIn[16:8] };
|
||||
control_wait_instr_cntr_tc_nxt <= ( MemReadDataIn[16:8] == 9'h0);
|
||||
end
|
||||
2'b01: // MSB == 1 then count 16-to-1
|
||||
begin
|
||||
control_wait_instr_cntr_nxt <= { MemReadDataIn[16:8], 4'hF}; // Remember: N-1 means that "0" should be one wait period
|
||||
control_wait_instr_cntr_tc_nxt <= 1'b0;
|
||||
end
|
||||
2'b10: // Normal Count
|
||||
begin
|
||||
control_wait_instr_cntr_nxt <= control_wait_instr_cntr - 13'h1;
|
||||
control_wait_instr_cntr_tc_nxt <= (control_wait_instr_cntr == 13'h1);
|
||||
end
|
||||
2'b11: // Normal Count - The value was shift << 4 so it is already 16x larger at loading time
|
||||
begin
|
||||
control_wait_instr_cntr_nxt <= control_wait_instr_cntr - 13'h1;
|
||||
control_wait_instr_cntr_tc_nxt <= (control_wait_instr_cntr == 13'h1);
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// Use the "run" bit to signal when the statemachine is "busy" in addition to
|
||||
// the statemachine busy bit.
|
||||
//
|
||||
assign BusyOut = RunSM | BusySM;
|
||||
|
||||
|
||||
// Define the Sensor Manager Memory's read address
|
||||
//
|
||||
// Note: StateMachine is allowed to read all of SensorManager Memory
|
||||
//
|
||||
// The Sensor Manager Memory's "read" port is 10-bits (i.e. [9:0])
|
||||
//
|
||||
// Select the Mail Box Address pointer during Mail Box Jump operations.
|
||||
// The location pointed to contains Mail Box Jump enable bits AND NOT
|
||||
// SM instructions.
|
||||
//
|
||||
assign MemReadAddressOut = CtrlMailBoxJumpInstCycle ? {CtrlMailBoxTablePtr, CtrlMailBoxSegmentCtr[5:4]}
|
||||
: StateMachineCtrlMemAddr ;
|
||||
|
||||
|
||||
// Limit the register write function to the upper half of the Sensor Manager's Memory space
|
||||
//
|
||||
// Note: The Sensor Manager Memory's "write" port address is 10-bits (i.e. [9:0])
|
||||
//
|
||||
assign MemWriteAddressOut = CtrlReceiveAddressReg;
|
||||
|
||||
|
||||
// Define the Data to be written to Sensor Memory
|
||||
//
|
||||
// Note: The I2C Master IP only outputs byte wide values
|
||||
//
|
||||
// For the current design, the following are read back:
|
||||
// - I2C Master IP is read back
|
||||
// - TimeStamp registers for four sensors
|
||||
// - TimeSTamp related interrupt event register
|
||||
//
|
||||
// Only the I2C Master IP was supported in previous designs
|
||||
//
|
||||
always @(MemReadDataIn or
|
||||
MemWriteDataOut or
|
||||
i2c_masterDataToMem or
|
||||
TimeStamp_Delta_sensor_0 or
|
||||
TimeStamp_Delta_sensor_1 or
|
||||
TimeStamp_Delta_sensor_2 or
|
||||
TimeStamp_Delta_sensor_3 or
|
||||
TimeStamp_Delta_readback or
|
||||
SensorInterrupt_0_o or
|
||||
SensorInterrupt_1_o or
|
||||
SensorInterrupt_2_o or
|
||||
SensorInterrupt_3_o
|
||||
)
|
||||
begin
|
||||
case(MemReadDataIn[7:3])
|
||||
I2C_MASTER_ADR: MemWriteDataOut <= {1'b0, i2c_masterDataToMem};
|
||||
TIMESTAMP_DELTA_ADR:
|
||||
begin
|
||||
case(MemReadDataIn[2:0])
|
||||
TIMESTAMP_DELTA_SENSOR_0 : MemWriteDataOut <= {1'b0, TimeStamp_Delta_sensor_0};
|
||||
TIMESTAMP_DELTA_SENSOR_1 : MemWriteDataOut <= {1'b0, TimeStamp_Delta_sensor_1};
|
||||
TIMESTAMP_DELTA_SENSOR_2 : MemWriteDataOut <= {1'b0, TimeStamp_Delta_sensor_2};
|
||||
TIMESTAMP_DELTA_SENSOR_3 : MemWriteDataOut <= {1'b0, TimeStamp_Delta_sensor_3};
|
||||
TIMESTAMP_DELTA_GENERIC_LSB : MemWriteDataOut <= {1'b0, TimeStamp_Delta_readback[7:0]};
|
||||
TIMESTAMP_DELTA_GENERIC_MSB : MemWriteDataOut <= {1'b0, TimeStamp_Delta_readback[15:8]};
|
||||
TIMESTAMP_DELTA_INT_EVENT : MemWriteDataOut <= {4'h0, SensorInterrupt_3_o,
|
||||
SensorInterrupt_2_o,
|
||||
SensorInterrupt_1_o,
|
||||
SensorInterrupt_0_o};
|
||||
default: MemWriteDataOut <= {1'b0, i2c_masterDataToMem};
|
||||
endcase
|
||||
end
|
||||
default: MemWriteDataOut <= {1'b0, i2c_masterDataToMem};
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// Define the Sensor Manager Memory's clock
|
||||
//
|
||||
// Note: This is currently a flow through but this may change in future designs.
|
||||
//
|
||||
assign MemClockOut = ClockIn;
|
||||
|
||||
|
||||
// Combine all Wishbone bus acknowledges
|
||||
//
|
||||
// Note: Only one acknowledge should happen at a time.
|
||||
//
|
||||
assign wb_ack = wb_ack_sm | I2C_wb_ack_i;
|
||||
|
||||
|
||||
// Multiplex the address to the I2C Master IP when performing an I2C read
|
||||
//
|
||||
// Note: The address must be switched from the I2C "Control" Register to the I2C "Transmit/Receive" data address.
|
||||
//
|
||||
// This only affects the I2C Master IP and does not affect any other device on the Wishbone bus.
|
||||
//
|
||||
assign I2C_wb_adr_o = ((MemReadDataIn[7:0] == {I2C_MASTER_ADR, I2C_MASTER_CR}) & MemReadDataIn[13] & (~wb_we))
|
||||
? I2C_MASTER_TXR : MemReadDataIn[2:0];
|
||||
|
||||
|
||||
//------Instantiate Modules----------------
|
||||
//
|
||||
|
||||
// Instantiate the Sensor Manager Statemachine
|
||||
//
|
||||
StateMachine StateMachine_inst (
|
||||
|
||||
.CLK_IN ( ClockIn ),
|
||||
.RESET_IN ( ResetIn ),
|
||||
|
||||
.RUNTIME_ADDRESS ( CtrlRunTimeAddressReg ),
|
||||
.CONTROL_JUMP_REG_DCD ( control_jump_reg_dcd ),
|
||||
.SAVE_REG_2_MEM ( save_reg_2_mem ),
|
||||
|
||||
.MAILBOX_JUMP_INST_CYCLE (CtrlMailBoxJumpInstCycle ),
|
||||
.MAILBOX_JUMP_INST_PTR (CtrlMailBoxJumpInstPtr ),
|
||||
.MAILBOX_SEGMENT_CTR (CtrlMailBoxSegmentCtr[3:0] ),
|
||||
|
||||
.WB_ACK_I ( wb_ack ),
|
||||
.WB_BUSY_I ( I2C_tip_i | control_wait_instr_busy ),
|
||||
.WB_BUSY_POLL_I ( wb_busy_poll ),
|
||||
|
||||
.WB_WE_O ( wb_we ),
|
||||
.WB_STB_O ( wb_stb ),
|
||||
.WB_CYC_O ( wb_cyc ),
|
||||
|
||||
.SM_CNTL_REG_RUN ( RunSM ),
|
||||
.SM_READ_DATA ( MemReadDataIn ), // Data "Byte" is MemReadDataIn[17:8]
|
||||
|
||||
.SM_INSTR_PTR ( StateMachineCtrlMemAddr ),
|
||||
.SM_READ_SELECT ( MemReadEnableOut ),
|
||||
|
||||
.SM_WRITE_SELECT ( MemWriteEnableOut ),
|
||||
.SM_BUSY ( BusySM )
|
||||
|
||||
);
|
||||
|
||||
|
||||
// test points
|
||||
//
|
||||
assign TP1 = I2C_tip_i;
|
||||
assign TP2 = BusyOut;
|
||||
assign TP3 = 0;
|
||||
|
||||
// Logic to generate SmClockSelect_o
|
||||
wire d_SmClockSelect;
|
||||
|
||||
always @(posedge ClockIn or posedge ResetIn)
|
||||
begin
|
||||
if (ResetIn)
|
||||
begin
|
||||
s1_BusyOut <= 1'b0;
|
||||
s2_BusyOut <= 1'b0;
|
||||
SmClockSelect_o <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
s1_BusyOut <= BusyOut;
|
||||
s2_BusyOut <= s1_BusyOut;
|
||||
SmClockSelect_o <= d_SmClockSelect;
|
||||
end
|
||||
end
|
||||
|
||||
assign d_SmClockSelect = SmClockSelect_o ? ((!s1_BusyOut && s2_BusyOut) ? 1'b0 : 1'b1) : ((StartFromFFE_1ff ^ StartFromFFE_2ff) ? 1'b1: 1'b0);
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,608 @@
|
|||
// -----------------------------------------------------------------------------
|
||||
// title : Sensor Manager Statemachine
|
||||
// project : ULP Sensor Hub
|
||||
// -----------------------------------------------------------------------------
|
||||
// file : StateMachine.v
|
||||
// author : Glen Gomes
|
||||
// company : QuickLogic Corp
|
||||
// created : 2013/12/06
|
||||
// last update : 2013/12/06
|
||||
// platform : PolarPro III
|
||||
// standard : Verilog 2001
|
||||
// -----------------------------------------------------------------------------
|
||||
// description: The Sensor Manger Statemachine is responsible for controlling the
|
||||
// operations of the Sensor Manager. These include performing
|
||||
// transfers between Sensor Memory and various registers.
|
||||
// -----------------------------------------------------------------------------
|
||||
// copyright (c) 2013
|
||||
// -----------------------------------------------------------------------------
|
||||
// revisions :
|
||||
// date version author description
|
||||
// 2013/12/06 1.0 Glen Gomes created
|
||||
// 2014/05/27 1.1 Glen Gomes Updated for Tay
|
||||
// -----------------------------------------------------------------------------
|
||||
// Comments: This solution is specifically for use with the QuickLogic
|
||||
// PolarPro III device.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
`timescale 1ns/10ps
|
||||
|
||||
module StateMachine (
|
||||
|
||||
CLK_IN,
|
||||
RESET_IN,
|
||||
|
||||
RUNTIME_ADDRESS,
|
||||
CONTROL_JUMP_REG_DCD,
|
||||
SAVE_REG_2_MEM,
|
||||
|
||||
MAILBOX_JUMP_INST_CYCLE,
|
||||
MAILBOX_JUMP_INST_PTR,
|
||||
MAILBOX_SEGMENT_CTR,
|
||||
|
||||
WB_ACK_I,
|
||||
WB_BUSY_I,
|
||||
WB_BUSY_POLL_I,
|
||||
|
||||
WB_WE_O,
|
||||
WB_STB_O,
|
||||
WB_CYC_O,
|
||||
|
||||
SM_CNTL_REG_RUN,
|
||||
SM_READ_DATA,
|
||||
|
||||
SM_INSTR_PTR,
|
||||
SM_READ_SELECT,
|
||||
|
||||
SM_WRITE_SELECT,
|
||||
|
||||
SM_BUSY
|
||||
|
||||
);
|
||||
|
||||
|
||||
//-----Port Signals--------------------
|
||||
//
|
||||
|
||||
input CLK_IN;
|
||||
input RESET_IN;
|
||||
|
||||
input [9:0] RUNTIME_ADDRESS;
|
||||
input CONTROL_JUMP_REG_DCD;
|
||||
input SAVE_REG_2_MEM;
|
||||
|
||||
input MAILBOX_JUMP_INST_CYCLE;
|
||||
input [9:0] MAILBOX_JUMP_INST_PTR;
|
||||
input [3:0] MAILBOX_SEGMENT_CTR;
|
||||
|
||||
input WB_ACK_I;
|
||||
input WB_BUSY_I;
|
||||
input WB_BUSY_POLL_I;
|
||||
|
||||
output WB_WE_O;
|
||||
output WB_STB_O;
|
||||
output WB_CYC_O;
|
||||
|
||||
input SM_CNTL_REG_RUN;
|
||||
input [17:0] SM_READ_DATA;
|
||||
|
||||
output [9:0] SM_INSTR_PTR;
|
||||
output SM_READ_SELECT;
|
||||
|
||||
output SM_WRITE_SELECT;
|
||||
|
||||
output SM_BUSY;
|
||||
|
||||
|
||||
wire CLK_IN;
|
||||
wire RESET_IN;
|
||||
|
||||
wire [9:0] RUNTIME_ADDRESS;
|
||||
wire CONTROL_JUMP_REG_DCD;
|
||||
wire SAVE_REG_2_MEM;
|
||||
|
||||
wire MAILBOX_JUMP_INST_CYCLE;
|
||||
wire [9:0] MAILBOX_JUMP_INST_PTR;
|
||||
wire [3:0] MAILBOX_SEGMENT_CTR;
|
||||
|
||||
wire WB_ACK_I;
|
||||
wire WB_BUSY_I;
|
||||
wire WB_BUSY_POLL_I;
|
||||
|
||||
reg WB_WE_O;
|
||||
reg wb_we_o_nxt;
|
||||
|
||||
reg WB_STB_O;
|
||||
reg wb_stb_o_nxt;
|
||||
|
||||
reg WB_CYC_O;
|
||||
reg wb_cyc_o_nxt;
|
||||
|
||||
wire SM_CNTL_REG_RUN;
|
||||
wire [17:0] SM_READ_DATA;
|
||||
|
||||
reg [9:0] SM_INSTR_PTR;
|
||||
reg [9:0] sm_instr_ptr_nxt;
|
||||
|
||||
reg SM_READ_SELECT;
|
||||
reg sm_read_select_nxt;
|
||||
|
||||
reg SM_WRITE_SELECT;
|
||||
reg sm_write_select_nxt;
|
||||
|
||||
reg SM_BUSY;
|
||||
reg sm_busy_nxt;
|
||||
|
||||
//-----Internal Signals--------------------
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// Define the Statemachine registers
|
||||
//
|
||||
reg [3:0] sensor_manager_sm;
|
||||
reg [3:0] sensor_manager_sm_nxt;
|
||||
|
||||
|
||||
//
|
||||
// Define the Instruction Pointer variables
|
||||
//
|
||||
|
||||
reg sm_instr_ptr_ce;
|
||||
reg sm_instr_ptr_ce_nxt;
|
||||
|
||||
reg sm_instr_ptr_ld;
|
||||
reg sm_instr_ptr_ld_nxt;
|
||||
|
||||
//reg sm_instr_ptr_sel;
|
||||
//reg sm_instr_ptr_sel_nxt;
|
||||
|
||||
reg mailbox_jump_inst_ptr_ld;
|
||||
|
||||
|
||||
//------Define Parameters---------
|
||||
//
|
||||
|
||||
//
|
||||
// Define the Sensor Manager Statemachine States
|
||||
//
|
||||
// Note: These states are chosen to allow for overlap of various signals
|
||||
// during operation. This overlap should help reduce timing
|
||||
// dependancies.
|
||||
//
|
||||
parameter SM_IDLE = 4'h0;
|
||||
parameter SM_INC_PTR = 4'h1;
|
||||
parameter SM_INST_RD = 4'h2;
|
||||
//parameter SM_INST_DCD = 4'h3; // Note: Will be used for TimeStamp Support in a future design
|
||||
parameter SM_REG_WR = 4'h4;
|
||||
parameter SM_REG_RD = 4'h5;
|
||||
parameter SM_WAIT_BUSY_ON = 4'h6;
|
||||
parameter SM_WAIT_BUSY_OFF = 4'h7;
|
||||
|
||||
|
||||
//
|
||||
// Sensor Manager Initialization Start Address
|
||||
//
|
||||
// Note: The previous IP used the reset of the "RuntimeAddress" register to
|
||||
// select the sensor initialization code. This value explicity selects
|
||||
// the value for the start (or re-start) of initialization.
|
||||
//
|
||||
parameter SM_INIT_INSTR_ADR = 10'h0; // Address for the start in initialization instructions
|
||||
|
||||
|
||||
//------Logic Operations----------
|
||||
//
|
||||
|
||||
//
|
||||
// Define the Instruction Pointer
|
||||
//
|
||||
// Note: This pointer can start at either the sensor initialization code start
|
||||
// address or the run-time code start address.
|
||||
//
|
||||
always @( SM_INSTR_PTR or
|
||||
sm_instr_ptr_ld or
|
||||
sm_instr_ptr_ce or
|
||||
SM_READ_DATA or
|
||||
CONTROL_JUMP_REG_DCD or
|
||||
RUNTIME_ADDRESS or
|
||||
MAILBOX_JUMP_INST_CYCLE or
|
||||
MAILBOX_JUMP_INST_PTR
|
||||
)
|
||||
begin
|
||||
case({sm_instr_ptr_ld, sm_instr_ptr_ce})
|
||||
2'b00: sm_instr_ptr_nxt <= SM_INSTR_PTR; // Hold Current Value
|
||||
2'b01: sm_instr_ptr_nxt <= SM_INSTR_PTR + 1'b1; // Increment to the next address
|
||||
2'b10:
|
||||
begin
|
||||
case({MAILBOX_JUMP_INST_CYCLE, CONTROL_JUMP_REG_DCD})
|
||||
2'b00: sm_instr_ptr_nxt <= RUNTIME_ADDRESS; // Run-time Code Address
|
||||
2'b01: sm_instr_ptr_nxt <= SM_READ_DATA[17:8]; // Jump Address
|
||||
default: sm_instr_ptr_nxt <= MAILBOX_JUMP_INST_PTR; // Mail Box Jump Address
|
||||
endcase
|
||||
end
|
||||
2'b11: sm_instr_ptr_nxt <= SM_INSTR_PTR; // Hold Current Value
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// Select the Mail Box Jump Enable Bit
|
||||
//
|
||||
// Note: Mail Box Jump enable bits are spread over 16-bits of the 18-bits from
|
||||
// SM Memory.
|
||||
//
|
||||
always @( MAILBOX_SEGMENT_CTR or
|
||||
SM_READ_DATA or
|
||||
mailbox_jump_inst_ptr_ld
|
||||
)
|
||||
begin
|
||||
case(MAILBOX_SEGMENT_CTR)
|
||||
4'h0: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[0];
|
||||
4'h1: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[1];
|
||||
4'h2: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[2];
|
||||
4'h3: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[3];
|
||||
4'h4: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[4];
|
||||
4'h5: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[5];
|
||||
4'h6: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[6];
|
||||
4'h7: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[7];
|
||||
4'h8: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[9];
|
||||
4'h9: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[10];
|
||||
4'hA: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[11];
|
||||
4'hB: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[12];
|
||||
4'hC: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[13];
|
||||
4'hD: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[14];
|
||||
4'hE: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[15];
|
||||
4'hF: mailbox_jump_inst_ptr_ld <= SM_READ_DATA[16];
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// Define the registers associated with the Sensor Manager Statemachine
|
||||
//
|
||||
always @(posedge CLK_IN or posedge RESET_IN)
|
||||
begin
|
||||
if (RESET_IN)
|
||||
begin
|
||||
sensor_manager_sm <= SM_IDLE;
|
||||
|
||||
SM_INSTR_PTR <= 10'h0;
|
||||
sm_instr_ptr_ce <= 1'b0;
|
||||
sm_instr_ptr_ld <= 1'b0;
|
||||
|
||||
WB_WE_O <= 1'b0;
|
||||
WB_STB_O <= 1'b0;
|
||||
WB_CYC_O <= 1'b0;
|
||||
|
||||
SM_READ_SELECT <= 1'b0;
|
||||
SM_WRITE_SELECT <= 1'b0;
|
||||
|
||||
SM_BUSY <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
sensor_manager_sm <= sensor_manager_sm_nxt;
|
||||
|
||||
SM_INSTR_PTR <= sm_instr_ptr_nxt;
|
||||
sm_instr_ptr_ce <= sm_instr_ptr_ce_nxt;
|
||||
sm_instr_ptr_ld <= sm_instr_ptr_ld_nxt;
|
||||
|
||||
WB_WE_O <= wb_we_o_nxt;
|
||||
WB_STB_O <= wb_stb_o_nxt;
|
||||
WB_CYC_O <= wb_cyc_o_nxt;
|
||||
|
||||
SM_READ_SELECT <= sm_read_select_nxt;
|
||||
SM_WRITE_SELECT <= sm_write_select_nxt;
|
||||
|
||||
SM_BUSY <= sm_busy_nxt;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Define the Sensor Manager Statemachine
|
||||
//
|
||||
always @( sensor_manager_sm or
|
||||
SM_CNTL_REG_RUN or
|
||||
CONTROL_JUMP_REG_DCD or
|
||||
SAVE_REG_2_MEM or
|
||||
WB_BUSY_I or
|
||||
WB_BUSY_POLL_I or
|
||||
WB_ACK_I or
|
||||
MAILBOX_JUMP_INST_CYCLE or
|
||||
mailbox_jump_inst_ptr_ld
|
||||
)
|
||||
begin
|
||||
case(sensor_manager_sm)
|
||||
SM_IDLE:
|
||||
begin
|
||||
|
||||
case(SM_CNTL_REG_RUN)
|
||||
1'b0: // No Activity
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_IDLE;
|
||||
|
||||
sm_busy_nxt <= 1'b0;
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
end
|
||||
1'b1: // Start at the Sensor Run-Time Code
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||
|
||||
sm_busy_nxt <= 1'b1;
|
||||
sm_instr_ptr_ld_nxt <= 1'b1;
|
||||
end
|
||||
endcase
|
||||
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_read_select_nxt <= 1'b0;
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
SM_INC_PTR:
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_INST_RD;
|
||||
|
||||
sm_busy_nxt <= 1'b1;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_read_select_nxt <= 1'b1;
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
SM_INST_RD:
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_REG_WR;
|
||||
|
||||
sm_busy_nxt <= 1'b1;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_read_select_nxt <= 1'b0;
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b1;
|
||||
wb_stb_o_nxt <= 1'b1;
|
||||
wb_cyc_o_nxt <= 1'b1;
|
||||
end
|
||||
SM_REG_WR:
|
||||
begin
|
||||
|
||||
sm_read_select_nxt <= 1'b0;
|
||||
|
||||
case(SM_CNTL_REG_RUN)
|
||||
1'b0: // A write of "0" to bit "0" of the Command register at address "0" turns off
|
||||
// the Sensor Manager's Statemachine
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_IDLE;
|
||||
|
||||
sm_busy_nxt <= 1'b0;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
1'b1: // Sensor Manager Statemachine is not stopped; continue processing
|
||||
begin
|
||||
sm_busy_nxt <= 1'b1;
|
||||
|
||||
case({WB_BUSY_POLL_I, WB_ACK_I})
|
||||
2'b00: // Wait for Wish Bone Acknowledge and no need to wait for transfer complete
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_REG_WR;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b1;
|
||||
wb_stb_o_nxt <= 1'b1;
|
||||
wb_cyc_o_nxt <= 1'b1;
|
||||
end
|
||||
2'b01: // Wish Bone Acknowledge Received and no need to wait for transfer complete
|
||||
begin
|
||||
case(SAVE_REG_2_MEM)
|
||||
1'b0:
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= CONTROL_JUMP_REG_DCD
|
||||
| (MAILBOX_JUMP_INST_CYCLE & mailbox_jump_inst_ptr_ld);
|
||||
|
||||
sm_instr_ptr_ce_nxt <= ~ CONTROL_JUMP_REG_DCD
|
||||
& ~ MAILBOX_JUMP_INST_CYCLE;
|
||||
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
1'b1:
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_REG_RD;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_write_select_nxt <= 1'b1;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
wb_stb_o_nxt <= 1'b1;
|
||||
wb_cyc_o_nxt <= 1'b1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
2'b10: // Wait for Wish Bone Acknowledge and will need to wait for transfer complete
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_REG_WR;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b1;
|
||||
wb_stb_o_nxt <= 1'b1;
|
||||
wb_cyc_o_nxt <= 1'b1;
|
||||
end
|
||||
2'b11: // Acknowledge received but need to wait for transfer complete
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_WAIT_BUSY_ON;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
endcase
|
||||
end
|
||||
SM_REG_RD:
|
||||
begin
|
||||
sm_busy_nxt <= 1'b1;
|
||||
|
||||
sm_read_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
|
||||
case(WB_ACK_I)
|
||||
1'b0: // Waiting for Wish Bone Acknowledge
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_REG_RD;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_write_select_nxt <= 1'b1;
|
||||
|
||||
wb_stb_o_nxt <= 1'b1;
|
||||
wb_cyc_o_nxt <= 1'b1;
|
||||
end
|
||||
1'b1: // Got Wish Bone Acknowledge
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= CONTROL_JUMP_REG_DCD;
|
||||
sm_instr_ptr_ce_nxt <= ~CONTROL_JUMP_REG_DCD;
|
||||
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
SM_WAIT_BUSY_ON:
|
||||
begin
|
||||
sm_busy_nxt <= 1'b1;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_read_select_nxt <= 1'b0;
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
|
||||
case(WB_BUSY_I)
|
||||
1'b0: sensor_manager_sm_nxt <= SM_WAIT_BUSY_ON; // Wait for Busy from I/F
|
||||
1'b1: sensor_manager_sm_nxt <= SM_WAIT_BUSY_OFF; // Got Busy from I/F
|
||||
endcase
|
||||
end
|
||||
SM_WAIT_BUSY_OFF:
|
||||
begin
|
||||
sm_busy_nxt <= 1'b1;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
|
||||
sm_read_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
|
||||
case({SAVE_REG_2_MEM, WB_BUSY_I})
|
||||
2'b00: // Wishbone transfer complete; no need to write anything to Sensor Manager Memory
|
||||
//
|
||||
// Note: Writes to the command register do not enter this state.
|
||||
// Therefore, there is no need to check for the end of processing.
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||
|
||||
sm_instr_ptr_ce_nxt <= 1'b1;
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
2'b01: // Wait for Wishbone transfer to complete
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_WAIT_BUSY_OFF;
|
||||
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
2'b10: // Wishbone transfer complete; Write resulting register value to Sensor Manager Memory
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_REG_RD;
|
||||
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
sm_write_select_nxt <= 1'b1;
|
||||
|
||||
wb_stb_o_nxt <= 1'b1;
|
||||
wb_cyc_o_nxt <= 1'b1;
|
||||
end
|
||||
2'b11: // Wait for Wishbone transfer to complete
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_WAIT_BUSY_OFF;
|
||||
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
default:
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_IDLE;
|
||||
|
||||
sm_busy_nxt <= 1'b0;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_read_select_nxt <= 1'b0;
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,128 @@
|
|||
|
||||
`timescale 1ns / 10ps
|
||||
|
||||
module SystemClockControl (
|
||||
OperatingClockRef_i,
|
||||
Clock32KIn_i,
|
||||
SPIClock_i,
|
||||
ResetIn_i,
|
||||
|
||||
FfeClkSelect_i,
|
||||
SmClkSelect_i,
|
||||
SmSpeedSelect_i,
|
||||
SpiClkSelect_i,
|
||||
ClkSourceSelect_i,
|
||||
Clk32KhzEnable_i,
|
||||
MainClkEnable_i,
|
||||
FfeClkEnable_i,
|
||||
CM_AutoDrain_Busy,
|
||||
|
||||
SmClock_o,
|
||||
FfeClock_o,
|
||||
FfeClock_x2_o,
|
||||
clock_32KHz_o,
|
||||
multiplierClk_o,
|
||||
ClockGen_State_o,
|
||||
CM_FIFO_ReadClk,
|
||||
|
||||
clk_ringosc_i,
|
||||
clk_ringosc_x2_i,
|
||||
enable_i,
|
||||
clk_cal_value_o,
|
||||
assp_ringosc_en_o
|
||||
);
|
||||
|
||||
// IO Declaration
|
||||
input OperatingClockRef_i;
|
||||
input Clock32KIn_i;
|
||||
input SPIClock_i;
|
||||
input ResetIn_i;
|
||||
|
||||
input [2:0] FfeClkSelect_i;
|
||||
input [2:0] SmClkSelect_i;
|
||||
input SmSpeedSelect_i;
|
||||
input SpiClkSelect_i;
|
||||
input ClkSourceSelect_i;
|
||||
input Clk32KhzEnable_i;
|
||||
input MainClkEnable_i;
|
||||
input FfeClkEnable_i;
|
||||
input CM_AutoDrain_Busy;
|
||||
|
||||
output SmClock_o;
|
||||
output FfeClock_o;
|
||||
output FfeClock_x2_o;
|
||||
output clock_32KHz_o;
|
||||
output multiplierClk_o;
|
||||
output [3:0] ClockGen_State_o;
|
||||
output CM_FIFO_ReadClk;
|
||||
|
||||
input clk_ringosc_i;
|
||||
input clk_ringosc_x2_i;
|
||||
input enable_i;
|
||||
output [15:0] clk_cal_value_o;
|
||||
output assp_ringosc_en_o;
|
||||
|
||||
reg multiplierClk_o;
|
||||
wire [3:0] ClockGen_State_o;
|
||||
wire CM_FIFO_ReadClk;
|
||||
wire assp_ringosc_en_o;
|
||||
|
||||
|
||||
|
||||
// Internal Signals Declaration
|
||||
wire highSpeedClock, highSpeedClock_buff, highSpeedClock_x2_buff;
|
||||
reg [6:0] ClockDiv;
|
||||
wire FfeClock;
|
||||
reg SmClock;
|
||||
wire RingOscEnable;
|
||||
wire ring_osc_clk;
|
||||
wire OperatingClockRef;
|
||||
|
||||
|
||||
// Operations
|
||||
|
||||
// Gating the enternal osc
|
||||
// assign OperatingClockRef = OperatingClockRef_i && MainClkEnable_i;
|
||||
assign OperatingClockRef = OperatingClockRef_i;
|
||||
|
||||
// CM FIFO AutoDrain Read Clock
|
||||
// assign CM_FIFO_ReadClk = CM_AutoDrain_Busy ? (FfeClock && FfeClkEnable_i): SPIClock_i;
|
||||
assign CM_FIFO_ReadClk = CM_AutoDrain_Busy ? highSpeedClock_buff : SPIClock_i;
|
||||
|
||||
// Ring Osclilator enable when the when weither FFE or SM is busy
|
||||
// assign RingOscEnable = !ResetIn_i && MainClkEnable_i && ClkSourceSelect_i;
|
||||
|
||||
// Logic to gate 32KHz clock when the ULPSH goes to sleep
|
||||
// Only static power consumption
|
||||
assign clock_32KHz_o = Clock32KIn_i && Clk32KhzEnable_i;
|
||||
|
||||
// Logic to select between the external high speed clock and the internal ring oscillation
|
||||
// and main clock division
|
||||
// assign highSpeedClock = ClkSourceSelect_i ? ring_osc_clk : OperatingClockRef;
|
||||
buff buff_highSpeedClock (.A(clk_ringosc_i), .Q(highSpeedClock_buff)); // don't use a clock network for this
|
||||
//pragma attribute buff_highSpeedClock dont_touch true
|
||||
|
||||
buff buff_highSpeedClock_x2 (.A(clk_ringosc_x2_i), .Q(highSpeedClock_x2_buff)); // don't use a clock network for this
|
||||
//pragma attribute buff_highSpeedClock_x2 dont_touch true
|
||||
|
||||
|
||||
|
||||
// FFE CLK and SM CLK select and masking
|
||||
// assign FfeClock_o = SpiClkSelect_i ? SPIClock_i : FfeClock && FfeClkEnable_i;
|
||||
// assign SmClock_o = SmSpeedSelect_i ? SmClock : (SpiClkSelect_i ? SPIClock_i : FfeClock);
|
||||
assign FfeClock_o = SpiClkSelect_i ? SPIClock_i : highSpeedClock_buff;
|
||||
assign FfeClock_x2_o = SpiClkSelect_i ? SPIClock_i : highSpeedClock_x2_buff;
|
||||
assign SmClock_o = SpiClkSelect_i ? SPIClock_i : highSpeedClock_buff;
|
||||
|
||||
|
||||
ring_osc_adjust ring_osc_adjust_1 (
|
||||
.reset_i ( ResetIn_i ),
|
||||
.clk_ringosc_i ( clk_ringosc_i ),
|
||||
.clk_32khz_i ( Clock32KIn_i ),
|
||||
.enable_i ( enable_i ),
|
||||
.cal_val_o ( clk_cal_value_o )
|
||||
);
|
||||
|
||||
assign assp_ringosc_en_o = ClkSourceSelect_i || MainClkEnable_i;
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,731 @@
|
|||
|
||||
/*------------------------------------------------------------------------------------------
|
||||
Title: TLC.v
|
||||
Description:
|
||||
|
||||
--------------------------------------------------------------------------------------------
|
||||
Revision History:
|
||||
|
||||
--------------------------------------------------------------------------------------------
|
||||
To Do:
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------*/
|
||||
|
||||
`timescale 1ns / 10ps
|
||||
|
||||
`include "SensorHubDefines.v"
|
||||
`include "ulpsh_rtl_defines.v"
|
||||
|
||||
module TLC (
|
||||
// General interface
|
||||
input SPI_SCLK,
|
||||
input FFE_Clock,
|
||||
input Clock32KIn,
|
||||
input ResetIn,
|
||||
output SW_Reset,
|
||||
|
||||
output reg RingOsc_cal_en,
|
||||
output reg [2:0] RingOsc_select,
|
||||
input [15:0] RingOsc_cal_value,
|
||||
|
||||
input I2C_Master_Error,
|
||||
input FFEBusyIn,
|
||||
input SMBusyIn,
|
||||
input SMOverrunIn,
|
||||
output StartFFEOut,
|
||||
// output InitSMOut, // Removed for Rel 0 on 6/18
|
||||
output StartSMOut,
|
||||
output reg [15:0] TimeStampOut,
|
||||
output reg TimeStampOut_Tog,
|
||||
output UseFastClockOut,
|
||||
|
||||
input [7:0] InterruptMsgFromFFEIn,
|
||||
output InterruptPinOut,
|
||||
input SensorInterruptIn,
|
||||
|
||||
output [31:0] FFE_Mailbox_Out,
|
||||
|
||||
input [9:0] CtrlRunTimeAddressReg, // Expanded for Rel 0 on 6/18
|
||||
output reg [9:0] CtrlRunTimeAddressOut, // Expanded for Rel 0 on 6/18
|
||||
output reg CtrlRunTimeAddressSM,
|
||||
|
||||
// Interface to SPI Slave
|
||||
input [6:0] RegAddrIn,
|
||||
input [7:0] RegDataIn,
|
||||
output reg [7:0] RegDataOut,
|
||||
input RegWriteEnableIn,
|
||||
input RegReadDataAckIn,
|
||||
|
||||
// Interface to memories
|
||||
output TLCDrivingFFEControlMem,
|
||||
output TLCDrivingFFEDataMem1,
|
||||
output TLCDrivingFFEDataMem2,
|
||||
output TLCDrivingSMMem,
|
||||
output TLCDrivingCMMem,
|
||||
output MemorySelect_en,
|
||||
output [2:0] MemorySelect,
|
||||
output [11:0] MemoryAddressOut,
|
||||
output [35:0] MemoryDataOut,
|
||||
input [35:0] MemoryDataIn,
|
||||
output reg MemoryReadEnableOut,
|
||||
output reg MemoryWriteEnableOut,
|
||||
output MemoryClockOut,
|
||||
|
||||
// Interface to Communication Manager FIFO
|
||||
output reg CM_FIFO_ReadEnable,
|
||||
input [8:0] CM_FIFO_ReadData,
|
||||
input [3:0] CM_FIFO_PopFlags,
|
||||
input [3:0] CM_FIFO_PushFlags,
|
||||
input CM_FIFO_Overflow,
|
||||
output CM_RingBufferMode,
|
||||
input CM_AutoDrain_Busy,
|
||||
|
||||
// test points
|
||||
output TP1,
|
||||
output TP2,
|
||||
|
||||
// LEDs ON/OFF Control
|
||||
output reg [2:0] leds_off_o,
|
||||
|
||||
// FFE CLock ENable
|
||||
output reg FFE_CLK_Enable_o,
|
||||
output reg ClockEnable_o,
|
||||
output reg clock_32KHz_Enable_o,
|
||||
output reg [2:0] FFE_Clock_Control_o,
|
||||
output reg [2:0] SM_Clock_Control_o,
|
||||
output reg ClkSourceSelect_o
|
||||
);
|
||||
|
||||
parameter CYCLES_PER_MSEC = 33; // number of 32.768KHz clock cycles per millisecond
|
||||
|
||||
reg [7:0] CommandReg;
|
||||
reg [7:0] msecs_per_sample_reg;
|
||||
reg [7:0] MemSelect_reg;
|
||||
reg [7:0] MemAddrLow;
|
||||
reg [7:0] MemAddrHigh;
|
||||
reg [7:0] MemDataByte0;
|
||||
reg [7:0] MemDataByte1;
|
||||
reg [7:0] MemDataByte2;
|
||||
reg [7:0] MemDataByte3;
|
||||
reg [3:0] MemDataByte4;
|
||||
reg [7:0] CM_Control_reg;
|
||||
reg WaitForMemRead;
|
||||
reg WaitForMemWrite;
|
||||
reg IncrementMemAddr;
|
||||
reg StartFFE_32K, StartFFE_Clkin;
|
||||
// reg InitSM_Clkin; // Removed for Rel 0 on 6/18
|
||||
reg StartSM_Clkin;
|
||||
|
||||
reg [7:0] clock32K_count; // this needs to be wide enough to accomodate the CYCLES_PER_MSEC constant
|
||||
reg [7:0] count_msecs;
|
||||
wire pulse_1ms;
|
||||
wire pulse_sample_period;
|
||||
reg pulse_sample_period_reg;
|
||||
wire FFE_Holdoff; // Used to ensure a full count on the First FFE run
|
||||
reg FFE_Holdoff_reset;
|
||||
reg FFE_Holdoff_preset;
|
||||
|
||||
wire RunFFEContinuously;
|
||||
//wire RunFFEOnce;
|
||||
//wire RunSMOnce;
|
||||
//wire RunSensorInit;
|
||||
|
||||
wire CM_FIFO_Overflow_reg;
|
||||
reg [3:0] CM_FIFO_PopFlags_r1;
|
||||
reg [3:0] CM_FIFO_PopFlags_r2;
|
||||
reg [3:0] CM_FIFO_PopFlags_sync;
|
||||
|
||||
wire I2C_Master_Error_reg;
|
||||
|
||||
reg [7:0] InterruptCtrl_reg;
|
||||
reg [7:0] InterruptFFEMsg_clear;
|
||||
wire Interrupt_En_0;
|
||||
wire [7:0] InterruptFFEMsg_latched;
|
||||
wire InterruptFFEMsg_ORed;
|
||||
|
||||
reg SW_Reset_Start;
|
||||
reg SW_Reset_r1;
|
||||
reg SW_Reset_r2;
|
||||
|
||||
reg RunFFEContinuously_r1;
|
||||
reg RunFFEContinuously_r2;
|
||||
|
||||
reg FFEOverrun;
|
||||
reg [31:0] FFE_Mailbox_reg;
|
||||
|
||||
wire i_StartFFEOut;
|
||||
reg s1_StartFFEOut, s2_StartFFEOut;
|
||||
reg s3_FFEBusyIn, s2_FFEBusyIn, s1_FFEBusyIn;
|
||||
reg d_FFE_CLK_Enable;
|
||||
reg s1_SMBusyIn, s2_SMBusyIn, s3_SMBusyIn;
|
||||
wire d_ClockEnable;
|
||||
wire smInit_enable;
|
||||
// reg s1_InitSM_Clkin, s2_InitSM_Clkin, s3_InitSM_Clkin, s4_InitSM_Clkin, s5_InitSM_Clkin, s6_InitSM_Clkin; // Removed for Rel 0 on 6/18
|
||||
reg s1_StartSM_Clkin, s2_StartSM_Clkin, s3_StartSM_Clkin, s4_StartSM_Clkin, s5_StartSM_Clkin, s6_StartSM_Clkin;
|
||||
wire [2:0] FFE_SET, SM_SET;
|
||||
wire clkSourceSelect;
|
||||
reg SleepMode, IntInputLevel;
|
||||
reg sensorInterrupt_s1, sensorInterrupt_s2, sensorInterrupt_s3;
|
||||
wire sleepModeSet, sleepReset;
|
||||
|
||||
|
||||
|
||||
assign FFE_Mailbox_Out = {FFE_Mailbox_reg[15:0], FFE_Mailbox_reg[31:16]};
|
||||
assign MemoryClockOut = SPI_SCLK;
|
||||
|
||||
assign RunFFEContinuously = CommandReg[0];
|
||||
//assign RunFFEOnce = CommandReg[1];
|
||||
//assign RunSMOnce = CommandReg[2];
|
||||
//assign RunSensorInit = CommandReg[3];
|
||||
//assign SW_Reset = CommandReg[6];
|
||||
assign UseFastClockOut = CommandReg[7];
|
||||
|
||||
assign Interrupt_En_0 = InterruptCtrl_reg[0];
|
||||
assign Interrupt_En_1 = InterruptCtrl_reg[1];
|
||||
|
||||
assign TLCDrivingFFEControlMem = MemSelect_reg[7] ? (MemSelect_reg[2:0] == 3'b000) : 1'b0;
|
||||
assign TLCDrivingFFEDataMem1 = MemSelect_reg[7] ? (MemSelect_reg[2:0] == 3'b001) : 1'b0;
|
||||
assign TLCDrivingFFEDataMem2 = MemSelect_reg[7] ? (MemSelect_reg[2:0] == 3'b010) : 1'b0;
|
||||
assign TLCDrivingSMMem = MemSelect_reg[7] ? (MemSelect_reg[2:0] == 3'b011) : 1'b0;
|
||||
assign TLCDrivingCMMem = 1'b0; // should be removed, since the CMMem is now the CM FIFO
|
||||
assign MemorySelect_en = MemSelect_reg[7];
|
||||
assign MemorySelect = MemSelect_reg[2:0];
|
||||
|
||||
assign MemoryAddressOut = {MemAddrHigh[3:0],MemAddrLow};
|
||||
assign MemoryDataOut = {MemDataByte4[3:0],MemDataByte3,MemDataByte2,MemDataByte1,MemDataByte0};
|
||||
|
||||
assign CM_RingBufferMode = CM_Control_reg[0];
|
||||
|
||||
|
||||
|
||||
// requests to run FFE and Sensor Manager
|
||||
|
||||
assign pulse_1ms = (clock32K_count == (CYCLES_PER_MSEC - 1)); // 1-clock pulse each time 1ms has elapsed
|
||||
assign pulse_sample_period = (pulse_1ms && (count_msecs == 1)); // 1-clock pulse @ each sample period
|
||||
|
||||
assign StartFFEOut = s2_StartFFEOut;
|
||||
// Delay starting FFE
|
||||
always @(posedge Clock32KIn or posedge ResetIn)
|
||||
begin
|
||||
if (ResetIn)
|
||||
begin
|
||||
s1_StartFFEOut <= 1'b0;
|
||||
s2_StartFFEOut <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
s1_StartFFEOut <= i_StartFFEOut;
|
||||
s2_StartFFEOut <= s1_StartFFEOut;
|
||||
end
|
||||
end
|
||||
|
||||
// Synchronized FFE Busy input
|
||||
// & logic to generate FFE_CLK_Enable (active when timer starts and off when busy end)
|
||||
always @(posedge Clock32KIn or posedge ResetIn)
|
||||
begin
|
||||
if (ResetIn)
|
||||
begin
|
||||
s1_FFEBusyIn <= 0;
|
||||
s2_FFEBusyIn <= 0;
|
||||
s3_FFEBusyIn <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
s1_FFEBusyIn <= FFEBusyIn;
|
||||
s2_FFEBusyIn <= s1_FFEBusyIn;
|
||||
s3_FFEBusyIn <= s2_FFEBusyIn;
|
||||
end
|
||||
end
|
||||
|
||||
always @*
|
||||
begin
|
||||
if (!FFE_CLK_Enable_o)
|
||||
d_FFE_CLK_Enable = s1_StartFFEOut ^ i_StartFFEOut;
|
||||
else
|
||||
if (s3_FFEBusyIn && !s2_FFEBusyIn)
|
||||
d_FFE_CLK_Enable = 1'b0;
|
||||
else
|
||||
d_FFE_CLK_Enable = FFE_CLK_Enable_o;
|
||||
end
|
||||
|
||||
always @(posedge Clock32KIn or posedge ResetIn)
|
||||
begin
|
||||
if (ResetIn)
|
||||
begin
|
||||
FFE_CLK_Enable_o <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
FFE_CLK_Enable_o <= d_FFE_CLK_Enable;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
always @(posedge Clock32KIn or posedge ResetIn) begin
|
||||
if (ResetIn) begin
|
||||
clock32K_count <= 0;
|
||||
count_msecs <= 1; // reset to 1 (sample period = 0 does not make sense, and should be invalid)
|
||||
pulse_sample_period_reg <= 0;
|
||||
TimeStampOut <= 0;
|
||||
TimeStampOut_Tog <= 0;
|
||||
StartFFE_32K <= 0;
|
||||
FFEOverrun <= 0;
|
||||
end else begin
|
||||
|
||||
pulse_sample_period_reg <= pulse_sample_period; // de-glitch the pulse_sample_period signal, since it's used to asynchronously reset FFE_Holdoff
|
||||
|
||||
if (pulse_1ms) begin
|
||||
clock32K_count <= 0;
|
||||
TimeStampOut <= TimeStampOut + 1; // the timestamp increments @ 1ms
|
||||
TimeStampOut_Tog <= ~TimeStampOut_Tog; // the timestamp increments @ 1ms
|
||||
end else begin
|
||||
clock32K_count <= clock32K_count + 1;
|
||||
TimeStampOut <= TimeStampOut;
|
||||
TimeStampOut_Tog <= TimeStampOut_Tog;
|
||||
end
|
||||
|
||||
if (pulse_sample_period) // sample period boundary
|
||||
count_msecs <= msecs_per_sample_reg; // reset the msec counter back to the register value
|
||||
else
|
||||
if (pulse_1ms)
|
||||
count_msecs <= count_msecs - 1; // decrement by 1 @ the 1ms boundary
|
||||
else
|
||||
count_msecs <= count_msecs;
|
||||
|
||||
|
||||
//if ((clock32K_count == (CYCLES_PER_MSEC - 1)) && (count_msecs == 1)) begin // msec counter about to be reset back to the register value
|
||||
if (pulse_sample_period && !SleepMode) begin // msec counter about to be reset back to the register value
|
||||
if (RunFFEContinuously && !FFE_Holdoff) begin // trigger a run only if FFE_Holdoff has been deactivated
|
||||
if (FFEBusyIn) begin
|
||||
FFEOverrun <= 1'b1;
|
||||
end else begin
|
||||
StartFFE_32K <= ~StartFFE_32K;
|
||||
//CMBufferBeingWrittenOut <= CMBufferBeingWrittenOut + 1;
|
||||
//if (!AlternateI2CIsActiveIn) begin // If Alternate I2C is active, then we are reading the buffer
|
||||
// CMBufferBeingRead <= CMBufferBeingWrittenOut;
|
||||
//end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
// software-controlled reset, 1-2 clock pulses wide @ the 32K clock
|
||||
|
||||
// generate a one-clock pulse @ the SPI_SCLK, to be used to preset a flop running in the 32K clock domain
|
||||
always @(posedge SPI_SCLK)
|
||||
if (RegWriteEnableIn && (RegAddrIn == `CommandReg) && RegDataIn[6]) // SW Reset control bit is being written
|
||||
SW_Reset_Start <= 1;
|
||||
else
|
||||
SW_Reset_Start <= 0;
|
||||
|
||||
// 32K clock domain, the r1 flop gets preset by the SPI clock pulse above, and only gets deactivated after another 32K clock period (using the r2 flop)
|
||||
always @(posedge Clock32KIn or posedge SW_Reset_Start)
|
||||
if (SW_Reset_Start)
|
||||
SW_Reset_r1 <= 1;
|
||||
else
|
||||
if (SW_Reset_r1 && !SW_Reset_r2)
|
||||
SW_Reset_r1 <= 1;
|
||||
else
|
||||
SW_Reset_r1 <= 0;
|
||||
|
||||
// r2 flop, used to stretch the generated reset pulse
|
||||
always @(posedge Clock32KIn)
|
||||
SW_Reset_r2 <= SW_Reset_r1;
|
||||
|
||||
|
||||
assign SW_Reset = SW_Reset_r2;
|
||||
|
||||
|
||||
// When running the FFE continuously, this logic prevents the FFE from running until the start of a sample period
|
||||
|
||||
always @(posedge SPI_SCLK or posedge ResetIn)
|
||||
if (ResetIn)
|
||||
FFE_Holdoff_preset <= 0;
|
||||
else
|
||||
if (RegWriteEnableIn && (RegAddrIn == `CommandReg) && RegDataIn[0]) // Run FFE Continuously control bit is being written...
|
||||
FFE_Holdoff_preset <= 1; // ... assert FFE_Holdoff
|
||||
else
|
||||
FFE_Holdoff_preset <= 0;
|
||||
|
||||
always @(posedge Clock32KIn or posedge ResetIn)
|
||||
if (ResetIn)
|
||||
FFE_Holdoff_reset <= 0;
|
||||
else
|
||||
if (pulse_sample_period_reg && RunFFEContinuously && FFE_Holdoff) // reset FFE_Holdoff when the first timer expiration occurs, to ensure a full first run
|
||||
FFE_Holdoff_reset <= 1;
|
||||
else
|
||||
FFE_Holdoff_reset <= 0;
|
||||
|
||||
dff_pre_clr dff_pre_clr_FFE_Holdoff ( .CLK(1'b0) , .CLR(FFE_Holdoff_reset), .D(1'b0), .PRE(FFE_Holdoff_preset), .Q(FFE_Holdoff) );
|
||||
|
||||
|
||||
|
||||
// latch the I2C Master Error signal
|
||||
dff_pre_clr dff_pre_clr_I2C_Master_Error ( .CLK(1'b0) , .CLR(ResetIn), .D(1'b0), .PRE(I2C_Master_Error), .Q(I2C_Master_Error_reg) );
|
||||
|
||||
|
||||
|
||||
// interrupt logic
|
||||
|
||||
// note: InterruptMsgFromFFEIn should be de-glitched externally (currently de-glitched in FFE_Control.v)
|
||||
|
||||
// logic to clear the FFE msg interrupts
|
||||
always @(posedge SPI_SCLK)
|
||||
if (RegWriteEnableIn && (RegAddrIn == `InterruptFFEMsg))
|
||||
InterruptFFEMsg_clear <= RegDataIn[7:0];
|
||||
else
|
||||
InterruptFFEMsg_clear <= 8'b0;
|
||||
|
||||
// latch the interrupt msg from the FFE, clear when the InterruptFFEMsg register is being written
|
||||
dff_pre_clr dff_pre_clr_InterruptFFEMsg_0 ( .CLK(1'b0) , .CLR(InterruptFFEMsg_clear[0]), .D(1'b0), .PRE(InterruptMsgFromFFEIn[0]), .Q(InterruptFFEMsg_latched[0]) );
|
||||
dff_pre_clr dff_pre_clr_InterruptFFEMsg_1 ( .CLK(1'b0) , .CLR(InterruptFFEMsg_clear[1]), .D(1'b0), .PRE(InterruptMsgFromFFEIn[1]), .Q(InterruptFFEMsg_latched[1]) );
|
||||
dff_pre_clr dff_pre_clr_InterruptFFEMsg_2 ( .CLK(1'b0) , .CLR(InterruptFFEMsg_clear[2]), .D(1'b0), .PRE(InterruptMsgFromFFEIn[2]), .Q(InterruptFFEMsg_latched[2]) );
|
||||
dff_pre_clr dff_pre_clr_InterruptFFEMsg_3 ( .CLK(1'b0) , .CLR(InterruptFFEMsg_clear[3]), .D(1'b0), .PRE(InterruptMsgFromFFEIn[3]), .Q(InterruptFFEMsg_latched[3]) );
|
||||
dff_pre_clr dff_pre_clr_InterruptFFEMsg_4 ( .CLK(1'b0) , .CLR(InterruptFFEMsg_clear[4]), .D(1'b0), .PRE(InterruptMsgFromFFEIn[4]), .Q(InterruptFFEMsg_latched[4]) );
|
||||
dff_pre_clr dff_pre_clr_InterruptFFEMsg_5 ( .CLK(1'b0) , .CLR(InterruptFFEMsg_clear[5]), .D(1'b0), .PRE(InterruptMsgFromFFEIn[5]), .Q(InterruptFFEMsg_latched[5]) );
|
||||
dff_pre_clr dff_pre_clr_InterruptFFEMsg_6 ( .CLK(1'b0) , .CLR(InterruptFFEMsg_clear[6]), .D(1'b0), .PRE(InterruptMsgFromFFEIn[6]), .Q(InterruptFFEMsg_latched[6]) );
|
||||
dff_pre_clr dff_pre_clr_InterruptFFEMsg_7 ( .CLK(1'b0) , .CLR(InterruptFFEMsg_clear[7]), .D(1'b0), .PRE(InterruptMsgFromFFEIn[7]), .Q(InterruptFFEMsg_latched[7]) );
|
||||
|
||||
|
||||
|
||||
assign InterruptFFEMsg_ORed = |InterruptFFEMsg_latched[7:0];
|
||||
|
||||
// drive the interrupt output pin: active-high, level sensitive
|
||||
assign InterruptPinOut = (Interrupt_En_0 && InterruptFFEMsg_ORed) ||
|
||||
(Interrupt_En_1 && (I2C_Master_Error_reg || SMOverrunIn || FFEOverrun));
|
||||
|
||||
|
||||
|
||||
// overflow detection bit
|
||||
|
||||
dff_pre_clr dff_pre_clr_overflow ( .CLK(1'b0) , .CLR(ResetIn), .D(1'b0), .PRE(CM_FIFO_Overflow), .Q(CM_FIFO_Overflow_reg) );
|
||||
|
||||
|
||||
// sync the FIFO flags to the SPI clock domain
|
||||
always @(posedge SPI_SCLK) begin
|
||||
CM_FIFO_PopFlags_r1 <= CM_FIFO_PopFlags;
|
||||
CM_FIFO_PopFlags_r2 <= CM_FIFO_PopFlags_r1;
|
||||
if (CM_FIFO_PopFlags_r1 == CM_FIFO_PopFlags_r2)
|
||||
CM_FIFO_PopFlags_sync <= CM_FIFO_PopFlags_r2;
|
||||
else
|
||||
CM_FIFO_PopFlags_sync <= CM_FIFO_PopFlags_sync;
|
||||
end
|
||||
|
||||
|
||||
//Registers for controlling the FFE and memories
|
||||
always @(posedge SPI_SCLK or posedge ResetIn) begin
|
||||
if (ResetIn) begin
|
||||
RegDataOut <= 0;
|
||||
MemoryReadEnableOut <= 0;
|
||||
MemoryWriteEnableOut <= 0;
|
||||
WaitForMemRead <= 0;
|
||||
WaitForMemWrite <= 0;
|
||||
IncrementMemAddr <= 0;
|
||||
CommandReg <= 0;
|
||||
msecs_per_sample_reg <= 1; // default value is 1 (sample period = 0 should be invalid)
|
||||
InterruptCtrl_reg <= 0;
|
||||
MemSelect_reg <= 0;
|
||||
MemAddrLow <= 0;
|
||||
MemAddrHigh <= 0;
|
||||
MemDataByte0 <= 0;
|
||||
MemDataByte1 <= 0;
|
||||
MemDataByte2 <= 0;
|
||||
MemDataByte3 <= 0;
|
||||
MemDataByte4 <= 0;
|
||||
StartFFE_Clkin <= 0;
|
||||
// InitSM_Clkin <= 0; // Removed for Rel 0 on 6/18
|
||||
StartSM_Clkin <= 0;
|
||||
CM_FIFO_ReadEnable <= 0;
|
||||
CM_Control_reg <= 0;
|
||||
FFE_Mailbox_reg <= 0;
|
||||
CtrlRunTimeAddressOut <= 0;
|
||||
CtrlRunTimeAddressSM <= 0;
|
||||
leds_off_o <= 3'b111;
|
||||
ClkSourceSelect_o <= 1'b0;
|
||||
clock_32KHz_Enable_o <= 1'b1;
|
||||
FFE_Clock_Control_o <= FFE_SET;
|
||||
SM_Clock_Control_o <= SM_SET;
|
||||
RingOsc_cal_en <= 0;
|
||||
RingOsc_select <= 3'h7;
|
||||
end else begin
|
||||
if (MemoryWriteEnableOut) begin
|
||||
if(WaitForMemWrite == 0) begin
|
||||
WaitForMemWrite <= 1;
|
||||
end else begin
|
||||
MemoryWriteEnableOut <= 0;
|
||||
WaitForMemWrite <= 0;
|
||||
IncrementMemAddr <= 1;
|
||||
end
|
||||
end // if (MemoryWriteEnableOut)
|
||||
|
||||
if (IncrementMemAddr) begin
|
||||
IncrementMemAddr <= 0;
|
||||
{MemAddrHigh[3:0],MemAddrLow} <= {MemAddrHigh[3:0],MemAddrLow} + 1;
|
||||
end
|
||||
|
||||
if (MemoryReadEnableOut) begin
|
||||
if (WaitForMemRead == 0) begin
|
||||
WaitForMemRead <= 1;
|
||||
end else begin
|
||||
MemoryReadEnableOut <= 0;
|
||||
WaitForMemRead <= 0;
|
||||
MemDataByte4 <= MemoryDataIn[35:32];
|
||||
MemDataByte3 <= MemoryDataIn[31:24];
|
||||
MemDataByte2 <= MemoryDataIn[23:16];
|
||||
MemDataByte1 <= MemoryDataIn[15:8];
|
||||
MemDataByte0 <= MemoryDataIn[7:0];
|
||||
end
|
||||
end
|
||||
|
||||
// CM FIFO read control
|
||||
///// Old Code
|
||||
/*
|
||||
if (CM_FIFO_ReadEnable)
|
||||
CM_FIFO_ReadEnable <= 0;
|
||||
else
|
||||
if (RegAddrIn == `CM_FIFO_Data && RegReadDataAckIn)
|
||||
CM_FIFO_ReadEnable <= 1;
|
||||
else
|
||||
CM_FIFO_ReadEnable <= 0;
|
||||
*/
|
||||
//// New Code
|
||||
if (RegAddrIn == `CM_FIFO_Data && RegReadDataAckIn)
|
||||
CM_FIFO_ReadEnable <= !CM_FIFO_ReadEnable;
|
||||
else
|
||||
CM_FIFO_ReadEnable <= CM_FIFO_ReadEnable;
|
||||
|
||||
if (RegWriteEnableIn) begin
|
||||
case (RegAddrIn)
|
||||
`CommandReg: begin
|
||||
CommandReg <= RegDataIn;
|
||||
//FFE_Holdoff <= 1;
|
||||
end
|
||||
`milSecSample: msecs_per_sample_reg <= RegDataIn;
|
||||
`InterruptCtrl: InterruptCtrl_reg <= RegDataIn;
|
||||
//`InterruptStat: // currently writes to this register does nothing, adding more interrupts may change this.
|
||||
`MemSelect: MemSelect_reg <= RegDataIn;
|
||||
`MemAddrLow: MemAddrLow <= RegDataIn;
|
||||
`MemAddrHigh: begin
|
||||
MemAddrHigh <= RegDataIn;
|
||||
WaitForMemRead <= 0; // this is assigned in separate 'if' statements, the logic should be combined into 1.
|
||||
MemoryReadEnableOut <= 1;
|
||||
end
|
||||
`MemDataByte0: MemDataByte0 <= RegDataIn;
|
||||
`MemDataByte1: MemDataByte1 <= RegDataIn;
|
||||
`MemDataByte2: MemDataByte2 <= RegDataIn;
|
||||
`MemDataByte3: MemDataByte3 <= RegDataIn;
|
||||
`MemDataByte4: begin
|
||||
MemDataByte4 <= RegDataIn[3:0];
|
||||
MemoryWriteEnableOut <= 1;
|
||||
WaitForMemWrite <= 0; // this is assigned in separate 'if' statements, the logic should be combined into 1.
|
||||
end
|
||||
`CM_Control: CM_Control_reg <= RegDataIn;
|
||||
`MailboxToFFE_0: FFE_Mailbox_reg[7:0] <= RegDataIn;
|
||||
`MailboxToFFE_1: FFE_Mailbox_reg[15:8] <= RegDataIn;
|
||||
`MailboxToFFE_2: FFE_Mailbox_reg[23:16] <= RegDataIn;
|
||||
`MailboxToFFE_3: FFE_Mailbox_reg[31:24] <= RegDataIn;
|
||||
`RunTimeAdrReg: begin
|
||||
CtrlRunTimeAddressOut[7:0] <= RegDataIn; // Expanded for Rel 0 on 6/18
|
||||
CtrlRunTimeAddressSM <= ~CtrlRunTimeAddressSM;
|
||||
end
|
||||
`DemoLedCtrlReg: begin
|
||||
leds_off_o <= RegDataIn[2:0];
|
||||
end
|
||||
`ClocksControl: begin
|
||||
FFE_Clock_Control_o <= RegDataIn[2:0];
|
||||
SM_Clock_Control_o <= RegDataIn[5:3];
|
||||
ClkSourceSelect_o <= RegDataIn[6];
|
||||
clock_32KHz_Enable_o <= RegDataIn[7];
|
||||
end
|
||||
`RunTimeAdrReg_Upr: begin
|
||||
CtrlRunTimeAddressOut[9:8] <= RegDataIn[1:0]; // New for Rel 0 on 6/18
|
||||
end
|
||||
`SleepControl: begin
|
||||
RingOsc_cal_en <= RegDataIn[7];
|
||||
RingOsc_select <= RegDataIn[6:4];
|
||||
end
|
||||
endcase
|
||||
|
||||
if ((RegAddrIn == `CommandReg) && RegDataIn[1]) // run FFE once
|
||||
StartFFE_Clkin <= ~StartFFE_Clkin;
|
||||
|
||||
//the SM control signals come as a pair because only one should be toggled at a time if both bits are written to in CommandReg
|
||||
//Initialization takes precedense over Start
|
||||
// if ((RegAddrIn == `CommandReg) && RegDataIn[3]) // Removed for Rel 0 on 6/18
|
||||
// InitSM_Clkin <= ~InitSM_Clkin; // Removed for Rel 0 on 6/18
|
||||
// else if ((RegAddrIn == `CommandReg) && RegDataIn[2]) // Updated for Rel 0 on 6/18
|
||||
if ((RegAddrIn == `CommandReg) && RegDataIn[2])
|
||||
StartSM_Clkin <= ~StartSM_Clkin;
|
||||
|
||||
end else begin
|
||||
case (RegAddrIn)
|
||||
|
||||
`CommandReg: RegDataOut <= { CommandReg[7], // UseFastClk
|
||||
1'b0, // SW_Reset, self-clearing
|
||||
1'b0, // reserved
|
||||
1'b0, // reserved
|
||||
1'b0, // RunSensorInit, self-clearing
|
||||
1'b0, // RunSMOnce, self-clearing
|
||||
1'b0, // RunFFEOnce, self-clearing
|
||||
CommandReg[0] // RunFFEContinuously
|
||||
};
|
||||
|
||||
`StatusReg: RegDataOut <= { 3'b0,
|
||||
I2C_Master_Error_reg,
|
||||
SMOverrunIn,
|
||||
FFEOverrun,
|
||||
SMBusyIn,
|
||||
FFEBusyIn
|
||||
}; // Status Reg
|
||||
|
||||
`milSecSample: RegDataOut <= msecs_per_sample_reg;
|
||||
`InterruptCtrl: RegDataOut <= {6'b0, Interrupt_En_1, Interrupt_En_0};
|
||||
`InterruptStat: RegDataOut <= {7'b0, InterruptFFEMsg_ORed};
|
||||
`MemSelect: RegDataOut <= {MemSelect_reg[7], 4'b0, MemSelect_reg[2:0]};
|
||||
`MemAddrLow: RegDataOut <= MemAddrLow;
|
||||
`MemAddrHigh: RegDataOut <= MemAddrHigh;
|
||||
`MemDataByte0: RegDataOut <= MemoryDataIn[7:0]; // MemDataByte0;
|
||||
`MemDataByte1: RegDataOut <= MemoryDataIn[15:8]; // MemDataByte1;
|
||||
`MemDataByte2: RegDataOut <= MemoryDataIn[23:16]; // MemDataByte2;
|
||||
`MemDataByte3: RegDataOut <= MemoryDataIn[31:24]; // MemDataByte3;
|
||||
`MemDataByte4: RegDataOut <= MemoryDataIn[35:32]; // MemDataByte4;
|
||||
`CM_FIFO_Data: RegDataOut <= CM_FIFO_ReadData[7:0];
|
||||
`CM_Control: RegDataOut <= {7'b0, CM_RingBufferMode};
|
||||
`CM_Status: RegDataOut <= {6'b0, CM_FIFO_Overflow_reg, CM_AutoDrain_Busy};
|
||||
`CM_FIFO_Flags_0: RegDataOut <= {4'b0, CM_FIFO_PopFlags_sync};
|
||||
`MailboxToFFE_0: RegDataOut <= FFE_Mailbox_reg[7:0];
|
||||
`MailboxToFFE_1: RegDataOut <= FFE_Mailbox_reg[15:8];
|
||||
`MailboxToFFE_2: RegDataOut <= FFE_Mailbox_reg[23:16];
|
||||
`MailboxToFFE_3: RegDataOut <= FFE_Mailbox_reg[31:24];
|
||||
`InterruptFFEMsg: RegDataOut <= InterruptFFEMsg_latched;
|
||||
`RunTimeAdrReg: RegDataOut <= CtrlRunTimeAddressReg[7:0]; // Expanded for Rel 0 on 6/18
|
||||
`DemoLedCtrlReg: RegDataOut <= {5'b0, leds_off_o};
|
||||
`ClocksControl: RegDataOut <= {clock_32KHz_Enable_o, ClkSourceSelect_o, SM_Clock_Control_o[2:0], FFE_Clock_Control_o[2:0]};
|
||||
`SleepControl: RegDataOut <= {RingOsc_cal_en, RingOsc_select[2:0], 1'b0, sleepModeSet, IntInputLevel, SleepMode};
|
||||
`RunTimeAdrReg_Upr: RegDataOut <= {6'h0, CtrlRunTimeAddressReg[9:8]}; // New for Rel 0 on 6/18
|
||||
`CalValueLow: RegDataOut <= RingOsc_cal_value[7:0];
|
||||
`CalValueHi: RegDataOut <= RingOsc_cal_value[15:8];
|
||||
default: RegDataOut <= 8'h21;
|
||||
endcase
|
||||
end
|
||||
end // if (ResetIn)
|
||||
end // Always
|
||||
|
||||
|
||||
assign i_StartFFEOut = StartFFE_32K ^ StartFFE_Clkin;
|
||||
//assign InitSMOut = s6_InitSM_Clkin; // Removed for Rel 0 on 6/18
|
||||
assign StartSMOut = s6_StartSM_Clkin;
|
||||
|
||||
// test points
|
||||
assign TP1 = FFE_Mailbox_reg[0];
|
||||
assign TP2 = RegWriteEnableIn;
|
||||
|
||||
// Logic to drive RIng Osc Clock Enable / Disable
|
||||
|
||||
//assign smInit_enable = (s2_InitSM_Clkin ^ s3_InitSM_Clkin) || (s2_StartSM_Clkin ^ s3_StartSM_Clkin); // Removed for Rel 0 on 6/18
|
||||
assign smInit_enable = (s2_StartSM_Clkin ^ s3_StartSM_Clkin); // Updated for Rel 0 on 6/18
|
||||
|
||||
assign d_ClockEnable = ClockEnable_o ? ((!s2_SMBusyIn && s3_SMBusyIn) ? 1'b0 : 1'b1) : (( d_FFE_CLK_Enable || smInit_enable ) ? 1'b1 : 1'b0);
|
||||
always @(posedge Clock32KIn or posedge ResetIn)
|
||||
begin
|
||||
if (ResetIn)
|
||||
begin
|
||||
s1_SMBusyIn <= 0;
|
||||
s2_SMBusyIn <= 0;
|
||||
s3_SMBusyIn <= 0;
|
||||
ClockEnable_o <= 0;
|
||||
// s1_InitSM_Clkin <= 0;
|
||||
// s2_InitSM_Clkin <= 0;
|
||||
// s3_InitSM_Clkin <= 0;
|
||||
// s4_InitSM_Clkin <= 0;
|
||||
// s5_InitSM_Clkin <= 0;
|
||||
// s6_InitSM_Clkin <= 0;
|
||||
s1_StartSM_Clkin <= 0;
|
||||
s2_StartSM_Clkin <= 0;
|
||||
s3_StartSM_Clkin <= 0;
|
||||
s4_StartSM_Clkin <= 0;
|
||||
s5_StartSM_Clkin <= 0;
|
||||
s6_StartSM_Clkin <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
s1_SMBusyIn <= (SMBusyIn || FFEBusyIn);
|
||||
s2_SMBusyIn <= s1_SMBusyIn;
|
||||
s3_SMBusyIn <= s2_SMBusyIn;
|
||||
ClockEnable_o <= d_ClockEnable;
|
||||
// s1_InitSM_Clkin <= InitSM_Clkin;
|
||||
// s2_InitSM_Clkin <= s1_InitSM_Clkin;
|
||||
// s3_InitSM_Clkin <= s2_InitSM_Clkin;
|
||||
// s4_InitSM_Clkin <= s3_InitSM_Clkin;
|
||||
// s5_InitSM_Clkin <= s4_InitSM_Clkin;
|
||||
// s6_InitSM_Clkin <= s5_InitSM_Clkin;
|
||||
s1_StartSM_Clkin <= StartSM_Clkin;
|
||||
s2_StartSM_Clkin <= s1_StartSM_Clkin;
|
||||
s3_StartSM_Clkin <= s2_StartSM_Clkin;
|
||||
s4_StartSM_Clkin <= s3_StartSM_Clkin;
|
||||
s5_StartSM_Clkin <= s4_StartSM_Clkin;
|
||||
s6_StartSM_Clkin <= s5_StartSM_Clkin;
|
||||
end
|
||||
end
|
||||
|
||||
// Logic to select default reset values for the SM and FFE CLK selection
|
||||
assign FFE_SET[0] = (`FFE1CLK_FREQ_SLT == 8'b00000001) || (`FFE1CLK_FREQ_SLT == 8'b00000010) || (`FFE1CLK_FREQ_SLT == 8'b00000100) || (`FFE1CLK_FREQ_SLT == 8'b00001000) ||
|
||||
(`FFE1CLK_FREQ_SLT == 8'b00010000) || (`FFE1CLK_FREQ_SLT == 8'b01000000);
|
||||
assign FFE_SET[1] = (`FFE1CLK_FREQ_SLT == 8'b00000001) || (`FFE1CLK_FREQ_SLT == 8'b00000010) || (`FFE1CLK_FREQ_SLT == 8'b00000100) || (`FFE1CLK_FREQ_SLT == 8'b00001000) ||
|
||||
(`FFE1CLK_FREQ_SLT == 8'b00100000) || (`FFE1CLK_FREQ_SLT == 8'b01000000);
|
||||
assign FFE_SET[2] = (`FFE1CLK_FREQ_SLT == 8'b10000000);
|
||||
|
||||
assign SM_SET[0] = (`SM1CLK_FREQ_SLT == 8'b00000010) || (`SM1CLK_FREQ_SLT == 8'b00001000) || (`SM1CLK_FREQ_SLT == 8'b00100000) || (`SM1CLK_FREQ_SLT == 8'b10000000);
|
||||
assign SM_SET[1] = (`SM1CLK_FREQ_SLT == 8'b00000100) || (`SM1CLK_FREQ_SLT == 8'b00001000) || (`SM1CLK_FREQ_SLT == 8'b01000000) || (`SM1CLK_FREQ_SLT == 8'b10000000);
|
||||
assign SM_SET[2] = (`SM1CLK_FREQ_SLT == 8'b00010000) || (`SM1CLK_FREQ_SLT == 8'b00100000) || (`SM1CLK_FREQ_SLT == 8'b01000000) || (`SM1CLK_FREQ_SLT == 8'b10000000);
|
||||
|
||||
// Logic for Sleep Mode
|
||||
// Sensor interrupt input is double ring to check for transtion from low to high
|
||||
// Once detected, the design will enable the sampling period
|
||||
assign sleepModeSet = sensorInterrupt_s2 && !sensorInterrupt_s3;
|
||||
always @(posedge Clock32KIn or posedge ResetIn)
|
||||
begin
|
||||
if (ResetIn)
|
||||
begin
|
||||
sensorInterrupt_s1 <= 0;
|
||||
sensorInterrupt_s2 <= 0;
|
||||
sensorInterrupt_s3 <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
sensorInterrupt_s1 <= (SensorInterruptIn ~^ IntInputLevel) && SleepMode;
|
||||
sensorInterrupt_s2 <= sensorInterrupt_s1;
|
||||
sensorInterrupt_s3 <= sensorInterrupt_s2;
|
||||
end
|
||||
end
|
||||
|
||||
assign sleepReset = ResetIn || sleepModeSet;
|
||||
always @(posedge SPI_SCLK or posedge sleepReset) begin
|
||||
if (sleepReset)
|
||||
begin
|
||||
SleepMode <= 1'b0;
|
||||
end
|
||||
else if ((RegAddrIn == `SleepControl) && RegWriteEnableIn)
|
||||
begin
|
||||
SleepMode <= RegDataIn[0];
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
always @(posedge SPI_SCLK or posedge ResetIn) begin
|
||||
if (ResetIn)
|
||||
begin
|
||||
IntInputLevel <= 1'b1;
|
||||
end
|
||||
else if ((RegAddrIn == `SleepControl) && RegWriteEnableIn)
|
||||
begin
|
||||
IntInputLevel <= RegDataIn[1];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,126 @@
|
|||
/***************************************************
|
||||
Vendor : QuickLogic Corp.
|
||||
Aurora Version : AU 1.0.0
|
||||
File Name : primtive_macros.v
|
||||
Author : Kishor Kumar
|
||||
Description : Verilog Netlist File (For Synthesis/Pre-Layout Simulation)
|
||||
*****************************************************/
|
||||
|
||||
/*-------------------------------------------------------------------------------
|
||||
MODULE NAME : ck_buff
|
||||
DESCRIPTION : Clock tree buffer
|
||||
--------------------------------------------------------------------------------*/
|
||||
`ifdef ck_buff
|
||||
`else
|
||||
`define ck_buff
|
||||
module ck_buff ( A , Q )/* synthesis black_box black_box_pad_pin = "A" */;
|
||||
input A/* synthesis syn_isclock=1 */;
|
||||
output Q;
|
||||
//pragma synthesis_off
|
||||
//pragma synthesis_on
|
||||
endmodule /* ck buff */
|
||||
`endif
|
||||
|
||||
/*-------------------------------------------------------------------------------
|
||||
MODULE NAME : gclkbuff
|
||||
DESCRIPTION : Global clock buffer
|
||||
--------------------------------------------------------------------------------*/
|
||||
`ifdef GCLKBUFF
|
||||
`else
|
||||
`define GCLKBUFF
|
||||
module GCLKBUFF ( A , Z )/* synthesis black_box */;
|
||||
input A;
|
||||
output Z;
|
||||
//pragma synthesis_off
|
||||
//pragma synthesis_on
|
||||
endmodule /* gclk buff */
|
||||
`endif
|
||||
|
||||
/*-------------------------------------------------------------------------------
|
||||
MODULE NAME : in_buff
|
||||
DESCRIPTION : Input buffer
|
||||
--------------------------------------------------------------------------------*/
|
||||
`ifdef in_buff
|
||||
`else
|
||||
`define in_buff
|
||||
module in_buff ( A , Q )/* synthesis black_box */;
|
||||
input A;
|
||||
output Q;
|
||||
//pragma synthesis_off
|
||||
//pragma synthesis_on
|
||||
endmodule /* in buff */
|
||||
`endif
|
||||
|
||||
/*-------------------------------------------------------------------------------
|
||||
MODULE NAME : out_buff
|
||||
DESCRIPTION : Output buffer
|
||||
--------------------------------------------------------------------------------*/
|
||||
`ifdef out_buff
|
||||
`else
|
||||
`define out_buff
|
||||
module out_buff ( A , Q )/* synthesis black_box */;
|
||||
input A;
|
||||
output Q;
|
||||
//pragma synthesis_off
|
||||
//pragma synthesis_on
|
||||
endmodule /* out buff */
|
||||
`endif
|
||||
|
||||
/*-------------------------------------------------------------------------------
|
||||
MODULE NAME : inv
|
||||
DESCRIPTION : Inverter
|
||||
--------------------------------------------------------------------------------*/
|
||||
`ifdef inv
|
||||
`else
|
||||
`define inv
|
||||
module inv ( A , Q )/* synthesis black_box */;
|
||||
input A;
|
||||
output Q;
|
||||
//pragma synthesis_off
|
||||
//pragma synthesis_on
|
||||
endmodule /*inverter*/
|
||||
`endif
|
||||
|
||||
/*-------------------------------------------------------------------------------
|
||||
MODULE NAME : buff
|
||||
DESCRIPTION : Buffer
|
||||
--------------------------------------------------------------------------------*/
|
||||
`ifdef buff
|
||||
`else
|
||||
`define buff
|
||||
module buff ( A , Q )/* synthesis black_box */;
|
||||
input A;
|
||||
output Q;
|
||||
//pragma synthesis_off
|
||||
//pragma synthesis_on
|
||||
endmodule /*buffer*/
|
||||
`endif
|
||||
|
||||
/*-------------------------------------------------------------------------------
|
||||
MODULE NAME : mux2x0
|
||||
DESCRIPTION : Basic Mux 2:1
|
||||
--------------------------------------------------------------------------------*/
|
||||
`ifdef mux2x0
|
||||
`else
|
||||
`define mux2x0
|
||||
module mux2x0 ( A , B, S, Q )/* synthesis black_box */;
|
||||
input A, B, S;
|
||||
output Q;
|
||||
//pragma synthesis_off
|
||||
//pragma synthesis_on
|
||||
endmodule /*mux2x0*/
|
||||
`endif
|
||||
|
||||
`ifdef LOGIC_Cell
|
||||
`else
|
||||
`define LOGIC_Cell
|
||||
module LOGIC_Cell (T0I0, T0I1, T0I2, T0I3, B0I0, B0I1, B0I2, B0I3,
|
||||
TB0S, Q0DI, CD0S, Q0EN, QST, QRT, QCK, QCKS, C0Z, Q0Z, B0Z)/* synthesis black_box */;
|
||||
input T0I0, T0I1, T0I2, T0I3, B0I0, B0I1, B0I2, B0I3;
|
||||
input TB0S, Q0DI, CD0S, Q0EN;
|
||||
input QST, QRT, QCK, QCKS;
|
||||
output C0Z, B0Z, Q0Z;
|
||||
//pragma synthesis_off
|
||||
//pragma synthesis_on
|
||||
endmodule /*LOGIC_Cell*/
|
||||
`endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,17 @@
|
|||
|
||||
`timescale 1ns / 1ns
|
||||
|
||||
module clock_buffer (
|
||||
input A,
|
||||
output Z
|
||||
);
|
||||
|
||||
|
||||
|
||||
GCLKBUFF gclkbuff_0 (.A(A), .Z(Z));
|
||||
//pragma attribute gclkbuff_0 ql_pack 1
|
||||
//pragma attribute gclkbuff_0 hierarchy preserve
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
`timescale 1ns / 1ns
|
||||
|
||||
|
||||
module dff_pre_clr (
|
||||
input CLK,
|
||||
input CLR,
|
||||
input D,
|
||||
input PRE,
|
||||
output Q
|
||||
);
|
||||
|
||||
dffpc dffpc_0 ( .CLK(CLK) , .CLR(CLR), .D(D), .PRE(PRE), .Q(Q) )/* synthesis black_box */;
|
||||
//pragma attribute dffpc_0 dont_touch true
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -0,0 +1,301 @@
|
|||
|
||||
/* ------------------------------------------------------------------
|
||||
ring_osc_adjust.v
|
||||
|
||||
Control logic to keep the ring oscillator's frequency within the
|
||||
desired range.
|
||||
|
||||
divider values from ClockDivider_rev2.pdf:
|
||||
|
||||
SEL sysclk_x2 sysclk
|
||||
--------------------------------
|
||||
000 ? ?
|
||||
001 2 4
|
||||
010 3 6
|
||||
011 4 8
|
||||
100 5 10
|
||||
101 6 12
|
||||
110 7 14
|
||||
111 8 16
|
||||
|
||||
------------------------------------------------------------------ */
|
||||
|
||||
`timescale 1ps/1ps
|
||||
|
||||
/*
|
||||
module ring_osc_adjust (
|
||||
input reset_i, // async reset
|
||||
input clk_ringosc_i, // the ring oscillator output divided by 2 (this is not clk_main)
|
||||
input clk_32khz_i, // 32.768KHz reference clock
|
||||
input enable_i, // enable, can be tied off externally or driven occasionally to force re-calibration
|
||||
output [2:0] div_sel_o // divider selection control for the ring oscillator divider circuit (in ASSP)
|
||||
);
|
||||
|
||||
reg clk32k_r1, clk32k_r2;
|
||||
reg clk32k_cycle_start;
|
||||
reg enable_32k_sync, enable_32k_sync_r1;
|
||||
reg enable_main_sync, enable_main_sync_r1, enable_main;
|
||||
reg [10:0] clk_ringosc_div2_cnt;
|
||||
reg [2:0] ring_osc_div, ring_osc_div_reg;
|
||||
|
||||
// divider SEL values
|
||||
localparam [2:0] DIV2_SEL = 3'b001;
|
||||
localparam [2:0] DIV3_SEL = 3'b010;
|
||||
localparam [2:0] DIV4_SEL = 3'b011;
|
||||
localparam [2:0] DIV5_SEL = 3'b100;
|
||||
localparam [2:0] DIV6_SEL = 3'b101;
|
||||
localparam [2:0] DIV7_SEL = 3'b110;
|
||||
localparam [2:0] DIV8_SEL = 3'b111;
|
||||
|
||||
// threshold values for each divider value.
|
||||
// These are the count values where each divider value will be applied.
|
||||
// Example: if there are 395 counts on clk_ringosc_div2 within a 32KHz clock period, the ring osc is divided by 5.
|
||||
// A divider of 5 means that sysclk_x2 = ring_osc/5, and sysclk = ring_osc/10.
|
||||
// Nomenclature:
|
||||
// ring_osc = ring oscillator raw clock (not accessible outside of ASSP)
|
||||
// ring_osc_div2 = ring oscillator divided by 2 (used for calibration)
|
||||
// sysclk_x2 = ring oscillator divided by SEL
|
||||
// sysclk = ring oscillator divided by SEL*2 (used as system clock A.K.A. FFE clock)
|
||||
// Assumptions:
|
||||
// Ring osc range: 25.2MHz - 53.2MHz (39.7ns to 18.8ns period)
|
||||
// I2C master will divide clk_main by 9 to produce SCL.
|
||||
// SCL freq cannot exceed 400KHz.
|
||||
// Guardband of 10% is added to allow for temperature/voltage variation, in case calibration is only done once at startup.
|
||||
// A smaller guardband can be used if calibration is performed periodically.
|
||||
localparam [10:0] DIV4_THRESHOLD = 11'd32; // (the threshold of 32 is arbitrary... just needs to be somewhat larger than 0)
|
||||
localparam [10:0] DIV5_THRESHOLD = 11'd395;
|
||||
localparam [10:0] DIV6_THRESHOLD = 11'd494;
|
||||
localparam [10:0] DIV7_THRESHOLD = 11'd595;
|
||||
localparam [10:0] DIV8_THRESHOLD = 11'd693;
|
||||
|
||||
|
||||
// synchronize the enable to clk32k (set this FF on the rising edge of enable_i,
|
||||
// clear it after one full 32KHz period has elapsed)
|
||||
always @(posedge enable_i or posedge clk_32khz_i)
|
||||
if (enable_i)
|
||||
enable_32k_sync <= 1'b1;
|
||||
else
|
||||
if (enable_32k_sync_r1)
|
||||
enable_32k_sync <= 1'b0;
|
||||
else
|
||||
enable_32k_sync <= enable_32k_sync;
|
||||
|
||||
always @(posedge clk_32khz_i)
|
||||
enable_32k_sync_r1 <= enable_32k_sync;
|
||||
|
||||
assign enable_32k = enable_32k_sync_r1;
|
||||
|
||||
|
||||
// detect rising edge on clk32khz
|
||||
always @(posedge clk_ringosc_i) begin
|
||||
if (!enable_i) begin
|
||||
clk32k_r1 <= 1'b0;
|
||||
clk32k_r2 <= 1'b0;
|
||||
clk32k_cycle_start <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
clk32k_r1 <= clk_32khz_i;
|
||||
clk32k_r2 <= clk32k_r1;
|
||||
clk32k_cycle_start <= clk32k_r1 && !clk32k_r2;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// synchronize the stretched enable to the main clk domain,
|
||||
// turn this enable off when clk32k_cycle_start is active
|
||||
always @(posedge clk_ringosc_i or posedge reset_i) begin
|
||||
if (reset_i) begin
|
||||
enable_main_sync <= 1'b0;
|
||||
enable_main_sync_r1 <= 1'b0;
|
||||
enable_main <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
enable_main_sync <= enable_32k;
|
||||
enable_main_sync_r1 <= enable_main_sync;
|
||||
case (enable_main)
|
||||
1'b0: if (clk32k_cycle_start && enable_main_sync_r1)
|
||||
enable_main <= 1'b1;
|
||||
else
|
||||
enable_main <= 1'b0;
|
||||
1'b1: if (clk32k_cycle_start && !enable_32k)
|
||||
enable_main <= 1'b0;
|
||||
else
|
||||
enable_main <= 1'b1;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// count # of clk_ringosc_div2 cycles per 32khz clock period
|
||||
always @(posedge clk_ringosc_i or posedge reset_i)
|
||||
if (reset_i)
|
||||
clk_ringosc_div2_cnt <= 0;
|
||||
else
|
||||
if (enable_main)
|
||||
if (clk32k_cycle_start)
|
||||
clk_ringosc_div2_cnt <= 0;
|
||||
else
|
||||
clk_ringosc_div2_cnt <= clk_ringosc_div2_cnt + 1;
|
||||
else
|
||||
clk_ringosc_div2_cnt <= 0;
|
||||
|
||||
|
||||
// set the ring_osc clock divider value
|
||||
// _div holds the temporary divider SEL valud
|
||||
// _div_reg gets assigned after a full 32KHz clock period
|
||||
always @(posedge clk_ringosc_i or posedge reset_i)
|
||||
if (reset_i) begin
|
||||
ring_osc_div <= 3'b111; // use the largest divide value by default
|
||||
ring_osc_div_reg <= 3'b111;
|
||||
end
|
||||
else begin
|
||||
if (enable_main)
|
||||
case (clk_ringosc_div2_cnt)
|
||||
DIV4_THRESHOLD: ring_osc_div <= DIV4_SEL;
|
||||
DIV5_THRESHOLD: ring_osc_div <= DIV5_SEL;
|
||||
DIV6_THRESHOLD: ring_osc_div <= DIV6_SEL;
|
||||
DIV7_THRESHOLD: ring_osc_div <= DIV7_SEL;
|
||||
DIV8_THRESHOLD: ring_osc_div <= DIV8_SEL;
|
||||
default: ring_osc_div <= ring_osc_div; // hold for all other values
|
||||
endcase
|
||||
else
|
||||
ring_osc_div <= ring_osc_div; // need to retain the old value when enable is off
|
||||
|
||||
if (clk32k_cycle_start)
|
||||
ring_osc_div_reg <= ring_osc_div;
|
||||
else
|
||||
ring_osc_div_reg <= ring_osc_div_reg;
|
||||
end
|
||||
|
||||
assign div_sel_o = ring_osc_div_reg;
|
||||
|
||||
|
||||
//// New Logic to produce CNT to system
|
||||
//// Detect transition of Calibration aneble from Low to Hi
|
||||
always @(posedge clk_32khz_i or posedge reset_i)
|
||||
begin
|
||||
if (reset_i) begin
|
||||
enable_r1 <= 1'b0;
|
||||
enable_r2 <= 1'b0;
|
||||
enable_r3 <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
enable_r1 <= enable_i;
|
||||
enable_r2 <= enable_r1;
|
||||
enable_r3 <= enable_r2;
|
||||
end
|
||||
end
|
||||
|
||||
// Generating enable for Clock Cnt circuit
|
||||
// Default is is 2 32KHz CLK period
|
||||
always @(posedge clk_32khz_i or posedge reset_i)
|
||||
begin
|
||||
if (reset_i)
|
||||
downCnt <= 2'b0;
|
||||
else
|
||||
if (enable_r2 && !enable_r3)
|
||||
downCnt <= 2'b11;
|
||||
else if (downCnt[1] || downCnt[0])
|
||||
downCnt <= downCnt - 1'b1;
|
||||
else
|
||||
downCnt <= downCnt;
|
||||
end
|
||||
|
||||
// Sync to ring osc clk
|
||||
always @(posedge clk_ringosc_i or posedge reset_i)
|
||||
if (reset_i)
|
||||
downCnt1_r1 <= 1'b0;
|
||||
downCnt1_r2 <= 1'b0;
|
||||
else
|
||||
downCnt1_r1 <= downCnt[1];
|
||||
downCnt1_r2 <= downCnt1_r1;
|
||||
|
||||
assign ringosccnt_reset = reset_i && !enable_i;
|
||||
// Counting # of ringosc cyces in two 32KHz clock
|
||||
always @(posedge clk_ringosc_i or posedge ringosccnt_reset)
|
||||
begin
|
||||
if (ringosccnt_reset)
|
||||
ringosc_2_cnt <= 16'b0;
|
||||
else if (downCnt1_r2)
|
||||
ringosc_2_cnt <= ringosc_2_cnt + 1'b0;
|
||||
else
|
||||
ringosc_2_cnt <= ringosc_2_cnt;
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
*/
|
||||
|
||||
module ring_osc_adjust (
|
||||
input reset_i, // async reset
|
||||
input clk_ringosc_i, // the ring oscillator output divided by 2 (this is not clk_main)
|
||||
input clk_32khz_i, // 32.768KHz reference clock
|
||||
input enable_i, // enable, can be tied off externally or driven occasionally to force re-calibration
|
||||
output [15:0] cal_val_o // divider selection control for the ring oscillator divider circuit (in ASSP)
|
||||
);
|
||||
|
||||
reg enable_r1, enable_r2, enable_r3;
|
||||
reg [2:0] downCnt;
|
||||
reg downCnt1_r1, downCnt1_r2;
|
||||
reg [15:0] ringosc_2_cnt;
|
||||
wire ringosccnt_reset;
|
||||
|
||||
//// New Logic to produce CNT to system
|
||||
//// Detect transition of Calibration aneble from Low to Hi
|
||||
always @(posedge clk_32khz_i or posedge reset_i)
|
||||
begin
|
||||
if (reset_i) begin
|
||||
enable_r1 <= 1'b0;
|
||||
enable_r2 <= 1'b0;
|
||||
enable_r3 <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
enable_r1 <= enable_i;
|
||||
enable_r2 <= enable_r1;
|
||||
enable_r3 <= enable_r2;
|
||||
end
|
||||
end
|
||||
|
||||
// Generating enable for Clock Cnt circuit
|
||||
// Default is is 2 32KHz CLK period
|
||||
always @(posedge clk_32khz_i or posedge reset_i)
|
||||
begin
|
||||
if (reset_i)
|
||||
downCnt <= 3'b0;
|
||||
else
|
||||
if (enable_r2 && !enable_r3)
|
||||
downCnt <= 3'b111;
|
||||
else if (downCnt != 3'b000)
|
||||
downCnt <= downCnt - 1'b1;
|
||||
else
|
||||
downCnt <= downCnt;
|
||||
end
|
||||
|
||||
// Sync to ring osc clk
|
||||
always @(posedge clk_ringosc_i or posedge reset_i)
|
||||
if (reset_i)
|
||||
begin
|
||||
downCnt1_r1 <= 1'b0;
|
||||
downCnt1_r2 <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
downCnt1_r1 <= downCnt[2];
|
||||
downCnt1_r2 <= downCnt1_r1;
|
||||
end
|
||||
|
||||
assign ringosccnt_reset = reset_i || !enable_i;
|
||||
// Counting # of ringosc cyces in two 32KHz clock
|
||||
always @(posedge clk_ringosc_i or posedge ringosccnt_reset)
|
||||
begin
|
||||
if (ringosccnt_reset)
|
||||
ringosc_2_cnt <= 16'b0;
|
||||
else if (downCnt1_r2)
|
||||
ringosc_2_cnt <= ringosc_2_cnt + 1'b1;
|
||||
else
|
||||
ringosc_2_cnt <= ringosc_2_cnt;
|
||||
end
|
||||
|
||||
assign cal_val_o = ringosc_2_cnt;
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,26 @@
|
|||
// -----------------------------------------------------------------------------
|
||||
// title : ulpsh_rtl_defines.v
|
||||
// project : ULP Sensor Hub
|
||||
// description : RTL defines
|
||||
// -----------------------------------------------------------------------------
|
||||
// copyright (c) 2014, QuickLogic Corporation
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Clock Circuit control defines
|
||||
`define OP_CLK_DIV 8'b01000000
|
||||
`define FFE1CLK_FREQ_SLT 8'b01000000
|
||||
`define SM1CLK_FREQ_SLT 8'b00100000
|
||||
|
||||
`ifdef SIMULATION
|
||||
`define OSC_SELECTION 1'b0
|
||||
`else
|
||||
`define OSC_SELECTION 1'b1
|
||||
`endif
|
||||
|
||||
`define ENABLE_FFE_F0_SINGLE_DM
|
||||
|
||||
`define ENABLE_FFE_F0_EXTENDED_DM
|
||||
|
||||
`define FFE_F0_SEG0_OFFSET 9'h095
|
||||
|
||||
`define ENABLE_FFE_F0_CM_SIZE_4K
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,162 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// cavlc_fsm ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// controls the cavlc parsing process ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - bin qiu, qiubin@opencores.org ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2011 Authors and OPENCORES.ORG ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from http://www.opencores.org/lgpl.shtml ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//2011-8-7 18:57 initial revision
|
||||
|
||||
`include "defines.v"
|
||||
|
||||
module cavlc_fsm
|
||||
(
|
||||
clk,
|
||||
rst_n,
|
||||
ena,
|
||||
start,
|
||||
max_coeff_num,
|
||||
TotalCoeff,
|
||||
TotalCoeff_comb,
|
||||
TrailingOnes,
|
||||
TrailingOnes_comb,
|
||||
ZeroLeft,
|
||||
state,
|
||||
i,
|
||||
idle,
|
||||
valid
|
||||
);
|
||||
//------------------------
|
||||
//ports
|
||||
//------------------------
|
||||
input clk;
|
||||
input rst_n;
|
||||
input ena;
|
||||
input start;
|
||||
|
||||
input [4:0] max_coeff_num;
|
||||
input [4:0] TotalCoeff;
|
||||
input [4:0] TotalCoeff_comb;
|
||||
input [1:0] TrailingOnes;
|
||||
input [1:0] TrailingOnes_comb;
|
||||
input [3:0] ZeroLeft;
|
||||
|
||||
output [7:0] state;
|
||||
output [3:0] i;
|
||||
output idle;
|
||||
output valid;
|
||||
|
||||
//------------------------
|
||||
//FFs
|
||||
//------------------------
|
||||
reg [7:0] state;
|
||||
reg [3:0] i;
|
||||
reg valid;
|
||||
|
||||
//------------------------
|
||||
//state & i & valid
|
||||
//------------------------
|
||||
always @(posedge clk or negedge rst_n)
|
||||
if (!rst_n) begin
|
||||
state <= `cavlc_idle_s;
|
||||
i <= 0;
|
||||
valid <= 0;
|
||||
end
|
||||
else if (ena)
|
||||
case(state)
|
||||
`cavlc_idle_s : begin
|
||||
if (start) begin
|
||||
state <= `cavlc_read_total_coeffs_s;
|
||||
valid <= 0;
|
||||
end
|
||||
else begin
|
||||
state <= `cavlc_idle_s;
|
||||
end
|
||||
end
|
||||
`cavlc_read_total_coeffs_s : begin
|
||||
i <= TotalCoeff_comb -1;
|
||||
if (TrailingOnes_comb > 0 && TotalCoeff_comb > 0)
|
||||
state <= `cavlc_read_t1s_flags_s;
|
||||
else if (TotalCoeff_comb > 0)
|
||||
state <= `cavlc_read_level_prefix_s;
|
||||
else begin
|
||||
state <= `cavlc_idle_s;
|
||||
valid <= 1;
|
||||
end
|
||||
end
|
||||
`cavlc_read_t1s_flags_s : begin
|
||||
if (TrailingOnes == TotalCoeff)
|
||||
state <= `cavlc_read_total_zeros_s;
|
||||
else begin
|
||||
state <= `cavlc_read_level_prefix_s;
|
||||
i <= i - TrailingOnes;
|
||||
end
|
||||
end
|
||||
`cavlc_read_level_prefix_s : begin
|
||||
state <= `cavlc_read_level_suffix_s;
|
||||
end
|
||||
`cavlc_read_level_suffix_s : begin
|
||||
state <= `cavlc_calc_level_s;
|
||||
end
|
||||
`cavlc_calc_level_s : begin
|
||||
if ( i == 0 && TotalCoeff < max_coeff_num)
|
||||
state <= `cavlc_read_total_zeros_s;
|
||||
else if (i == 0) begin
|
||||
state <= `cavlc_read_run_befores_s;
|
||||
i <= TotalCoeff - 1;
|
||||
end
|
||||
else begin
|
||||
state <= `cavlc_read_level_prefix_s;
|
||||
i <= i - 1;
|
||||
end
|
||||
end
|
||||
`cavlc_read_total_zeros_s : begin
|
||||
state <= `cavlc_read_run_befores_s;
|
||||
i <= TotalCoeff - 1;
|
||||
end
|
||||
`cavlc_read_run_befores_s : begin
|
||||
if (i == 0 || ZeroLeft == 0) begin
|
||||
state <= `cavlc_idle_s;
|
||||
valid <= 1;
|
||||
end
|
||||
else begin
|
||||
state <= `cavlc_read_run_befores_s;
|
||||
i <= i - 1;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
assign idle = state[`cavlc_idle_bit];
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// cavlc_len_gen ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// generate the number of bits to forward ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - bin qiu, qiubin@opencores.org ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2011 Authors and OPENCORES.ORG ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from http://www.opencores.org/lgpl.shtml ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//2011-8-7 20:19 initial revision
|
||||
|
||||
`include "defines.v"
|
||||
|
||||
module cavlc_len_gen
|
||||
(
|
||||
cavlc_state,
|
||||
len_read_total_coeffs_comb,
|
||||
len_read_levels_comb,
|
||||
len_read_total_zeros_comb,
|
||||
len_read_run_befores_comb,
|
||||
len_comb
|
||||
);
|
||||
//------------------------
|
||||
// ports
|
||||
//------------------------
|
||||
input [7:0] cavlc_state;
|
||||
input [4:0] len_read_total_coeffs_comb;
|
||||
input [4:0] len_read_levels_comb;
|
||||
input [3:0] len_read_total_zeros_comb;
|
||||
input [3:0] len_read_run_befores_comb;
|
||||
|
||||
output [4:0] len_comb;
|
||||
|
||||
//------------------------
|
||||
// regs
|
||||
//------------------------
|
||||
reg [4:0] len_comb; //number of bits comsumed by cavlc in a cycle
|
||||
|
||||
//------------------------
|
||||
// len_comb
|
||||
//------------------------
|
||||
always @ (*)
|
||||
case (1'b1) //synthesis parallel_case
|
||||
cavlc_state[`cavlc_read_total_coeffs_bit] : len_comb <= len_read_total_coeffs_comb;
|
||||
cavlc_state[`cavlc_read_t1s_flags_bit],
|
||||
cavlc_state[`cavlc_read_level_prefix_bit],
|
||||
cavlc_state[`cavlc_read_level_suffix_bit] : len_comb <= len_read_levels_comb;
|
||||
cavlc_state[`cavlc_read_total_zeros_bit] : len_comb <= len_read_total_zeros_comb;
|
||||
cavlc_state[`cavlc_read_run_befores_bit] : len_comb <= len_read_run_befores_comb;
|
||||
cavlc_state[`cavlc_calc_level_bit],
|
||||
cavlc_state[`cavlc_idle_bit] : len_comb <= 0;
|
||||
default : len_comb <= 'bx;
|
||||
endcase
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,400 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// cavlc_read_levels ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// decode levels for coeffs ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - bin qiu, qiubin@opencores.org ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2011 Authors and OPENCORES.ORG ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from http://www.opencores.org/lgpl.shtml ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//2011-8-6 initiial revision
|
||||
//2011-8-19 reverse the order of level
|
||||
|
||||
// include TrailingOnes
|
||||
|
||||
`include "defines.v"
|
||||
|
||||
module cavlc_read_levels (
|
||||
clk,
|
||||
rst_n,
|
||||
ena,
|
||||
t1s_sel,
|
||||
prefix_sel,
|
||||
suffix_sel,
|
||||
calc_sel,
|
||||
TrailingOnes,
|
||||
TotalCoeff,
|
||||
rbsp,
|
||||
i,
|
||||
level_0,
|
||||
level_1,
|
||||
level_2,
|
||||
level_3,
|
||||
level_4,
|
||||
level_5,
|
||||
level_6,
|
||||
level_7,
|
||||
level_8,
|
||||
level_9,
|
||||
level_10,
|
||||
level_11,
|
||||
level_12,
|
||||
level_13,
|
||||
level_14,
|
||||
level_15,
|
||||
len_comb
|
||||
);
|
||||
//------------------------
|
||||
// ports
|
||||
//------------------------
|
||||
input clk;
|
||||
input rst_n;
|
||||
|
||||
input ena;
|
||||
input t1s_sel;
|
||||
input prefix_sel;
|
||||
input suffix_sel;
|
||||
input calc_sel;
|
||||
|
||||
input [1:0] TrailingOnes;
|
||||
input [4:0] TotalCoeff;
|
||||
input [0:15] rbsp;
|
||||
input [3:0] i;
|
||||
|
||||
output [8:0] level_0;
|
||||
output [8:0] level_1;
|
||||
output [8:0] level_2;
|
||||
output [8:0] level_3;
|
||||
output [8:0] level_4;
|
||||
output [8:0] level_5;
|
||||
output [8:0] level_6;
|
||||
output [8:0] level_7;
|
||||
output [8:0] level_8;
|
||||
output [8:0] level_9;
|
||||
output [8:0] level_10;
|
||||
output [8:0] level_11;
|
||||
output [8:0] level_12;
|
||||
output [8:0] level_13;
|
||||
output [8:0] level_14;
|
||||
output [8:0] level_15;
|
||||
|
||||
output [4:0] len_comb;
|
||||
|
||||
//------------------------
|
||||
// regs
|
||||
//------------------------
|
||||
reg [0:15] rbsp_internal; // reduce toggle rate
|
||||
reg [3:0] level_prefix_comb;
|
||||
reg [8:0] level_suffix;
|
||||
reg [4:0] len_comb;
|
||||
|
||||
//------------------------
|
||||
// FFs
|
||||
//------------------------
|
||||
reg [3:0] level_prefix;
|
||||
reg [2:0] suffixLength; // range from 0 to 6
|
||||
reg [8:0] level;
|
||||
reg [8:0] level_abs;
|
||||
reg [8:0] level_code_tmp;
|
||||
reg [8:0] level_0, level_1, level_2, level_3, level_4, level_5, level_6, level_7;
|
||||
reg [8:0] level_8, level_9, level_10, level_11, level_12, level_13, level_14, level_15;
|
||||
|
||||
//------------------------
|
||||
// level_prefix_comb
|
||||
//------------------------
|
||||
always @(*)
|
||||
if ((t1s_sel || prefix_sel || suffix_sel)&& ena)
|
||||
rbsp_internal <= rbsp;
|
||||
else
|
||||
rbsp_internal <= 'hffff;
|
||||
|
||||
always @(*)
|
||||
if (rbsp_internal[0]) level_prefix_comb <= 0;
|
||||
else if (rbsp_internal[1]) level_prefix_comb <= 1;
|
||||
else if (rbsp_internal[2]) level_prefix_comb <= 2;
|
||||
else if (rbsp_internal[3]) level_prefix_comb <= 3;
|
||||
else if (rbsp_internal[4]) level_prefix_comb <= 4;
|
||||
else if (rbsp_internal[5]) level_prefix_comb <= 5;
|
||||
else if (rbsp_internal[6]) level_prefix_comb <= 6;
|
||||
else if (rbsp_internal[7]) level_prefix_comb <= 7;
|
||||
else if (rbsp_internal[8]) level_prefix_comb <= 8;
|
||||
else if (rbsp_internal[9]) level_prefix_comb <= 9;
|
||||
else if (rbsp_internal[10]) level_prefix_comb <= 10;
|
||||
else if (rbsp_internal[11]) level_prefix_comb <= 11;
|
||||
else if (rbsp_internal[12]) level_prefix_comb <= 12;
|
||||
else if (rbsp_internal[13]) level_prefix_comb <= 13;
|
||||
else if (rbsp_internal[14]) level_prefix_comb <= 14;
|
||||
else if (rbsp_internal[15]) level_prefix_comb <= 15;
|
||||
else level_prefix_comb <= 'bx;
|
||||
|
||||
|
||||
//------------------------
|
||||
// level_prefix
|
||||
//------------------------
|
||||
always @(posedge clk or negedge rst_n)
|
||||
if (!rst_n)
|
||||
level_prefix <= 0;
|
||||
else if (prefix_sel && ena)
|
||||
level_prefix <= level_prefix_comb;
|
||||
|
||||
//------------------------
|
||||
// suffixLength
|
||||
//------------------------
|
||||
wire first_level;
|
||||
assign first_level = (i == TotalCoeff - TrailingOnes - 1);
|
||||
|
||||
always @(posedge clk or negedge rst_n)
|
||||
if (!rst_n)
|
||||
suffixLength <= 0;
|
||||
else if (prefix_sel && ena) begin
|
||||
if (TotalCoeff > 10 && TrailingOnes < 3 && first_level ) //initialize suffixLength before proceeding first level_suffix
|
||||
suffixLength <= 1;
|
||||
else if (first_level)
|
||||
suffixLength <= 0;
|
||||
else if (suffixLength == 0 && level_abs > 2'd3)
|
||||
suffixLength <= 2;
|
||||
else if (suffixLength == 0)
|
||||
suffixLength <= 1;
|
||||
else if ( level_abs > (2'd3 << (suffixLength - 1'b1) ) && suffixLength < 6)
|
||||
suffixLength <= suffixLength + 1'b1;
|
||||
end
|
||||
|
||||
|
||||
//------------------------
|
||||
// level_suffix
|
||||
//------------------------
|
||||
always @(*)
|
||||
if (suffixLength > 0 && level_prefix <= 14)
|
||||
level_suffix <= {3'b0, rbsp_internal[0:5] >> (3'd6 - suffixLength)};
|
||||
else if (level_prefix == 14) //level_prefix == 14 && suffixLength == 0
|
||||
level_suffix <= {3'b0, rbsp_internal[0:3] };
|
||||
else if (level_prefix == 15)
|
||||
level_suffix <= rbsp_internal[3:11];
|
||||
else
|
||||
level_suffix <= 0;
|
||||
|
||||
//------------------------
|
||||
// level_code_tmp
|
||||
//------------------------
|
||||
always @(posedge clk or negedge rst_n)
|
||||
if (!rst_n) begin
|
||||
level_code_tmp <= 0;
|
||||
end
|
||||
else if (suffix_sel && ena) begin
|
||||
level_code_tmp <= (level_prefix << suffixLength) + level_suffix +
|
||||
((suffixLength == 0 && level_prefix == 15) ? 4'd15 : 0);
|
||||
end
|
||||
|
||||
|
||||
//------------------------
|
||||
// level
|
||||
//------------------------
|
||||
wire [2:0] tmp1;
|
||||
|
||||
assign tmp1 = (first_level && TrailingOnes < 3)? 2'd2 : 2'd0;
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
if (level_code_tmp % 2 == 0) begin
|
||||
level <= ( level_code_tmp + tmp1 + 2 ) >> 1;
|
||||
end
|
||||
else begin
|
||||
level <= (-level_code_tmp - tmp1 - 1 ) >> 1;
|
||||
end
|
||||
end
|
||||
|
||||
//------------------------
|
||||
// level_abs
|
||||
//------------------------
|
||||
wire level_abs_refresh;
|
||||
assign level_abs_refresh = calc_sel && ena;
|
||||
|
||||
always @(posedge clk or negedge rst_n)
|
||||
if (!rst_n) begin
|
||||
level_abs <= 0;
|
||||
end
|
||||
else if (level_abs_refresh) begin
|
||||
level_abs <= level[8] ? -level : level;
|
||||
end
|
||||
|
||||
//------------------------
|
||||
// level regfile
|
||||
//------------------------
|
||||
always @ (posedge clk or negedge rst_n)
|
||||
if (!rst_n) begin
|
||||
level_0 <= 0; level_1 <= 0; level_2 <= 0; level_3 <= 0;
|
||||
level_4 <= 0; level_5 <= 0; level_6 <= 0; level_7 <= 0;
|
||||
level_8 <= 0; level_9 <= 0; level_10<= 0; level_11<= 0;
|
||||
level_12<= 0; level_13<= 0; level_14<= 0; level_15<= 0;
|
||||
end
|
||||
else if (t1s_sel && ena)
|
||||
case (i)
|
||||
0 : level_0 <= rbsp_internal[0]? -1 : 1;
|
||||
1 : begin
|
||||
level_1 <= rbsp_internal[0]? -1 : 1;
|
||||
if (TrailingOnes[1])
|
||||
level_0 <= rbsp_internal[1]? -1 : 1;
|
||||
end
|
||||
2 : begin
|
||||
level_2 <= rbsp_internal[0]? -1 : 1;
|
||||
if (TrailingOnes[1])
|
||||
level_1 <= rbsp_internal[1]? -1 : 1;
|
||||
if (TrailingOnes == 3)
|
||||
level_0 <= rbsp_internal[2]? -1 : 1;
|
||||
end
|
||||
3 : begin
|
||||
level_3 <= rbsp_internal[0]? -1 : 1;
|
||||
if (TrailingOnes[1])
|
||||
level_2 <= rbsp_internal[1]? -1 : 1;
|
||||
if (TrailingOnes == 3)
|
||||
level_1 <= rbsp_internal[2]? -1 : 1;
|
||||
end
|
||||
4 : begin
|
||||
level_4 <= rbsp_internal[0]? -1 : 1;
|
||||
if (TrailingOnes[1])
|
||||
level_3 <= rbsp_internal[1]? -1 : 1;
|
||||
if (TrailingOnes == 3)
|
||||
level_2 <= rbsp_internal[2]? -1 : 1;
|
||||
end
|
||||
5 : begin
|
||||
level_5 <= rbsp_internal[0]? -1 : 1;
|
||||
if (TrailingOnes[1])
|
||||
level_4 <= rbsp_internal[1]? -1 : 1;
|
||||
if (TrailingOnes == 3)
|
||||
level_3 <= rbsp_internal[2]? -1 : 1;
|
||||
end
|
||||
6 : begin
|
||||
level_6 <= rbsp_internal[0]? -1 : 1;
|
||||
if (TrailingOnes[1])
|
||||
level_5 <= rbsp_internal[1]? -1 : 1;
|
||||
if (TrailingOnes == 3)
|
||||
level_4 <= rbsp_internal[2]? -1 : 1;
|
||||
end
|
||||
7 : begin
|
||||
level_7 <= rbsp_internal[0]? -1 : 1;
|
||||
if (TrailingOnes[1])
|
||||
level_6 <= rbsp_internal[1]? -1 : 1;
|
||||
if (TrailingOnes == 3)
|
||||
level_5 <= rbsp_internal[2]? -1 : 1;
|
||||
end
|
||||
8 : begin
|
||||
level_8 <= rbsp_internal[0]? -1 : 1;
|
||||
if (TrailingOnes[1])
|
||||
level_7 <= rbsp_internal[1]? -1 : 1;
|
||||
if (TrailingOnes == 3)
|
||||
level_6 <= rbsp_internal[2]? -1 : 1;
|
||||
end
|
||||
9 : begin
|
||||
level_9 <= rbsp_internal[0]? -1 : 1;
|
||||
if (TrailingOnes[1])
|
||||
level_8 <= rbsp_internal[1]? -1 : 1;
|
||||
if (TrailingOnes == 3)
|
||||
level_7 <= rbsp_internal[2]? -1 : 1;
|
||||
end
|
||||
10: begin
|
||||
level_10 <= rbsp_internal[0]? -1 : 1;
|
||||
if (TrailingOnes[1])
|
||||
level_9 <= rbsp_internal[1]? -1 : 1;
|
||||
if (TrailingOnes == 3)
|
||||
level_8 <= rbsp_internal[2]? -1 : 1;
|
||||
end
|
||||
11: begin
|
||||
level_11 <= rbsp_internal[0]? -1 : 1;
|
||||
if (TrailingOnes[1])
|
||||
level_10 <= rbsp_internal[1]? -1 : 1;
|
||||
if (TrailingOnes == 3)
|
||||
level_9 <= rbsp_internal[2]? -1 : 1;
|
||||
end
|
||||
12: begin
|
||||
level_12 <= rbsp_internal[0]? -1 : 1;
|
||||
if (TrailingOnes[1])
|
||||
level_11 <= rbsp_internal[1]? -1 : 1;
|
||||
if (TrailingOnes == 3)
|
||||
level_10 <= rbsp_internal[2]? -1 : 1;
|
||||
end
|
||||
13: begin
|
||||
level_13 <= rbsp_internal[0]? -1 : 1;
|
||||
if (TrailingOnes[1])
|
||||
level_12 <= rbsp_internal[1]? -1 : 1;
|
||||
if (TrailingOnes == 3)
|
||||
level_11 <= rbsp_internal[2]? -1 : 1;
|
||||
end
|
||||
14: begin
|
||||
level_14 <= rbsp_internal[0]? -1 : 1;
|
||||
if (TrailingOnes[1])
|
||||
level_13 <= rbsp_internal[1]? -1 : 1;
|
||||
if (TrailingOnes == 3)
|
||||
level_12 <= rbsp_internal[2]? -1 : 1;
|
||||
end
|
||||
15: begin
|
||||
level_15 <= rbsp_internal[0]? -1 : 1;
|
||||
if (TrailingOnes[1])
|
||||
level_14 <= rbsp_internal[1]? -1 : 1;
|
||||
if (TrailingOnes == 3)
|
||||
level_13 <= rbsp_internal[2]? -1 : 1;
|
||||
end
|
||||
endcase
|
||||
else if (calc_sel && ena)
|
||||
case (i)
|
||||
0 :level_0 <= level;
|
||||
1 :level_1 <= level;
|
||||
2 :level_2 <= level;
|
||||
3 :level_3 <= level;
|
||||
4 :level_4 <= level;
|
||||
5 :level_5 <= level;
|
||||
6 :level_6 <= level;
|
||||
7 :level_7 <= level;
|
||||
8 :level_8 <= level;
|
||||
9 :level_9 <= level;
|
||||
10:level_10<= level;
|
||||
11:level_11<= level;
|
||||
12:level_12<= level;
|
||||
13:level_13<= level;
|
||||
14:level_14<= level;
|
||||
15:level_15<= level;
|
||||
endcase
|
||||
|
||||
always @(*)
|
||||
if(t1s_sel)
|
||||
len_comb <= TrailingOnes;
|
||||
else if(prefix_sel)
|
||||
len_comb <= level_prefix_comb + 1;
|
||||
else if(suffix_sel && suffixLength > 0 && level_prefix <= 14)
|
||||
len_comb <= suffixLength;
|
||||
else if(suffix_sel && level_prefix == 14)
|
||||
len_comb <= 4;
|
||||
else if(suffix_sel && level_prefix == 15)
|
||||
len_comb <= 12;
|
||||
else
|
||||
len_comb <= 0;
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,368 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// cavlc_read_run_befores ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// decode runs and combine them with levels ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - bin qiu, qiubin@opencores.org ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2011 Authors and OPENCORES.ORG ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from http://www.opencores.org/lgpl.shtml ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//2011-8-16 initiial revision
|
||||
|
||||
`include "defines.v"
|
||||
|
||||
module cavlc_read_run_befores
|
||||
(
|
||||
clk,
|
||||
rst_n,
|
||||
ena,
|
||||
sel,
|
||||
clr,
|
||||
ZeroLeft_init,
|
||||
|
||||
rbsp,
|
||||
i,
|
||||
TotalZeros_comb,
|
||||
|
||||
level_0,
|
||||
level_1,
|
||||
level_2,
|
||||
level_3,
|
||||
level_4,
|
||||
level_5,
|
||||
level_6,
|
||||
level_7,
|
||||
level_8,
|
||||
level_9,
|
||||
level_10,
|
||||
level_11,
|
||||
level_12,
|
||||
level_13,
|
||||
level_14,
|
||||
level_15,
|
||||
|
||||
coeff_0,
|
||||
coeff_1,
|
||||
coeff_2,
|
||||
coeff_3,
|
||||
coeff_4,
|
||||
coeff_5,
|
||||
coeff_6,
|
||||
coeff_7,
|
||||
coeff_8,
|
||||
coeff_9,
|
||||
coeff_10,
|
||||
coeff_11,
|
||||
coeff_12,
|
||||
coeff_13,
|
||||
coeff_14,
|
||||
coeff_15,
|
||||
ZeroLeft,
|
||||
len_comb
|
||||
);
|
||||
//----------------------
|
||||
//ports
|
||||
//----------------------
|
||||
input clk;
|
||||
input rst_n;
|
||||
input ena;
|
||||
input sel;
|
||||
input clr;
|
||||
input ZeroLeft_init;
|
||||
|
||||
input [0:10] rbsp;
|
||||
input [3:0] i; //range from TotalCoeff-1 to 0
|
||||
input [3:0] TotalZeros_comb;
|
||||
|
||||
input [8:0] level_0;
|
||||
input [8:0] level_1;
|
||||
input [8:0] level_2;
|
||||
input [8:0] level_3;
|
||||
input [8:0] level_4;
|
||||
input [8:0] level_5;
|
||||
input [8:0] level_6;
|
||||
input [8:0] level_7;
|
||||
input [8:0] level_8;
|
||||
input [8:0] level_9;
|
||||
input [8:0] level_10;
|
||||
input [8:0] level_11;
|
||||
input [8:0] level_12;
|
||||
input [8:0] level_13;
|
||||
input [8:0] level_14;
|
||||
input [8:0] level_15;
|
||||
|
||||
output [8:0] coeff_0;
|
||||
output [8:0] coeff_1;
|
||||
output [8:0] coeff_2;
|
||||
output [8:0] coeff_3;
|
||||
output [8:0] coeff_4;
|
||||
output [8:0] coeff_5;
|
||||
output [8:0] coeff_6;
|
||||
output [8:0] coeff_7;
|
||||
output [8:0] coeff_8;
|
||||
output [8:0] coeff_9;
|
||||
output [8:0] coeff_10;
|
||||
output [8:0] coeff_11;
|
||||
output [8:0] coeff_12;
|
||||
output [8:0] coeff_13;
|
||||
output [8:0] coeff_14;
|
||||
output [8:0] coeff_15;
|
||||
|
||||
output [3:0] ZeroLeft;
|
||||
|
||||
output [3:0] len_comb;
|
||||
|
||||
//----------------------
|
||||
//regs
|
||||
//----------------------
|
||||
reg [3:0] run;
|
||||
reg [3:0] len;
|
||||
reg [8:0] coeff;
|
||||
|
||||
|
||||
reg [3:0] len_comb;
|
||||
|
||||
//----------------------
|
||||
//FFs
|
||||
//----------------------
|
||||
reg [3:0] ZeroLeft;
|
||||
|
||||
reg [8:0] coeff_0;
|
||||
reg [8:0] coeff_1;
|
||||
reg [8:0] coeff_2;
|
||||
reg [8:0] coeff_3;
|
||||
reg [8:0] coeff_4;
|
||||
reg [8:0] coeff_5;
|
||||
reg [8:0] coeff_6;
|
||||
reg [8:0] coeff_7;
|
||||
reg [8:0] coeff_8;
|
||||
reg [8:0] coeff_9;
|
||||
reg [8:0] coeff_10;
|
||||
reg [8:0] coeff_11;
|
||||
reg [8:0] coeff_12;
|
||||
reg [8:0] coeff_13;
|
||||
reg [8:0] coeff_14;
|
||||
reg [8:0] coeff_15;
|
||||
|
||||
//----------------------
|
||||
//run & len
|
||||
//----------------------
|
||||
always @(rbsp or ZeroLeft or ena or sel)
|
||||
if (ena && sel)
|
||||
case(ZeroLeft)
|
||||
0 : begin len <= 0; run <= 0; end
|
||||
1 : begin len <= 1; run <= rbsp[0]? 0:1; end
|
||||
2 : begin if (rbsp[0]) begin
|
||||
run <= 0;
|
||||
len <= 1;
|
||||
end
|
||||
else if (rbsp[1]) begin
|
||||
run <= 1;
|
||||
len <= 2;
|
||||
end
|
||||
else begin
|
||||
run <= 2;
|
||||
len <= 2;
|
||||
end
|
||||
end
|
||||
3 : begin
|
||||
run <= 3 - rbsp[0:1];
|
||||
len <= 2;
|
||||
end
|
||||
4 : begin
|
||||
if (rbsp[0:1] != 0) begin
|
||||
run <= 3 - rbsp[0:1];
|
||||
len <= 2;
|
||||
end
|
||||
else begin
|
||||
run <= rbsp[2]? 3:4;
|
||||
len <= 3;
|
||||
end
|
||||
end
|
||||
5 : begin
|
||||
if (rbsp[0]) begin
|
||||
run <= rbsp[1]? 0:1;
|
||||
len <= 2;
|
||||
end
|
||||
else if (rbsp[1]) begin
|
||||
run <= rbsp[2]? 2:3;
|
||||
len <= 3;
|
||||
end
|
||||
else begin
|
||||
run <= rbsp[2]? 4:5;
|
||||
len <= 3;
|
||||
end
|
||||
end
|
||||
6 : begin
|
||||
if (rbsp[0:1] == 2'b11) begin
|
||||
run <= 0;
|
||||
len <= 2;
|
||||
end
|
||||
else begin
|
||||
len <= 3;
|
||||
case(rbsp[0:2])
|
||||
3'b000 : run <= 1;
|
||||
3'b001 : run <= 2;
|
||||
3'b011 : run <= 3;
|
||||
3'b010 : run <= 4;
|
||||
3'b101 : run <= 5;
|
||||
default: run <= 6;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
default : begin
|
||||
if (rbsp[0:2] != 0) begin
|
||||
run <= 7 - rbsp[0:2];
|
||||
len <= 3;
|
||||
end
|
||||
else begin
|
||||
case (1'b1)
|
||||
rbsp[3] : begin run <= 7; len <= 4; end
|
||||
rbsp[4] : begin run <= 8; len <= 5; end
|
||||
rbsp[5] : begin run <= 9; len <= 6; end
|
||||
rbsp[6] : begin run <= 10; len <= 7; end
|
||||
rbsp[7] : begin run <= 11; len <= 8; end
|
||||
rbsp[8] : begin run <= 12; len <= 9; end
|
||||
rbsp[9] : begin run <= 13; len <= 10;end
|
||||
rbsp[10]: begin run <= 14; len <= 11;end
|
||||
default : begin run <= 'bx; len <='bx;end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
endcase
|
||||
else begin
|
||||
len <= 0;
|
||||
run <= 0;
|
||||
end
|
||||
|
||||
//----------------------
|
||||
//len_comb
|
||||
//----------------------
|
||||
always @(*)
|
||||
if (i > 0)
|
||||
len_comb <= len;
|
||||
else
|
||||
len_comb <= 0;
|
||||
|
||||
|
||||
//----------------------
|
||||
//ZeroLeft
|
||||
//----------------------
|
||||
always @(posedge clk or negedge rst_n)
|
||||
if (!rst_n)
|
||||
ZeroLeft <= 0;
|
||||
else if (ena && clr) //in case TotalCoeff >= max_coeff_num
|
||||
ZeroLeft <= 0;
|
||||
else if (ena && ZeroLeft_init)
|
||||
ZeroLeft <= TotalZeros_comb;
|
||||
else if (ena && sel )//if ZeroLeft == 0, run will be 0
|
||||
ZeroLeft <= ZeroLeft - run;
|
||||
|
||||
//----------------------
|
||||
//coeff
|
||||
//----------------------
|
||||
always @(*)
|
||||
if (ena && sel)
|
||||
case (i)
|
||||
0 :coeff <= level_0;
|
||||
1 :coeff <= level_1;
|
||||
2 :coeff <= level_2;
|
||||
3 :coeff <= level_3;
|
||||
4 :coeff <= level_4;
|
||||
5 :coeff <= level_5;
|
||||
6 :coeff <= level_6;
|
||||
7 :coeff <= level_7;
|
||||
8 :coeff <= level_8;
|
||||
9 :coeff <= level_9;
|
||||
10:coeff <= level_10;
|
||||
11:coeff <= level_11;
|
||||
12:coeff <= level_12;
|
||||
13:coeff <= level_13;
|
||||
14:coeff <= level_14;
|
||||
15:coeff <= level_15;
|
||||
endcase
|
||||
else
|
||||
coeff <= 0;
|
||||
|
||||
//----------------------
|
||||
//coeff_0 to coeff_15
|
||||
//----------------------
|
||||
always @(posedge clk or negedge rst_n)
|
||||
if (!rst_n) begin
|
||||
coeff_0 <= 0; coeff_1 <= 0; coeff_2 <= 0; coeff_3 <= 0;
|
||||
coeff_4 <= 0; coeff_5 <= 0; coeff_6 <= 0; coeff_7 <= 0;
|
||||
coeff_8 <= 0; coeff_9 <= 0; coeff_10<= 0; coeff_11<= 0;
|
||||
coeff_12<= 0; coeff_13<= 0; coeff_14<= 0; coeff_15<= 0;
|
||||
end
|
||||
else if (ena && clr) begin
|
||||
coeff_0 <= 0; coeff_1 <= 0; coeff_2 <= 0; coeff_3 <= 0;
|
||||
coeff_4 <= 0; coeff_5 <= 0; coeff_6 <= 0; coeff_7 <= 0;
|
||||
coeff_8 <= 0; coeff_9 <= 0; coeff_10<= 0; coeff_11<= 0;
|
||||
coeff_12<= 0; coeff_13<= 0; coeff_14<= 0; coeff_15<= 0;
|
||||
end
|
||||
else if (ena && sel && ZeroLeft > 0)
|
||||
case (ZeroLeft+i)
|
||||
1 :coeff_1 <= coeff;
|
||||
2 :coeff_2 <= coeff;
|
||||
3 :coeff_3 <= coeff;
|
||||
4 :coeff_4 <= coeff;
|
||||
5 :coeff_5 <= coeff;
|
||||
6 :coeff_6 <= coeff;
|
||||
7 :coeff_7 <= coeff;
|
||||
8 :coeff_8 <= coeff;
|
||||
9 :coeff_9 <= coeff;
|
||||
10:coeff_10 <= coeff;
|
||||
11:coeff_11 <= coeff;
|
||||
12:coeff_12 <= coeff;
|
||||
13:coeff_13 <= coeff;
|
||||
14:coeff_14 <= coeff;
|
||||
default:
|
||||
coeff_15 <= coeff;
|
||||
endcase
|
||||
else if (ena && sel) begin
|
||||
if (i >= 0) coeff_0 <= level_0;
|
||||
if (i >= 1) coeff_1 <= level_1;
|
||||
if (i >= 2) coeff_2 <= level_2;
|
||||
if (i >= 3) coeff_3 <= level_3;
|
||||
if (i >= 4) coeff_4 <= level_4;
|
||||
if (i >= 5) coeff_5 <= level_5;
|
||||
if (i >= 6) coeff_6 <= level_6;
|
||||
if (i >= 7) coeff_7 <= level_7;
|
||||
if (i >= 8) coeff_8 <= level_8;
|
||||
if (i >= 9) coeff_9 <= level_9;
|
||||
if (i >= 10)coeff_10 <= level_10;
|
||||
if (i >= 11)coeff_11 <= level_11;
|
||||
if (i >= 12)coeff_12 <= level_12;
|
||||
if (i >= 13)coeff_13 <= level_13;
|
||||
if (i >= 14)coeff_14 <= level_14;
|
||||
if (i == 15)coeff_15 <= level_15;
|
||||
end
|
||||
endmodule
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,716 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// cavlc_read_total_zeros ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// decode total_zeros ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - bin qiu, qiubin@opencores.org ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2011 Authors and OPENCORES.ORG ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from http://www.opencores.org/lgpl.shtml ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//2011-8-14 initial version
|
||||
|
||||
`include "defines.v"
|
||||
|
||||
module cavlc_read_total_zeros
|
||||
(
|
||||
ena,
|
||||
sel,
|
||||
chroma_DC_sel,
|
||||
rbsp,
|
||||
TotalCoeff,
|
||||
TotalZeros_comb,
|
||||
len_comb
|
||||
);
|
||||
//------------------------
|
||||
//ports
|
||||
//------------------------
|
||||
input ena;
|
||||
input sel;
|
||||
input chroma_DC_sel;
|
||||
input [0:8] rbsp;
|
||||
input [3:0] TotalCoeff;
|
||||
|
||||
output [3:0] TotalZeros_comb;
|
||||
output [3:0] len_comb;
|
||||
|
||||
//-------------------------
|
||||
//rregs
|
||||
//-------------------------
|
||||
reg [3:0] TotalZeros_comb; //TotalZeros will be saved as ZeroLeft in module cavlc_read_run_befores
|
||||
reg [3:0] len_comb;
|
||||
|
||||
|
||||
//for chroma_DC
|
||||
reg [0:2] rbsp_chroma_DC;
|
||||
reg [1:0] TotalZeros_chroma_DC;
|
||||
reg [1:0] len_chroma_DC;
|
||||
|
||||
//for TotalCoeff <= 3
|
||||
reg [0:8] rbsp_LE3;
|
||||
reg [3:0] TotalZeros_LE3;
|
||||
reg [3:0] len_LE3;
|
||||
|
||||
//for TotalCoeff > 3
|
||||
reg [0:5] rbsp_G3;
|
||||
reg [3:0] TotalZeros_G3;
|
||||
reg [2:0] len_G3;
|
||||
|
||||
|
||||
//----------------------------------------
|
||||
//input mux
|
||||
//----------------------------------------
|
||||
always @(*)
|
||||
if (ena && sel && chroma_DC_sel) begin
|
||||
rbsp_chroma_DC <= rbsp[0:2];
|
||||
rbsp_LE3 <= 'hffff;
|
||||
rbsp_G3 <= 'hffff;
|
||||
end
|
||||
else if (ena && sel && TotalCoeff[3:2] == 2'b00) begin
|
||||
rbsp_chroma_DC <= 'hffff;
|
||||
rbsp_LE3 <= rbsp[0:8];
|
||||
rbsp_G3 <= 'hffff;
|
||||
end
|
||||
else if (ena && sel)begin
|
||||
rbsp_chroma_DC <= 'hffff;
|
||||
rbsp_LE3 <= 'hffff;
|
||||
rbsp_G3 <= rbsp[0:5];
|
||||
end
|
||||
else begin
|
||||
rbsp_chroma_DC <= 'hffff;
|
||||
rbsp_LE3 <= 'hffff;
|
||||
rbsp_G3 <= 'hffff;
|
||||
end
|
||||
|
||||
//----------------------------------------
|
||||
//TotalZeros_chroma_DC & len_chroma_DC
|
||||
//----------------------------------------
|
||||
always @(*)
|
||||
if ( TotalCoeff == 1 && rbsp_chroma_DC[0] ) begin
|
||||
TotalZeros_chroma_DC <= 0;
|
||||
len_chroma_DC <= 1;
|
||||
end
|
||||
else if ( TotalCoeff == 1 && rbsp_chroma_DC[1] ) begin
|
||||
TotalZeros_chroma_DC <= 1;
|
||||
len_chroma_DC <= 2;
|
||||
end
|
||||
else if ( TotalCoeff == 1 && rbsp_chroma_DC[2] ) begin
|
||||
TotalZeros_chroma_DC <= 2;
|
||||
len_chroma_DC <= 3;
|
||||
end
|
||||
else if ( TotalCoeff == 1 ) begin
|
||||
TotalZeros_chroma_DC <= 3;
|
||||
len_chroma_DC <= 3;
|
||||
end
|
||||
else if ( TotalCoeff == 2 && rbsp_chroma_DC[0] ) begin
|
||||
TotalZeros_chroma_DC <= 0;
|
||||
len_chroma_DC <= 1;
|
||||
end
|
||||
else if ( TotalCoeff == 2 && rbsp_chroma_DC[1] ) begin
|
||||
TotalZeros_chroma_DC <= 1;
|
||||
len_chroma_DC <= 2;
|
||||
end
|
||||
else if ( TotalCoeff == 2 ) begin
|
||||
TotalZeros_chroma_DC <= 2;
|
||||
len_chroma_DC <= 2;
|
||||
end
|
||||
else if ( rbsp_chroma_DC[0] ) begin
|
||||
TotalZeros_chroma_DC <= 0;
|
||||
len_chroma_DC <= 1;
|
||||
end
|
||||
else begin
|
||||
TotalZeros_chroma_DC <= 1;
|
||||
len_chroma_DC <= 1;
|
||||
end
|
||||
|
||||
|
||||
//---------------------------------
|
||||
//TotalZeros_LE3 & len_LE3
|
||||
//---------------------------------
|
||||
always @(rbsp_LE3 or TotalCoeff)
|
||||
case (TotalCoeff[1:0])
|
||||
1 :begin
|
||||
case(1'b1)
|
||||
rbsp_LE3[0] : begin
|
||||
TotalZeros_LE3 <= 0;
|
||||
len_LE3 <= 1;
|
||||
end
|
||||
rbsp_LE3[1] : begin
|
||||
len_LE3 <= 3;
|
||||
if (rbsp_LE3[2])
|
||||
TotalZeros_LE3 <= 1;
|
||||
else
|
||||
TotalZeros_LE3 <= 2;
|
||||
end
|
||||
rbsp_LE3[2] : begin
|
||||
len_LE3 <= 4;
|
||||
if (rbsp_LE3[3])
|
||||
TotalZeros_LE3 <= 3;
|
||||
else
|
||||
TotalZeros_LE3 <= 4;
|
||||
end
|
||||
rbsp_LE3[3] : begin
|
||||
len_LE3 <= 5;
|
||||
if (rbsp_LE3[4])
|
||||
TotalZeros_LE3 <= 5;
|
||||
else
|
||||
TotalZeros_LE3 <= 6;
|
||||
end
|
||||
rbsp_LE3[4] : begin
|
||||
len_LE3 <= 6;
|
||||
if (rbsp_LE3[5])
|
||||
TotalZeros_LE3 <= 7;
|
||||
else
|
||||
TotalZeros_LE3 <= 8;
|
||||
end
|
||||
rbsp_LE3[5] : begin
|
||||
len_LE3 <= 7;
|
||||
if (rbsp_LE3[6])
|
||||
TotalZeros_LE3 <= 9;
|
||||
else
|
||||
TotalZeros_LE3 <= 10;
|
||||
end
|
||||
rbsp_LE3[6] : begin
|
||||
len_LE3 <= 8;
|
||||
if (rbsp_LE3[7])
|
||||
TotalZeros_LE3 <= 11;
|
||||
else
|
||||
TotalZeros_LE3 <= 12;
|
||||
end
|
||||
rbsp_LE3[7] : begin
|
||||
len_LE3 <= 9;
|
||||
if (rbsp_LE3[8])
|
||||
TotalZeros_LE3 <= 13;
|
||||
else
|
||||
TotalZeros_LE3 <= 14;
|
||||
end
|
||||
default : begin
|
||||
len_LE3 <= 9;
|
||||
TotalZeros_LE3 <= 15;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
2 : begin
|
||||
case(1'b1)
|
||||
rbsp_LE3[0] : begin
|
||||
len_LE3 <= 3;
|
||||
case(rbsp_LE3[1:2])
|
||||
'b11 : TotalZeros_LE3 <= 0;
|
||||
'b10 : TotalZeros_LE3 <= 1;
|
||||
'b01 : TotalZeros_LE3 <= 2;
|
||||
'b00 : TotalZeros_LE3 <= 3;
|
||||
endcase
|
||||
end
|
||||
rbsp_LE3[1] : begin
|
||||
if (rbsp_LE3[2]) begin
|
||||
TotalZeros_LE3 <= 4;
|
||||
len_LE3 <= 3;
|
||||
end
|
||||
else begin
|
||||
len_LE3 <= 4;
|
||||
if (rbsp_LE3[3])
|
||||
TotalZeros_LE3 <= 5;
|
||||
else
|
||||
TotalZeros_LE3 <= 6;
|
||||
end
|
||||
end
|
||||
rbsp_LE3[2] : begin
|
||||
len_LE3 <= 4;
|
||||
if (rbsp_LE3[3])
|
||||
TotalZeros_LE3 <= 7;
|
||||
else
|
||||
TotalZeros_LE3 <= 8;
|
||||
end
|
||||
rbsp_LE3[3] : begin
|
||||
len_LE3 <= 5;
|
||||
if (rbsp_LE3[4])
|
||||
TotalZeros_LE3 <= 9;
|
||||
else
|
||||
TotalZeros_LE3 <= 10;
|
||||
end
|
||||
default : begin
|
||||
len_LE3 <= 6;
|
||||
case(rbsp_LE3[4:5])
|
||||
'b11 : TotalZeros_LE3 <= 11;
|
||||
'b10 : TotalZeros_LE3 <= 12;
|
||||
'b01 : TotalZeros_LE3 <= 13;
|
||||
'b00 : TotalZeros_LE3 <= 14;
|
||||
endcase
|
||||
end
|
||||
endcase
|
||||
end
|
||||
3 : begin
|
||||
case(1'b1)
|
||||
rbsp_LE3[0] : begin
|
||||
len_LE3 <= 3;
|
||||
case(rbsp_LE3[1:2])
|
||||
'b11 : TotalZeros_LE3 <= 1;
|
||||
'b10 : TotalZeros_LE3 <= 2;
|
||||
'b01 : TotalZeros_LE3 <= 3;
|
||||
'b00 : TotalZeros_LE3 <= 6;
|
||||
endcase
|
||||
end
|
||||
rbsp_LE3[1] : begin
|
||||
if (rbsp_LE3[2]) begin
|
||||
TotalZeros_LE3 <= 7;
|
||||
len_LE3 <= 3;
|
||||
end
|
||||
else begin
|
||||
len_LE3 <= 4;
|
||||
if (rbsp_LE3[3])
|
||||
TotalZeros_LE3 <= 0;
|
||||
else
|
||||
TotalZeros_LE3 <= 4;
|
||||
end
|
||||
end
|
||||
rbsp_LE3[2] : begin
|
||||
len_LE3 <= 4;
|
||||
if (rbsp_LE3[3])
|
||||
TotalZeros_LE3 <= 5;
|
||||
else
|
||||
TotalZeros_LE3 <= 8;
|
||||
end
|
||||
rbsp_LE3[3] : begin
|
||||
len_LE3 <= 5;
|
||||
if (rbsp_LE3[4])
|
||||
TotalZeros_LE3 <= 9;
|
||||
else
|
||||
TotalZeros_LE3 <= 10;
|
||||
end
|
||||
rbsp_LE3[4] : begin
|
||||
len_LE3 <= 5;
|
||||
TotalZeros_LE3 <= 12;
|
||||
end
|
||||
default : begin
|
||||
len_LE3 <= 6;
|
||||
if(rbsp_LE3[5])
|
||||
TotalZeros_LE3 <= 11;
|
||||
else
|
||||
TotalZeros_LE3 <= 13;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
default : begin
|
||||
len_LE3 <= 'bx;
|
||||
TotalZeros_LE3 <= 'bx;
|
||||
end
|
||||
endcase
|
||||
|
||||
//---------------------------------
|
||||
//TotalZeros_G3 & len_G3
|
||||
//---------------------------------
|
||||
always @(rbsp_G3 or TotalCoeff)
|
||||
case (TotalCoeff)
|
||||
4 : begin
|
||||
case(1'b1)
|
||||
rbsp_G3[0] : begin
|
||||
len_G3 <= 3;
|
||||
case(rbsp_G3[1:2])
|
||||
'b11 : TotalZeros_G3 <= 1;
|
||||
'b10 : TotalZeros_G3 <= 4;
|
||||
'b01 : TotalZeros_G3 <= 5;
|
||||
'b00 : TotalZeros_G3 <= 6;
|
||||
endcase
|
||||
end
|
||||
rbsp_G3[1] : begin
|
||||
if (rbsp_G3[2]) begin
|
||||
TotalZeros_G3 <= 8;
|
||||
len_G3 <= 3;
|
||||
end
|
||||
else begin
|
||||
len_G3 <= 4;
|
||||
if (rbsp_G3[3])
|
||||
TotalZeros_G3 <= 2;
|
||||
else
|
||||
TotalZeros_G3 <= 3;
|
||||
end
|
||||
end
|
||||
rbsp_G3[2] : begin
|
||||
len_G3 <= 4;
|
||||
if (rbsp_G3[3])
|
||||
TotalZeros_G3 <= 7;
|
||||
else
|
||||
TotalZeros_G3 <= 9;
|
||||
end
|
||||
default : begin
|
||||
len_G3 <= 5;
|
||||
case(rbsp_G3[3:4])
|
||||
'b11 : TotalZeros_G3 <= 0;
|
||||
'b10 : TotalZeros_G3 <= 10;
|
||||
'b01 : TotalZeros_G3 <= 11;
|
||||
'b00 : TotalZeros_G3 <= 12;
|
||||
endcase
|
||||
end
|
||||
endcase
|
||||
end
|
||||
5 :begin
|
||||
case(1'b1)
|
||||
rbsp_G3[0] : begin
|
||||
len_G3 <= 3;
|
||||
case(rbsp_G3[1:2])
|
||||
'b11 : TotalZeros_G3 <= 3;
|
||||
'b10 : TotalZeros_G3 <= 4;
|
||||
'b01 : TotalZeros_G3 <= 5;
|
||||
'b00 : TotalZeros_G3 <= 6;
|
||||
endcase
|
||||
end
|
||||
rbsp_G3[1] : begin
|
||||
if (rbsp_G3[2]) begin
|
||||
TotalZeros_G3 <= 7;
|
||||
len_G3 <= 3;
|
||||
end
|
||||
else begin
|
||||
len_G3 <= 4;
|
||||
if (rbsp_G3[3])
|
||||
TotalZeros_G3 <= 0;
|
||||
else
|
||||
TotalZeros_G3 <= 1;
|
||||
end
|
||||
end
|
||||
rbsp_G3[2] : begin
|
||||
len_G3 <= 4;
|
||||
if (rbsp_G3[3])
|
||||
TotalZeros_G3 <= 2;
|
||||
else
|
||||
TotalZeros_G3 <= 8;
|
||||
end
|
||||
rbsp_G3[3] : begin
|
||||
len_G3 <= 4;
|
||||
TotalZeros_G3 <= 10;
|
||||
end
|
||||
default : begin
|
||||
len_G3 <= 5;
|
||||
if (rbsp_G3[4])
|
||||
TotalZeros_G3 <= 9;
|
||||
else
|
||||
TotalZeros_G3 <= 11;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
6 : begin
|
||||
case(1'b1)
|
||||
rbsp_G3[0] : begin
|
||||
len_G3 <= 3;
|
||||
case(rbsp_G3[1:2])
|
||||
'b11 : TotalZeros_G3 <= 2;
|
||||
'b10 : TotalZeros_G3 <= 3;
|
||||
'b01 : TotalZeros_G3 <= 4;
|
||||
'b00 : TotalZeros_G3 <= 5;
|
||||
endcase
|
||||
end
|
||||
rbsp_G3[1] : begin
|
||||
len_G3 <= 3;
|
||||
if (rbsp_G3[2])
|
||||
TotalZeros_G3 <= 6;
|
||||
else
|
||||
TotalZeros_G3 <= 7;
|
||||
end
|
||||
rbsp_G3[2] : begin
|
||||
len_G3 <= 3;
|
||||
TotalZeros_G3 <= 9;
|
||||
end
|
||||
rbsp_G3[3] : begin
|
||||
len_G3 <= 4;
|
||||
TotalZeros_G3 <= 8;
|
||||
end
|
||||
rbsp_G3[4] : begin
|
||||
len_G3 <= 5;
|
||||
TotalZeros_G3 <= 1;
|
||||
end
|
||||
default : begin
|
||||
len_G3 <= 6;
|
||||
if (rbsp_G3[5])
|
||||
TotalZeros_G3 <= 0;
|
||||
else
|
||||
TotalZeros_G3 <= 10;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
7 :begin
|
||||
case(1'b1)
|
||||
rbsp_G3[0] : begin
|
||||
if (rbsp_G3[1]) begin
|
||||
TotalZeros_G3 <= 5;
|
||||
len_G3 <= 2;
|
||||
end
|
||||
else begin
|
||||
len_G3 <= 3;
|
||||
if (rbsp_G3[2])
|
||||
TotalZeros_G3 <= 2;
|
||||
else
|
||||
TotalZeros_G3 <= 3;
|
||||
end
|
||||
end
|
||||
rbsp_G3[1] : begin
|
||||
len_G3 <= 3;
|
||||
if (rbsp_G3[2])
|
||||
TotalZeros_G3 <= 4;
|
||||
else
|
||||
TotalZeros_G3 <= 6;
|
||||
end
|
||||
rbsp_G3[2] : begin
|
||||
len_G3 <= 3;
|
||||
TotalZeros_G3 <= 8;
|
||||
end
|
||||
rbsp_G3[3] : begin
|
||||
len_G3 <= 4;
|
||||
TotalZeros_G3 <= 7;
|
||||
end
|
||||
rbsp_G3[4] : begin
|
||||
len_G3 <= 5;
|
||||
TotalZeros_G3 <= 1;
|
||||
end
|
||||
default : begin
|
||||
len_G3 <= 6;
|
||||
if (rbsp_G3[5])
|
||||
TotalZeros_G3 <= 0;
|
||||
else
|
||||
TotalZeros_G3 <= 9;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
8 :begin
|
||||
case(1'b1)
|
||||
rbsp_G3[0] : begin
|
||||
len_G3 <= 2;
|
||||
if (rbsp_G3[1])
|
||||
TotalZeros_G3 <= 4;
|
||||
else
|
||||
TotalZeros_G3 <= 5;
|
||||
end
|
||||
rbsp_G3[1] : begin
|
||||
len_G3 <= 3;
|
||||
if (rbsp_G3[2])
|
||||
TotalZeros_G3 <= 3;
|
||||
else
|
||||
TotalZeros_G3 <= 6;
|
||||
end
|
||||
rbsp_G3[2] : begin
|
||||
len_G3 <= 3;
|
||||
TotalZeros_G3 <= 7;
|
||||
end
|
||||
rbsp_G3[3] : begin
|
||||
len_G3 <= 4;
|
||||
TotalZeros_G3 <= 1;
|
||||
end
|
||||
rbsp_G3[4] : begin
|
||||
len_G3 <= 5;
|
||||
TotalZeros_G3 <= 2;
|
||||
end
|
||||
default : begin
|
||||
len_G3 <= 6;
|
||||
if (rbsp_G3[5])
|
||||
TotalZeros_G3 <= 0;
|
||||
else
|
||||
TotalZeros_G3 <= 8;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
9 : begin
|
||||
case(1'b1)
|
||||
rbsp_G3[0] : begin
|
||||
len_G3 <= 2;
|
||||
if (rbsp_G3[1])
|
||||
TotalZeros_G3 <= 3;
|
||||
else
|
||||
TotalZeros_G3 <= 4;
|
||||
end
|
||||
rbsp_G3[1] : begin
|
||||
len_G3 <= 2;
|
||||
TotalZeros_G3 <= 6;
|
||||
end
|
||||
rbsp_G3[2] : begin
|
||||
len_G3 <= 3;
|
||||
TotalZeros_G3 <= 5;
|
||||
end
|
||||
rbsp_G3[3] : begin
|
||||
len_G3 <= 4;
|
||||
TotalZeros_G3 <= 2;
|
||||
end
|
||||
rbsp_G3[4] : begin
|
||||
len_G3 <= 5;
|
||||
TotalZeros_G3 <= 7;
|
||||
end
|
||||
default : begin
|
||||
len_G3 <= 6;
|
||||
if (rbsp_G3[5])
|
||||
TotalZeros_G3 <= 0;
|
||||
else
|
||||
TotalZeros_G3 <= 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
10 : begin
|
||||
case(1'b1)
|
||||
rbsp_G3[0] : begin
|
||||
len_G3 <= 2;
|
||||
if (rbsp_G3[1])
|
||||
TotalZeros_G3 <= 3;
|
||||
else
|
||||
TotalZeros_G3 <= 4;
|
||||
end
|
||||
rbsp_G3[1] : begin
|
||||
len_G3 <= 2;
|
||||
TotalZeros_G3 <= 5;
|
||||
end
|
||||
rbsp_G3[2] : begin
|
||||
len_G3 <= 3;
|
||||
TotalZeros_G3 <= 2;
|
||||
end
|
||||
rbsp_G3[3] : begin
|
||||
len_G3 <= 4;
|
||||
TotalZeros_G3 <= 6;
|
||||
end
|
||||
default : begin
|
||||
len_G3 <= 5;
|
||||
if (rbsp_G3[4])
|
||||
TotalZeros_G3 <= 0;
|
||||
else
|
||||
TotalZeros_G3 <= 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
11 : begin
|
||||
case(1'b1)
|
||||
rbsp_G3[0] : begin
|
||||
len_G3 <= 1;
|
||||
TotalZeros_G3 <= 4;
|
||||
end
|
||||
rbsp_G3[1] : begin
|
||||
len_G3 <= 3;
|
||||
if (rbsp_G3[2])
|
||||
TotalZeros_G3 <= 5;
|
||||
else
|
||||
TotalZeros_G3 <= 3;
|
||||
end
|
||||
rbsp_G3[2] : begin
|
||||
len_G3 <= 3;
|
||||
TotalZeros_G3 <= 2;
|
||||
end
|
||||
default : begin
|
||||
len_G3 <= 4;
|
||||
if (rbsp_G3[3])
|
||||
TotalZeros_G3 <= 1;
|
||||
else
|
||||
TotalZeros_G3 <= 0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
12 : begin
|
||||
case(1'b1)
|
||||
rbsp_G3[0] : begin
|
||||
len_G3 <= 1;
|
||||
TotalZeros_G3 <= 3;
|
||||
end
|
||||
rbsp_G3[1] : begin
|
||||
len_G3 <= 2;
|
||||
TotalZeros_G3 <= 2;
|
||||
end
|
||||
rbsp_G3[2] : begin
|
||||
len_G3 <= 3;
|
||||
TotalZeros_G3 <= 4;
|
||||
end
|
||||
default : begin
|
||||
len_G3 <= 4;
|
||||
if (rbsp_G3[3])
|
||||
TotalZeros_G3 <= 1;
|
||||
else
|
||||
TotalZeros_G3 <= 0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
13 :begin
|
||||
if (rbsp_G3[0]) begin
|
||||
TotalZeros_G3 <= 2;
|
||||
len_G3 <= 1;
|
||||
end
|
||||
else if (rbsp_G3[1]) begin
|
||||
TotalZeros_G3 <= 3;
|
||||
len_G3 <= 2;
|
||||
end
|
||||
else if (rbsp_G3[2]) begin
|
||||
TotalZeros_G3 <= 1;
|
||||
len_G3 <= 3;
|
||||
end
|
||||
else begin
|
||||
TotalZeros_G3 <= 0;
|
||||
len_G3 <= 3;
|
||||
end
|
||||
end
|
||||
14 : begin
|
||||
if (rbsp_G3[0]) begin
|
||||
TotalZeros_G3 <= 2;
|
||||
len_G3 <= 1;
|
||||
end
|
||||
else if (rbsp_G3[1]) begin
|
||||
TotalZeros_G3 <= 1;
|
||||
len_G3 <= 2;
|
||||
end
|
||||
else begin
|
||||
TotalZeros_G3 <= 0;
|
||||
len_G3 <= 2;
|
||||
end
|
||||
end
|
||||
15 : begin
|
||||
len_G3 <= 1;
|
||||
if (rbsp_G3[0])
|
||||
TotalZeros_G3 <= 1;
|
||||
else
|
||||
TotalZeros_G3 <= 0;
|
||||
end
|
||||
default : begin
|
||||
len_G3 <= 'bx;
|
||||
TotalZeros_G3 <= 'bx;
|
||||
end
|
||||
endcase
|
||||
|
||||
//---------------------------------
|
||||
//TotalZeros_comb & len_comb
|
||||
//---------------------------------
|
||||
always @(*)
|
||||
if (ena && sel && chroma_DC_sel) begin
|
||||
TotalZeros_comb <= TotalZeros_chroma_DC;
|
||||
len_comb <= len_chroma_DC;
|
||||
end
|
||||
else if (ena && sel && TotalCoeff[3:2] == 2'b00) begin
|
||||
TotalZeros_comb <= TotalZeros_LE3;
|
||||
len_comb <= len_LE3;
|
||||
end
|
||||
else if (ena && sel)begin
|
||||
TotalZeros_comb <= TotalZeros_G3;
|
||||
len_comb <= len_G3;
|
||||
end
|
||||
else begin
|
||||
TotalZeros_comb <= 0;
|
||||
len_comb <= 0;
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,294 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// cavlc_top ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// top module of cavlc decoder ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - bin qiu, qiubin@opencores.org ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2011 Authors and OPENCORES.ORG ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from http://www.opencores.org/lgpl.shtml ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
//2011-8-7 initial version
|
||||
|
||||
`include "defines.v"
|
||||
|
||||
module cavlc_top
|
||||
(
|
||||
clk,
|
||||
rst_n,
|
||||
ena,
|
||||
start,
|
||||
rbsp,
|
||||
nC,
|
||||
max_coeff_num,
|
||||
|
||||
coeff_0,
|
||||
coeff_1,
|
||||
coeff_2,
|
||||
coeff_3,
|
||||
coeff_4,
|
||||
coeff_5,
|
||||
coeff_6,
|
||||
coeff_7,
|
||||
coeff_8,
|
||||
coeff_9,
|
||||
coeff_10,
|
||||
coeff_11,
|
||||
coeff_12,
|
||||
coeff_13,
|
||||
coeff_14,
|
||||
coeff_15,
|
||||
TotalCoeff,
|
||||
len_comb,
|
||||
idle,
|
||||
valid
|
||||
);
|
||||
//------------------------
|
||||
// ports
|
||||
//------------------------
|
||||
input clk, rst_n;
|
||||
input ena;
|
||||
input start;
|
||||
input [0:15] rbsp;
|
||||
input signed [5:0] nC;
|
||||
input [4:0] max_coeff_num;
|
||||
|
||||
output signed [8:0] coeff_0;
|
||||
output signed [8:0] coeff_1;
|
||||
output signed [8:0] coeff_2;
|
||||
output signed [8:0] coeff_3;
|
||||
output signed [8:0] coeff_4;
|
||||
output signed [8:0] coeff_5;
|
||||
output signed [8:0] coeff_6;
|
||||
output signed [8:0] coeff_7;
|
||||
output signed [8:0] coeff_8;
|
||||
output signed [8:0] coeff_9;
|
||||
output signed [8:0] coeff_10;
|
||||
output signed [8:0] coeff_11;
|
||||
output signed [8:0] coeff_12;
|
||||
output signed [8:0] coeff_13;
|
||||
output signed [8:0] coeff_14;
|
||||
output signed [8:0] coeff_15;
|
||||
output [4:0] TotalCoeff;
|
||||
output [4:0] len_comb;
|
||||
output idle;
|
||||
output valid;
|
||||
|
||||
//------------------------
|
||||
// cavlc_read_total_coeffs
|
||||
//------------------------
|
||||
wire [1:0] TrailingOnes;
|
||||
wire [4:0] TotalCoeff;
|
||||
wire [1:0] TrailingOnes_comb;
|
||||
wire [4:0] TotalCoeff_comb;
|
||||
wire [4:0] len_read_total_coeffs_comb;
|
||||
wire [7:0] cavlc_state;
|
||||
|
||||
cavlc_read_total_coeffs cavlc_read_total_coeffs(
|
||||
.clk(clk),
|
||||
.rst_n(rst_n),
|
||||
.ena(ena),
|
||||
.start(start),
|
||||
.sel(cavlc_state[`cavlc_read_total_coeffs_bit]),
|
||||
|
||||
.rbsp(rbsp),
|
||||
.nC(nC),
|
||||
|
||||
.TrailingOnes(TrailingOnes),
|
||||
.TotalCoeff(TotalCoeff),
|
||||
|
||||
.TrailingOnes_comb(TrailingOnes_comb),
|
||||
.TotalCoeff_comb(TotalCoeff_comb),
|
||||
|
||||
.len_comb(len_read_total_coeffs_comb)
|
||||
);
|
||||
|
||||
//------------------------
|
||||
// cavlc_read_levels
|
||||
//------------------------
|
||||
wire [4:0] len_read_levels_comb;
|
||||
wire [3:0] i;
|
||||
|
||||
wire [8:0] level_0;
|
||||
wire [8:0] level_1;
|
||||
wire [8:0] level_2;
|
||||
wire [8:0] level_3;
|
||||
wire [8:0] level_4;
|
||||
wire [8:0] level_5;
|
||||
wire [8:0] level_6;
|
||||
wire [8:0] level_7;
|
||||
wire [8:0] level_8;
|
||||
wire [8:0] level_9;
|
||||
wire [8:0] level_10;
|
||||
wire [8:0] level_11;
|
||||
wire [8:0] level_12;
|
||||
wire [8:0] level_13;
|
||||
wire [8:0] level_14;
|
||||
wire [8:0] level_15;
|
||||
|
||||
cavlc_read_levels cavlc_read_levels(
|
||||
.clk(clk),
|
||||
.rst_n(rst_n),
|
||||
.ena(ena),
|
||||
.t1s_sel(cavlc_state[`cavlc_read_t1s_flags_bit]),
|
||||
.prefix_sel(cavlc_state[`cavlc_read_level_prefix_bit]),
|
||||
.suffix_sel(cavlc_state[`cavlc_read_level_suffix_bit]),
|
||||
.calc_sel(cavlc_state[`cavlc_calc_level_bit]),
|
||||
.TrailingOnes(TrailingOnes),
|
||||
.TotalCoeff(TotalCoeff),
|
||||
.i(i),
|
||||
.rbsp(rbsp),
|
||||
|
||||
.level_0(level_0),
|
||||
.level_1(level_1),
|
||||
.level_2(level_2),
|
||||
.level_3(level_3),
|
||||
.level_4(level_4),
|
||||
.level_5(level_5),
|
||||
.level_6(level_6),
|
||||
.level_7(level_7),
|
||||
.level_8(level_8),
|
||||
.level_9(level_9),
|
||||
.level_10(level_10),
|
||||
.level_11(level_11),
|
||||
.level_12(level_12),
|
||||
.level_13(level_13),
|
||||
.level_14(level_14),
|
||||
.level_15(level_15),
|
||||
.len_comb(len_read_levels_comb)
|
||||
);
|
||||
|
||||
//------------------------
|
||||
// cavlc_read_total_zeros
|
||||
//------------------------
|
||||
wire [3:0] TotalZeros_comb;
|
||||
wire [3:0] len_read_total_zeros_comb;
|
||||
|
||||
cavlc_read_total_zeros cavlc_read_total_zeros(
|
||||
.ena(ena),
|
||||
.sel(cavlc_state[`cavlc_read_total_zeros_bit]),
|
||||
.chroma_DC_sel(nC[5]),
|
||||
.rbsp(rbsp[0:8]),
|
||||
.TotalCoeff(TotalCoeff[3:0]),
|
||||
.TotalZeros_comb(TotalZeros_comb),
|
||||
.len_comb(len_read_total_zeros_comb)
|
||||
);
|
||||
|
||||
//------------------------
|
||||
// read_run_before
|
||||
//------------------------
|
||||
wire [3:0] ZeroLeft;
|
||||
wire [3:0] len_read_run_befores_comb;
|
||||
|
||||
cavlc_read_run_befores cavlc_read_run_befores(
|
||||
.clk(clk),
|
||||
.rst_n(rst_n),
|
||||
.ena(ena),
|
||||
.clr(cavlc_state[`cavlc_read_total_coeffs_bit]),
|
||||
.sel(cavlc_state[`cavlc_read_run_befores_bit]),
|
||||
.ZeroLeft_init(cavlc_state[`cavlc_read_total_zeros_bit]),
|
||||
|
||||
.rbsp(rbsp[0:10]),
|
||||
.i(i),
|
||||
.TotalZeros_comb(TotalZeros_comb),
|
||||
|
||||
.level_0(level_0),
|
||||
.level_1(level_1),
|
||||
.level_2(level_2),
|
||||
.level_3(level_3),
|
||||
.level_4(level_4),
|
||||
.level_5(level_5),
|
||||
.level_6(level_6),
|
||||
.level_7(level_7),
|
||||
.level_8(level_8),
|
||||
.level_9(level_9),
|
||||
.level_10(level_10),
|
||||
.level_11(level_11),
|
||||
.level_12(level_12),
|
||||
.level_13(level_13),
|
||||
.level_14(level_14),
|
||||
.level_15(level_15),
|
||||
|
||||
.coeff_0(coeff_0),
|
||||
.coeff_1(coeff_1),
|
||||
.coeff_2(coeff_2),
|
||||
.coeff_3(coeff_3),
|
||||
.coeff_4(coeff_4),
|
||||
.coeff_5(coeff_5),
|
||||
.coeff_6(coeff_6),
|
||||
.coeff_7(coeff_7),
|
||||
.coeff_8(coeff_8),
|
||||
.coeff_9(coeff_9),
|
||||
.coeff_10(coeff_10),
|
||||
.coeff_11(coeff_11),
|
||||
.coeff_12(coeff_12),
|
||||
.coeff_13(coeff_13),
|
||||
.coeff_14(coeff_14),
|
||||
.coeff_15(coeff_15),
|
||||
.ZeroLeft(ZeroLeft),
|
||||
.len_comb(len_read_run_befores_comb)
|
||||
);
|
||||
|
||||
//------------------------
|
||||
// cavlc_len_gen
|
||||
//------------------------
|
||||
wire [4:0] len_comb;
|
||||
|
||||
cavlc_len_gen cavlc_len_gen(
|
||||
.cavlc_state(cavlc_state),
|
||||
.len_read_total_coeffs_comb(len_read_total_coeffs_comb),
|
||||
.len_read_levels_comb(len_read_levels_comb),
|
||||
.len_read_total_zeros_comb(len_read_total_zeros_comb),
|
||||
.len_read_run_befores_comb(len_read_run_befores_comb),
|
||||
.len_comb(len_comb)
|
||||
);
|
||||
|
||||
//------------------------
|
||||
// fsm
|
||||
//------------------------
|
||||
cavlc_fsm cavlc_fsm(
|
||||
.clk(clk),
|
||||
.rst_n(rst_n),
|
||||
.ena(ena),
|
||||
.start(start),
|
||||
|
||||
.max_coeff_num(max_coeff_num),
|
||||
.TotalCoeff(TotalCoeff),
|
||||
.TotalCoeff_comb(TotalCoeff_comb),
|
||||
.TrailingOnes(TrailingOnes),
|
||||
.TrailingOnes_comb(TrailingOnes_comb),
|
||||
.ZeroLeft(ZeroLeft),
|
||||
.state(cavlc_state),
|
||||
.i(i),
|
||||
.idle(idle),
|
||||
.valid(valid)
|
||||
);
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,22 @@
|
|||
`timescale 1ns / 1ns // timescale time_unit/time_presicion
|
||||
|
||||
`define cavlc_idle_bit 0
|
||||
`define cavlc_read_total_coeffs_bit 1
|
||||
`define cavlc_read_t1s_flags_bit 2
|
||||
`define cavlc_read_level_prefix_bit 3
|
||||
`define cavlc_read_level_suffix_bit 4
|
||||
`define cavlc_calc_level_bit 5
|
||||
`define cavlc_read_total_zeros_bit 6
|
||||
`define cavlc_read_run_befores_bit 7
|
||||
|
||||
`define cavlc_idle_s 8'b00000001
|
||||
`define cavlc_read_total_coeffs_s 8'b00000010
|
||||
`define cavlc_read_t1s_flags_s 8'b00000100
|
||||
`define cavlc_read_level_prefix_s 8'b00001000
|
||||
`define cavlc_read_level_suffix_s 8'b00010000
|
||||
`define cavlc_calc_level_s 8'b00100000
|
||||
`define cavlc_read_total_zeros_s 8'b01000000
|
||||
`define cavlc_read_run_befores_s 8'b10000000
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,102 @@
|
|||
// 5 counter with 5 clock domain
|
||||
// each counter has 130 bits
|
||||
// each counter has 21 output
|
||||
|
||||
// test: placement , routing and performace for each clock domain
|
||||
|
||||
module counter120bitx5(clk1,clk2,clk3,clk4,clk5,out1x,out2x,out3x,out4x,out5x,reset);
|
||||
|
||||
input clk1,clk2,clk3,clk4,clk5,reset;
|
||||
|
||||
output [13:0] out1x;
|
||||
output [13:0] out2x;
|
||||
output [13:0] out3x;
|
||||
output [13:0] out4x;
|
||||
output [13:0] out5x;
|
||||
|
||||
reg [120:0] cnt1;
|
||||
reg [120:0] cnt2;
|
||||
reg [120:0] cnt3;
|
||||
reg [120:0] cnt4;
|
||||
reg [120:0] cnt5;
|
||||
|
||||
|
||||
assign out1x = {cnt1[120:115],cnt1[7:0]};
|
||||
assign out2x = {cnt2[120:115],cnt2[7:0]};
|
||||
assign out3x = {cnt3[120:115],cnt3[7:0]};
|
||||
assign out4x = {cnt4[120:115],cnt4[7:0]};
|
||||
assign out5x = {cnt5[120:115],cnt5[7:0]};
|
||||
|
||||
|
||||
always @(posedge clk1)
|
||||
|
||||
begin
|
||||
|
||||
if (reset)
|
||||
|
||||
cnt1 <=1'b0;
|
||||
|
||||
else
|
||||
|
||||
cnt1 <= cnt1+1;
|
||||
|
||||
end
|
||||
|
||||
|
||||
always @(posedge clk2)
|
||||
|
||||
begin
|
||||
|
||||
if (reset)
|
||||
|
||||
cnt2 <=1'b0;
|
||||
|
||||
else
|
||||
|
||||
cnt2 <= cnt2 +1;
|
||||
|
||||
end
|
||||
always @(posedge clk3)
|
||||
|
||||
begin
|
||||
|
||||
if (reset)
|
||||
|
||||
cnt3 <=1'b0;
|
||||
|
||||
else
|
||||
|
||||
cnt3 <= cnt3 +1;
|
||||
|
||||
end
|
||||
always @(posedge clk4)
|
||||
|
||||
begin
|
||||
|
||||
if (reset)
|
||||
|
||||
cnt4 <=1'b0;
|
||||
|
||||
else
|
||||
|
||||
cnt4 <= cnt4 +1;
|
||||
|
||||
end
|
||||
|
||||
always @(posedge clk5)
|
||||
|
||||
begin
|
||||
|
||||
if (reset)
|
||||
|
||||
cnt5 <=1'b0;
|
||||
|
||||
else
|
||||
|
||||
cnt5 <= cnt5 +1;
|
||||
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
# Generated by Yosys 0.9+2406 (git sha1 470f9532, gcc 9.3.0 -fPIC -Os)
|
||||
|
||||
.model top
|
||||
.inputs clk reset enable
|
||||
.outputs count(0) count(1) count(2) count(3) count(4) count(5) count(6) count(7) count(8) count(9) count(10) count(11) count(12) count(13) count(14) count(15)
|
||||
.names $false
|
||||
.names $true
|
||||
1
|
||||
.names $undef
|
||||
.subckt logic_0 a=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.subckt in_buff A=clk Q=$iopadmap$clk
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:12.13-12.45"
|
||||
.subckt out_buff A=$iopadmap$count(0) Q=count(0)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||
.subckt out_buff A=$iopadmap$count(1) Q=count(1)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||
.subckt out_buff A=$iopadmap$count(10) Q=count(10)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||
.subckt out_buff A=$iopadmap$count(11) Q=count(11)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||
.subckt out_buff A=$iopadmap$count(12) Q=count(12)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||
.subckt out_buff A=$iopadmap$count(13) Q=count(13)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||
.subckt out_buff A=$iopadmap$count(14) Q=count(14)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||
.subckt out_buff A=$iopadmap$count(15) Q=count(15)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||
.subckt out_buff A=$iopadmap$count(2) Q=count(2)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||
.subckt out_buff A=$iopadmap$count(3) Q=count(3)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||
.subckt out_buff A=$iopadmap$count(4) Q=count(4)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||
.subckt out_buff A=$iopadmap$count(5) Q=count(5)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||
.subckt out_buff A=$iopadmap$count(6) Q=count(6)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||
.subckt out_buff A=$iopadmap$count(7) Q=count(7)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||
.subckt out_buff A=$iopadmap$count(8) Q=count(8)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||
.subckt out_buff A=$iopadmap$count(9) Q=count(9)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:5.14-5.46"
|
||||
.subckt in_buff A=enable Q=$iopadmap$enable
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:12.13-12.45"
|
||||
.subckt in_buff A=reset Q=$iopadmap$reset
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_io_map.v:12.13-12.45"
|
||||
.subckt ff CQZ=$iopadmap$count(15) D=count_ff_CQZ_D(15) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||
.subckt ff CQZ=$iopadmap$count(14) D=count_ff_CQZ_D(14) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||
.subckt ff CQZ=$iopadmap$count(5) D=count_ff_CQZ_D(5) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||
.subckt ff CQZ=$iopadmap$count(4) D=count_ff_CQZ_D(4) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||
.subckt ff CQZ=$iopadmap$count(3) D=count_ff_CQZ_D(3) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||
.subckt ff CQZ=$iopadmap$count(2) D=count_ff_CQZ_D(2) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||
.subckt ff CQZ=$iopadmap$count(1) D=count_ff_CQZ_D(1) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||
.subckt ff CQZ=$iopadmap$count(0) D=count_ff_CQZ_D(0) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||
.subckt ff CQZ=$iopadmap$count(13) D=count_ff_CQZ_D(13) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||
.subckt ff CQZ=$iopadmap$count(12) D=count_ff_CQZ_D(12) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||
.subckt ff CQZ=$iopadmap$count(11) D=count_ff_CQZ_D(11) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||
.subckt ff CQZ=$iopadmap$count(10) D=count_ff_CQZ_D(10) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||
.subckt ff CQZ=$iopadmap$count(9) D=count_ff_CQZ_D(9) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||
.subckt ff CQZ=$iopadmap$count(8) D=count_ff_CQZ_D(8) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||
.subckt ff CQZ=$iopadmap$count(7) D=count_ff_CQZ_D(7) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||
.subckt ff CQZ=$iopadmap$count(6) D=count_ff_CQZ_D(6) QCK=$iopadmap$clk QEN=enable_LUT4_I2_O QRT=$auto$hilomap.cc:47:hilomap_worker$708 QST=$auto$hilomap.cc:47:hilomap_worker$708
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/git/yosys-testing/Designs/counter_16bit/rtl/counter_16bit.v:14.1-19.4|/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_ffs_map.v:120.8-120.84"
|
||||
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$auto$hilomap.cc:47:hilomap_worker$708 I2=$iopadmap$enable I3=$iopadmap$reset O=enable_LUT4_I2_O
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:16.41-16.110"
|
||||
.param EQN "(I0*~I1*I2*I3)+(~I0*I1*I2*I3)+(I0*I1*I2*I3)"
|
||||
.param INIT 1110
|
||||
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$auto$hilomap.cc:47:hilomap_worker$708 I2=$iopadmap$reset I3=reset_LUT4_I2_I3 O=count_ff_CQZ_D(15)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:16.41-16.110"
|
||||
.param EQN "(~I0*~I1*I2*I3)"
|
||||
.param INIT 0001
|
||||
.subckt LUT4 I0=reset_LUT4_I3_I2 I1=$iopadmap$count(13) I2=$iopadmap$reset I3=$iopadmap$count(14) O=count_ff_CQZ_D(14)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||
.param EQN "(I0*I1*~I2*~I3)+(~I0*~I1*~I2*I3)+(I0*~I1*~I2*I3)+(~I0*I1*~I2*I3)"
|
||||
.param INIT 0000011100001000
|
||||
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$auto$hilomap.cc:47:hilomap_worker$708 I2=$iopadmap$reset I3=reset_LUT4_I2_2_I3 O=count_ff_CQZ_D(12)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:16.41-16.110"
|
||||
.param EQN "(~I0*~I1*I2*I3)"
|
||||
.param INIT 0001
|
||||
.subckt LUT4 I0=reset_LUT4_I3_1_I2 I1=$iopadmap$count(10) I2=$iopadmap$count(11) I3=$iopadmap$count(12) O=reset_LUT4_I2_2_I3
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||
.param EQN "(~I0*~I1*~I2*~I3)+(I0*~I1*~I2*~I3)+(~I0*I1*~I2*~I3)+(I0*I1*~I2*~I3)+(~I0*~I1*I2*~I3)+(I0*~I1*I2*~I3)+(~I0*I1*I2*~I3)+(I0*I1*I2*I3)"
|
||||
.param INIT 1000000001111111
|
||||
.subckt LUT4 I0=reset_LUT4_I3_1_I2 I1=$iopadmap$count(10) I2=$iopadmap$reset I3=$iopadmap$count(11) O=count_ff_CQZ_D(11)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||
.param EQN "(I0*I1*~I2*~I3)+(~I0*~I1*~I2*I3)+(I0*~I1*~I2*I3)+(~I0*I1*~I2*I3)"
|
||||
.param INIT 0000011100001000
|
||||
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$auto$hilomap.cc:47:hilomap_worker$708 I2=$iopadmap$reset I3=reset_LUT4_I2_4_I3 O=count_ff_CQZ_D(9)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:16.41-16.110"
|
||||
.param EQN "(~I0*~I1*I2*I3)"
|
||||
.param INIT 0001
|
||||
.subckt LUT4 I0=reset_LUT4_I3_2_I2 I1=$iopadmap$count(7) I2=$iopadmap$count(8) I3=$iopadmap$count(9) O=reset_LUT4_I2_4_I3
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||
.param EQN "(~I0*~I1*~I2*~I3)+(I0*~I1*~I2*~I3)+(~I0*I1*~I2*~I3)+(I0*I1*~I2*~I3)+(~I0*~I1*I2*~I3)+(I0*~I1*I2*~I3)+(~I0*I1*I2*~I3)+(I0*I1*I2*I3)"
|
||||
.param INIT 1000000001111111
|
||||
.subckt LUT4 I0=reset_LUT4_I3_2_I2 I1=$iopadmap$count(7) I2=$iopadmap$reset I3=$iopadmap$count(8) O=count_ff_CQZ_D(8)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||
.param EQN "(I0*I1*~I2*~I3)+(~I0*~I1*~I2*I3)+(I0*~I1*~I2*I3)+(~I0*I1*~I2*I3)"
|
||||
.param INIT 0000011100001000
|
||||
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$auto$hilomap.cc:47:hilomap_worker$708 I2=$iopadmap$reset I3=reset_LUT4_I2_6_I3 O=count_ff_CQZ_D(6)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:16.41-16.110"
|
||||
.param EQN "(~I0*~I1*I2*I3)"
|
||||
.param INIT 0001
|
||||
.subckt LUT4 I0=reset_LUT4_I3_3_I2 I1=$iopadmap$count(4) I2=$iopadmap$count(5) I3=$iopadmap$count(6) O=reset_LUT4_I2_6_I3
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||
.param EQN "(~I0*~I1*~I2*~I3)+(I0*~I1*~I2*~I3)+(~I0*I1*~I2*~I3)+(I0*I1*~I2*~I3)+(~I0*~I1*I2*~I3)+(I0*~I1*I2*~I3)+(~I0*I1*I2*~I3)+(I0*I1*I2*I3)"
|
||||
.param INIT 1000000001111111
|
||||
.subckt LUT4 I0=reset_LUT4_I3_3_I2 I1=$iopadmap$count(4) I2=$iopadmap$reset I3=$iopadmap$count(5) O=count_ff_CQZ_D(5)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||
.param EQN "(I0*I1*~I2*~I3)+(~I0*~I1*~I2*I3)+(I0*~I1*~I2*I3)+(~I0*I1*~I2*I3)"
|
||||
.param INIT 0000011100001000
|
||||
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$auto$hilomap.cc:47:hilomap_worker$708 I2=$iopadmap$reset I3=reset_LUT4_I2_8_I3 O=count_ff_CQZ_D(3)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:16.41-16.110"
|
||||
.param EQN "(~I0*~I1*I2*I3)"
|
||||
.param INIT 0001
|
||||
.subckt LUT4 I0=$iopadmap$count(0) I1=$iopadmap$count(1) I2=$iopadmap$count(2) I3=$iopadmap$count(3) O=reset_LUT4_I2_8_I3
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||
.param EQN "(~I0*~I1*~I2*~I3)+(I0*~I1*~I2*~I3)+(~I0*I1*~I2*~I3)+(I0*I1*~I2*~I3)+(~I0*~I1*I2*~I3)+(I0*~I1*I2*~I3)+(~I0*I1*I2*~I3)+(I0*I1*I2*I3)"
|
||||
.param INIT 1000000001111111
|
||||
.subckt LUT4 I0=$iopadmap$count(0) I1=$iopadmap$count(1) I2=$iopadmap$reset I3=$iopadmap$count(2) O=count_ff_CQZ_D(2)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||
.param EQN "(I0*I1*~I2*~I3)+(~I0*~I1*~I2*I3)+(I0*~I1*~I2*I3)+(~I0*I1*~I2*I3)"
|
||||
.param INIT 0000011100001000
|
||||
.subckt LUT4 I0=reset_LUT4_I3_I2 I1=$iopadmap$count(13) I2=$iopadmap$count(14) I3=$iopadmap$count(15) O=reset_LUT4_I2_I3
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||
.param EQN "(~I0*~I1*~I2*~I3)+(I0*~I1*~I2*~I3)+(~I0*I1*~I2*~I3)+(I0*I1*~I2*~I3)+(~I0*~I1*I2*~I3)+(I0*~I1*I2*~I3)+(~I0*I1*I2*~I3)+(I0*I1*I2*I3)"
|
||||
.param INIT 1000000001111111
|
||||
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$iopadmap$count(13) I2=reset_LUT4_I3_I2 I3=$iopadmap$reset O=count_ff_CQZ_D(13)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:20.41-20.110"
|
||||
.param EQN "(~I0*I1*~I2*I3)+(~I0*~I1*I2*I3)"
|
||||
.param INIT 00010100
|
||||
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$iopadmap$count(10) I2=reset_LUT4_I3_1_I2 I3=$iopadmap$reset O=count_ff_CQZ_D(10)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:20.41-20.110"
|
||||
.param EQN "(~I0*I1*~I2*I3)+(~I0*~I1*I2*I3)"
|
||||
.param INIT 00010100
|
||||
.subckt LUT4 I0=reset_LUT4_I3_2_I2 I1=$iopadmap$count(7) I2=$iopadmap$count(8) I3=$iopadmap$count(9) O=reset_LUT4_I3_1_I2
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||
.param EQN "(I0*I1*I2*I3)"
|
||||
.param INIT 1000000000000000
|
||||
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$iopadmap$count(7) I2=reset_LUT4_I3_2_I2 I3=$iopadmap$reset O=count_ff_CQZ_D(7)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:20.41-20.110"
|
||||
.param EQN "(~I0*I1*~I2*I3)+(~I0*~I1*I2*I3)"
|
||||
.param INIT 00010100
|
||||
.subckt LUT4 I0=reset_LUT4_I3_3_I2 I1=$iopadmap$count(4) I2=$iopadmap$count(5) I3=$iopadmap$count(6) O=reset_LUT4_I3_2_I2
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||
.param EQN "(I0*I1*I2*I3)"
|
||||
.param INIT 1000000000000000
|
||||
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$iopadmap$count(4) I2=reset_LUT4_I3_3_I2 I3=$iopadmap$reset O=count_ff_CQZ_D(4)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:20.41-20.110"
|
||||
.param EQN "(~I0*I1*~I2*I3)+(~I0*~I1*I2*I3)"
|
||||
.param INIT 00010100
|
||||
.subckt LUT4 I0=$iopadmap$count(0) I1=$iopadmap$count(1) I2=$iopadmap$count(2) I3=$iopadmap$count(3) O=reset_LUT4_I3_3_I2
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||
.param EQN "(I0*I1*I2*I3)"
|
||||
.param INIT 1000000000000000
|
||||
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$iopadmap$count(1) I2=$iopadmap$count(0) I3=$iopadmap$reset O=count_ff_CQZ_D(1)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:20.41-20.110"
|
||||
.param EQN "(~I0*I1*~I2*I3)+(~I0*~I1*I2*I3)"
|
||||
.param INIT 00010100
|
||||
.subckt LUT4 I0=$auto$hilomap.cc:47:hilomap_worker$708 I1=$auto$hilomap.cc:47:hilomap_worker$708 I2=$iopadmap$count(0) I3=$iopadmap$reset O=count_ff_CQZ_D(0)
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:16.41-16.110"
|
||||
.param EQN "(~I0*~I1*I2*I3)"
|
||||
.param INIT 0001
|
||||
.subckt LUT4 I0=reset_LUT4_I3_1_I2 I1=$iopadmap$count(10) I2=$iopadmap$count(11) I3=$iopadmap$count(12) O=reset_LUT4_I3_I2
|
||||
.attr module_not_derived 00000000000000000000000000000001
|
||||
.attr src "/home/tpagarani/antmicro_install/bin/../share/yosys/quicklogic/ap3_lut_map.v:23.41-23.109"
|
||||
.param EQN "(I0*I1*I2*I3)"
|
||||
.param INIT 1000000000000000
|
||||
.end
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// Copyright (c) 2020 QuickLogic Corporation. All Rights Reserved.
|
||||
//
|
||||
// Description :
|
||||
// Example of asimple 16 bit up counter in Verilog HDL
|
||||
//
|
||||
// Version 1.0 : Initial Creation
|
||||
//
|
||||
module top (clk, reset, enable, count);
|
||||
input clk, reset, enable;
|
||||
output [15:0] count;
|
||||
reg [15:0] count;
|
||||
|
||||
always @ (posedge clk)
|
||||
if (reset == 1'b1) begin
|
||||
count <= 0;
|
||||
end else if ( enable == 1'b1) begin
|
||||
count <= count + 1;
|
||||
end
|
||||
|
||||
endmodule
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,311 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Discrete Cosine Transform, Parallel implementation ////
|
||||
//// ////
|
||||
//// 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: dct.v,v 1.3 2002-10-31 12:50:03 rherveille Exp $
|
||||
//
|
||||
// $Date: 2002-10-31 12:50:03 $
|
||||
// $Revision: 1.3 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.2 2002/10/23 09:06:59 rherveille
|
||||
// Improved many files.
|
||||
// Fixed some bugs in Run-Length-Encoder.
|
||||
// Removed dependency on ud_cnt and ro_cnt.
|
||||
// Started (Motion)JPEG hardware encoder project.
|
||||
//
|
||||
|
||||
//synopsys translate_off
|
||||
`include "timescale.v"
|
||||
//synopsys translate_on
|
||||
|
||||
module dct(
|
||||
clk,
|
||||
ena,
|
||||
rst,
|
||||
dstrb,
|
||||
din,
|
||||
dout_00, dout_01, dout_02, dout_03, dout_04, dout_05, dout_06, dout_07,
|
||||
dout_10, dout_11, dout_12, dout_13, dout_14, dout_15, dout_16, dout_17,
|
||||
dout_20, dout_21, dout_22, dout_23, dout_24, dout_25, dout_26, dout_27,
|
||||
dout_30, dout_31, dout_32, dout_33, dout_34, dout_35, dout_36, dout_37,
|
||||
dout_40, dout_41, dout_42, dout_43, dout_44, dout_45, dout_46, dout_47,
|
||||
dout_50, dout_51, dout_52, dout_53, dout_54, dout_55, dout_56, dout_57,
|
||||
dout_60, dout_61, dout_62, dout_63, dout_64, dout_65, dout_66, dout_67,
|
||||
dout_70, dout_71, dout_72, dout_73, dout_74, dout_75, dout_76, dout_77,
|
||||
douten
|
||||
);
|
||||
|
||||
//
|
||||
// parameters
|
||||
//
|
||||
// Worst case errors (Din = 64* -128) remain in decimal bit
|
||||
// when using 13bit coefficients
|
||||
//
|
||||
// For ultra-high
|
||||
parameter coef_width = 11;
|
||||
parameter di_width = 8;
|
||||
parameter do_width = 12;
|
||||
|
||||
//
|
||||
// inputs & outputs
|
||||
//
|
||||
|
||||
input clk;
|
||||
input ena;
|
||||
input rst; // active low asynchronous reset
|
||||
|
||||
input dstrb; // data-strobe. Present dstrb 1clk-cycle before data block
|
||||
input [di_width:1] din;
|
||||
output [do_width:1]
|
||||
dout_00, dout_01, dout_02, dout_03, dout_04, dout_05, dout_06, dout_07,
|
||||
dout_10, dout_11, dout_12, dout_13, dout_14, dout_15, dout_16, dout_17,
|
||||
dout_20, dout_21, dout_22, dout_23, dout_24, dout_25, dout_26, dout_27,
|
||||
dout_30, dout_31, dout_32, dout_33, dout_34, dout_35, dout_36, dout_37,
|
||||
dout_40, dout_41, dout_42, dout_43, dout_44, dout_45, dout_46, dout_47,
|
||||
dout_50, dout_51, dout_52, dout_53, dout_54, dout_55, dout_56, dout_57,
|
||||
dout_60, dout_61, dout_62, dout_63, dout_64, dout_65, dout_66, dout_67,
|
||||
dout_70, dout_71, dout_72, dout_73, dout_74, dout_75, dout_76, dout_77;
|
||||
|
||||
output douten; // data-out enable
|
||||
reg douten;
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
reg go, dgo, ddgo, ddcnt, dddcnt;
|
||||
reg [di_width:1] ddin;
|
||||
|
||||
//
|
||||
// module body
|
||||
//
|
||||
|
||||
// generate sample counter
|
||||
reg [5:0] sample_cnt;
|
||||
wire dcnt = &sample_cnt;
|
||||
|
||||
always @(posedge clk or negedge rst)
|
||||
if (~rst)
|
||||
sample_cnt <= #1 6'h0;
|
||||
else if (ena)
|
||||
if(dstrb)
|
||||
sample_cnt <= #1 6'h0;
|
||||
else if(~dcnt)
|
||||
sample_cnt <= #1 sample_cnt + 6'h1;
|
||||
|
||||
// internal signals
|
||||
always @(posedge clk or negedge rst)
|
||||
if (~rst)
|
||||
begin
|
||||
go <= #1 1'b0;
|
||||
dgo <= #1 1'b0;
|
||||
ddgo <= #1 1'b0;
|
||||
ddin <= #1 0;
|
||||
|
||||
douten <= #1 1'b0;
|
||||
ddcnt <= #1 1'b1;
|
||||
dddcnt <= #1 1'b1;
|
||||
end
|
||||
else if (ena)
|
||||
begin
|
||||
go <= #1 dstrb;
|
||||
dgo <= #1 go;
|
||||
ddgo <= #1 dgo;
|
||||
ddin <= #1 din;
|
||||
|
||||
ddcnt <= #1 dcnt;
|
||||
dddcnt <= #1 ddcnt;
|
||||
|
||||
douten <= #1 ddcnt & ~dddcnt;
|
||||
end
|
||||
|
||||
// Hookup DCT units
|
||||
|
||||
// V = 0
|
||||
dctub #(coef_width, di_width, 3'h0)
|
||||
dct_block_0 (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.ddgo(ddgo),
|
||||
.x(sample_cnt[2:0]),
|
||||
.y(sample_cnt[5:3]),
|
||||
.ddin(ddin),
|
||||
.dout0(dout_00), // (U,V) = (0,0)
|
||||
.dout1(dout_01), // (U,V) = (0,1)
|
||||
.dout2(dout_02), // (U,V) = (0,2)
|
||||
.dout3(dout_03), // (U,V) = (0,3)
|
||||
.dout4(dout_04), // (U,V) = (0,4)
|
||||
.dout5(dout_05), // (U,V) = (0,5)
|
||||
.dout6(dout_06), // (U,V) = (0,6)
|
||||
.dout7(dout_07) // (U,V) = (0,7)
|
||||
);
|
||||
|
||||
// V = 1
|
||||
dctub #(coef_width, di_width, 3'h1)
|
||||
dct_block_1 (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.ddgo(ddgo),
|
||||
.x(sample_cnt[2:0]),
|
||||
.y(sample_cnt[5:3]),
|
||||
.ddin(ddin),
|
||||
.dout0(dout_10), // (U,V) = (1,0)
|
||||
.dout1(dout_11), // (U,V) = (1,1)
|
||||
.dout2(dout_12), // (U,V) = (1,2)
|
||||
.dout3(dout_13), // (U,V) = (1,3)
|
||||
.dout4(dout_14), // (U,V) = (1,4)
|
||||
.dout5(dout_15), // (U,V) = (1,5)
|
||||
.dout6(dout_16), // (U,V) = (1,6)
|
||||
.dout7(dout_17) // (U,V) = (1,7)
|
||||
);
|
||||
|
||||
// V = 2
|
||||
dctub #(coef_width, di_width, 3'h2)
|
||||
dct_block_2 (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.ddgo(ddgo),
|
||||
.x(sample_cnt[2:0]),
|
||||
.y(sample_cnt[5:3]),
|
||||
.ddin(ddin),
|
||||
.dout0(dout_20), // (U,V) = (2,0)
|
||||
.dout1(dout_21), // (U,V) = (2,1)
|
||||
.dout2(dout_22), // (U,V) = (2,2)
|
||||
.dout3(dout_23), // (U,V) = (2,3)
|
||||
.dout4(dout_24), // (U,V) = (2,4)
|
||||
.dout5(dout_25), // (U,V) = (2,5)
|
||||
.dout6(dout_26), // (U,V) = (2,6)
|
||||
.dout7(dout_27) // (U,V) = (2,7)
|
||||
);
|
||||
|
||||
// V = 3
|
||||
dctub #(coef_width, di_width, 3'h3)
|
||||
dct_block_3 (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.ddgo(ddgo),
|
||||
.x(sample_cnt[2:0]),
|
||||
.y(sample_cnt[5:3]),
|
||||
.ddin(ddin),
|
||||
.dout0(dout_30), // (U,V) = (3,0)
|
||||
.dout1(dout_31), // (U,V) = (3,1)
|
||||
.dout2(dout_32), // (U,V) = (3,2)
|
||||
.dout3(dout_33), // (U,V) = (3,3)
|
||||
.dout4(dout_34), // (U,V) = (3,4)
|
||||
.dout5(dout_35), // (U,V) = (3,5)
|
||||
.dout6(dout_36), // (U,V) = (3,6)
|
||||
.dout7(dout_37) // (U,V) = (3,7)
|
||||
);
|
||||
|
||||
// V = 4
|
||||
dctub #(coef_width, di_width, 3'h4)
|
||||
dct_block_4 (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.ddgo(ddgo),
|
||||
.x(sample_cnt[2:0]),
|
||||
.y(sample_cnt[5:3]),
|
||||
.ddin(ddin),
|
||||
.dout0(dout_40), // (U,V) = (4,0)
|
||||
.dout1(dout_41), // (U,V) = (4,1)
|
||||
.dout2(dout_42), // (U,V) = (4,2)
|
||||
.dout3(dout_43), // (U,V) = (4,3)
|
||||
.dout4(dout_44), // (U,V) = (4,4)
|
||||
.dout5(dout_45), // (U,V) = (4,5)
|
||||
.dout6(dout_46), // (U,V) = (4,6)
|
||||
.dout7(dout_47) // (U,V) = (4,7)
|
||||
);
|
||||
|
||||
// V = 5
|
||||
dctub #(coef_width, di_width, 3'h5)
|
||||
dct_block_5 (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.ddgo(ddgo),
|
||||
.x(sample_cnt[2:0]),
|
||||
.y(sample_cnt[5:3]),
|
||||
.ddin(ddin),
|
||||
.dout0(dout_50), // (U,V) = (5,0)
|
||||
.dout1(dout_51), // (U,V) = (5,1)
|
||||
.dout2(dout_52), // (U,V) = (5,2)
|
||||
.dout3(dout_53), // (U,V) = (5,3)
|
||||
.dout4(dout_54), // (U,V) = (5,4)
|
||||
.dout5(dout_55), // (U,V) = (5,5)
|
||||
.dout6(dout_56), // (U,V) = (5,6)
|
||||
.dout7(dout_57) // (U,V) = (5,7)
|
||||
);
|
||||
|
||||
// V = 6
|
||||
dctub #(coef_width, di_width, 3'h6)
|
||||
dct_block_6 (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.ddgo(ddgo),
|
||||
.x(sample_cnt[2:0]),
|
||||
.y(sample_cnt[5:3]),
|
||||
.ddin(ddin),
|
||||
.dout0(dout_60), // (U,V) = (6,0)
|
||||
.dout1(dout_61), // (U,V) = (6,1)
|
||||
.dout2(dout_62), // (U,V) = (6,2)
|
||||
.dout3(dout_63), // (U,V) = (6,3)
|
||||
.dout4(dout_64), // (U,V) = (6,4)
|
||||
.dout5(dout_65), // (U,V) = (6,5)
|
||||
.dout6(dout_66), // (U,V) = (6,6)
|
||||
.dout7(dout_67) // (U,V) = (6,7)
|
||||
);
|
||||
|
||||
// V = 7
|
||||
dctub #(coef_width, di_width, 3'h7)
|
||||
dct_block_7 (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.ddgo(ddgo),
|
||||
.x(sample_cnt[2:0]),
|
||||
.y(sample_cnt[5:3]),
|
||||
.ddin(ddin),
|
||||
.dout0(dout_70), // (U,V) = (7,0)
|
||||
.dout1(dout_71), // (U,V) = (7,1)
|
||||
.dout2(dout_72), // (U,V) = (7,2)
|
||||
.dout3(dout_73), // (U,V) = (7,3)
|
||||
.dout4(dout_74), // (U,V) = (7,4)
|
||||
.dout5(dout_75), // (U,V) = (7,5)
|
||||
.dout6(dout_76), // (U,V) = (7,6)
|
||||
.dout7(dout_77) // (U,V) = (7,7)
|
||||
);
|
||||
endmodule
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,123 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Discrete Cosine Transform, MAC unit ////
|
||||
//// ////
|
||||
//// Virtex-II: Block-Multiplier is used ////
|
||||
//// ////
|
||||
//// Author: Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// www.asics.ws ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// 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: dct_mac.v,v 1.3 2002-10-31 12:50:03 rherveille Exp $
|
||||
//
|
||||
// $Date: 2002-10-31 12:50:03 $
|
||||
// $Revision: 1.3 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.2 2002/10/23 09:06:59 rherveille
|
||||
// Improved many files.
|
||||
// Fixed some bugs in Run-Length-Encoder.
|
||||
// Removed dependency on ud_cnt and ro_cnt.
|
||||
// Started (Motion)JPEG hardware encoder project.
|
||||
//
|
||||
|
||||
//synopsys translate_off
|
||||
`include "timescale.v"
|
||||
//synopsys translate_on
|
||||
|
||||
module dct_mac(clk, ena, dclr, din, coef, result);
|
||||
|
||||
//
|
||||
// parameters
|
||||
//
|
||||
parameter dwidth = 8;
|
||||
parameter cwidth = 16;
|
||||
parameter mwidth = dwidth + cwidth; // multiplier result
|
||||
parameter rwidth = mwidth +3; // add 3 bits for growth
|
||||
|
||||
//
|
||||
// inputs & outputs
|
||||
//
|
||||
input clk; // clock input
|
||||
input ena; // clock enable
|
||||
input dclr; // start new mac (delayed 1 cycle)
|
||||
input [dwidth-1:0] din; // data input
|
||||
input [cwidth-1:0] coef; // coefficient input
|
||||
output [rwidth-1:0] result; // mac-result
|
||||
reg [rwidth -1:0] result;
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
wire [mwidth-1:0] idin;
|
||||
wire [mwidth-1:0] icoef;
|
||||
|
||||
reg [mwidth -1:0] mult_res /* synthesis syn_multstyle="block_mult" syn_pipeline=1*/ ;
|
||||
wire [rwidth -1:0] ext_mult_res;
|
||||
|
||||
|
||||
//
|
||||
// module body
|
||||
//
|
||||
assign icoef = { {(mwidth-cwidth){coef[cwidth-1]}}, coef};
|
||||
assign idin = { {(mwidth-dwidth){din[dwidth-1]}}, din};
|
||||
|
||||
// generate multiplier structure
|
||||
always @(posedge clk)
|
||||
if(ena)
|
||||
mult_res <= #1 icoef * idin;
|
||||
|
||||
assign ext_mult_res = { {3{mult_res[mwidth-1]}}, mult_res};
|
||||
|
||||
// generate adder structure
|
||||
always @(posedge clk)
|
||||
if(ena)
|
||||
if(dclr)
|
||||
result <= #1 ext_mult_res;
|
||||
else
|
||||
result <= #1 ext_mult_res + result;
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Discrete Cosine Transform Synthesis Test ////
|
||||
//// ////
|
||||
//// Author: Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// www.asics.ws ////
|
||||
//// ////
|
||||
//// Synthesis results: ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// 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: dct_syn.v,v 1.3 2002-10-31 12:50:03 rherveille Exp $
|
||||
//
|
||||
// $Date: 2002-10-31 12:50:03 $
|
||||
// $Revision: 1.3 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.2 2002/10/23 09:06:59 rherveille
|
||||
// Improved many files.
|
||||
// Fixed some bugs in Run-Length-Encoder.
|
||||
// Removed dependency on ud_cnt and ro_cnt.
|
||||
// Started (Motion)JPEG hardware encoder project.
|
||||
//
|
||||
//
|
||||
|
||||
// synopsys translate_off
|
||||
`include "timescale.v"
|
||||
// synopsys translate_on
|
||||
|
||||
module dct_syn(clk, ena, rst, dstrb, din, dout, den);
|
||||
|
||||
input clk;
|
||||
input ena;
|
||||
input rst;
|
||||
|
||||
input dstrb;
|
||||
input [7:0] din;
|
||||
|
||||
output [11:0] dout;
|
||||
output den;
|
||||
|
||||
//
|
||||
// DCT unit
|
||||
//
|
||||
|
||||
// As little as 11bits coefficients can be used while
|
||||
// all errors remain in the decimal bit range (dout[0])
|
||||
// total errors = 5(14bit resolution)
|
||||
// = 12(13bit resolution)
|
||||
// = 26(12bit resolution)
|
||||
// = 54(11bit resolution)
|
||||
fdct #(13) dut (
|
||||
.clk(clk),
|
||||
.ena(1'b1),
|
||||
.rst(rst),
|
||||
.dstrb(dstrb),
|
||||
.din(din),
|
||||
.dout(dout),
|
||||
.douten(den)
|
||||
);
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,106 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Discrete Cosine Transform Unit ////
|
||||
//// ////
|
||||
//// Author: Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// www.asics.ws ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// 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: dctu.v,v 1.3 2002-10-31 12:50:03 rherveille Exp $
|
||||
//
|
||||
// $Date: 2002-10-31 12:50:03 $
|
||||
// $Revision: 1.3 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.2 2002/10/23 09:06:59 rherveille
|
||||
// Improved many files.
|
||||
// Fixed some bugs in Run-Length-Encoder.
|
||||
// Removed dependency on ud_cnt and ro_cnt.
|
||||
// Started (Motion)JPEG hardware encoder project.
|
||||
//
|
||||
|
||||
|
||||
//synopsys translate_off
|
||||
`include "timescale.v"
|
||||
//synopsys translate_on
|
||||
|
||||
module dctu(clk, ena, ddgo, x, y, ddin, dout);
|
||||
|
||||
parameter coef_width = 16;
|
||||
parameter di_width = 8;
|
||||
parameter [2:0] v = 0;
|
||||
parameter [2:0] u = 0;
|
||||
|
||||
//
|
||||
// inputs & outputs
|
||||
//
|
||||
|
||||
input clk;
|
||||
input ena;
|
||||
input ddgo; // double delayed go signal
|
||||
input [2:0] x, y;
|
||||
|
||||
input [di_width:1] ddin; // delayed data input
|
||||
output [11:0] dout;
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
reg [ 31:0] coef;
|
||||
|
||||
wire [coef_width +10:0] result;
|
||||
`include "dct_cos_table.v"
|
||||
//
|
||||
// module body
|
||||
//
|
||||
|
||||
// hookup cosine-table
|
||||
always @(posedge clk)
|
||||
if(ena)
|
||||
coef <= #1 dct_cos_table(x, y, u, v);
|
||||
|
||||
// hookup dct-mac unit
|
||||
dct_mac #(8, coef_width)
|
||||
macu (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.dclr(ddgo),
|
||||
.din(ddin),
|
||||
.coef( coef[31:31 -coef_width +1] ),
|
||||
.result(result)
|
||||
);
|
||||
|
||||
assign dout = result[coef_width +10: coef_width -1];
|
||||
endmodule
|
|
@ -0,0 +1,169 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Discrete Cosine Transform, DCT unit block ////
|
||||
//// ////
|
||||
//// Author: Richard Herveille ////
|
||||
//// richard@asics.ws ////
|
||||
//// www.asics.ws ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// 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: dctub.v,v 1.3 2002-10-31 12:50:03 rherveille Exp $
|
||||
//
|
||||
// $Date: 2002-10-31 12:50:03 $
|
||||
// $Revision: 1.3 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.2 2002/10/23 09:06:59 rherveille
|
||||
// Improved many files.
|
||||
// Fixed some bugs in Run-Length-Encoder.
|
||||
// Removed dependency on ud_cnt and ro_cnt.
|
||||
// Started (Motion)JPEG hardware encoder project.
|
||||
//
|
||||
|
||||
|
||||
//synopsys translate_off
|
||||
`include "timescale.v"
|
||||
//synopsys translate_on
|
||||
|
||||
module dctub(clk, ena, ddgo, x, y, ddin,
|
||||
dout0, dout1, dout2, dout3, dout4, dout5, dout6, dout7);
|
||||
|
||||
parameter coef_width = 16;
|
||||
parameter di_width = 8;
|
||||
parameter [2:0] v = 3'h0;
|
||||
|
||||
//
|
||||
// inputs & outputs
|
||||
//
|
||||
input clk;
|
||||
input ena;
|
||||
input ddgo; // double delayed go strobe
|
||||
input [2:0] x, y;
|
||||
|
||||
input [di_width:1] ddin; // delayed data input
|
||||
output [11:0] dout0, dout1, dout2, dout3, dout4, dout5, dout6, dout7;
|
||||
|
||||
//
|
||||
// module body
|
||||
//
|
||||
|
||||
// Hookup DCT units
|
||||
dctu #(coef_width, di_width, v, 3'h0)
|
||||
dct_unit_0 (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.ddgo(ddgo),
|
||||
.x(x),
|
||||
.y(y),
|
||||
.ddin(ddin),
|
||||
.dout(dout0)
|
||||
);
|
||||
|
||||
dctu #(coef_width, di_width, v, 3'h1)
|
||||
dct_unit_1 (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.ddgo(ddgo),
|
||||
.x(x),
|
||||
.y(y),
|
||||
.ddin(ddin),
|
||||
.dout(dout1)
|
||||
);
|
||||
|
||||
dctu #(coef_width, di_width, v, 3'h2)
|
||||
dct_unit_2 (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.ddgo(ddgo),
|
||||
.x(x),
|
||||
.y(y),
|
||||
.ddin(ddin),
|
||||
.dout(dout2)
|
||||
);
|
||||
|
||||
dctu #(coef_width, di_width, v, 3'h3)
|
||||
dct_unit_3 (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.ddgo(ddgo),
|
||||
.x(x),
|
||||
.y(y),
|
||||
.ddin(ddin),
|
||||
.dout(dout3)
|
||||
);
|
||||
|
||||
dctu #(coef_width, di_width, v, 3'h4)
|
||||
dct_unit_4 (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.ddgo(ddgo),
|
||||
.x(x),
|
||||
.y(y),
|
||||
.ddin(ddin),
|
||||
.dout(dout4)
|
||||
);
|
||||
|
||||
dctu #(coef_width, di_width, v, 3'h5)
|
||||
dct_unit_5 (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.ddgo(ddgo),
|
||||
.x(x),
|
||||
.y(y),
|
||||
.ddin(ddin),
|
||||
.dout(dout5)
|
||||
);
|
||||
|
||||
dctu #(coef_width, di_width, v, 3'h6)
|
||||
dct_unit_6 (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.ddgo(ddgo),
|
||||
.x(x),
|
||||
.y(y),
|
||||
.ddin(ddin),
|
||||
.dout(dout6)
|
||||
);
|
||||
|
||||
dctu #(coef_width, di_width, v, 3'h7)
|
||||
dct_unit_7 (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.ddgo(ddgo),
|
||||
.x(x),
|
||||
.y(y),
|
||||
.ddin(ddin),
|
||||
.dout(dout7)
|
||||
);
|
||||
endmodule
|
|
@ -0,0 +1,292 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Forward Discrete Cosine Transform and ZigZag unit ////
|
||||
//// ////
|
||||
//// 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: fdct.v,v 1.3 2002-10-31 12:50:03 rherveille Exp $
|
||||
//
|
||||
// $Date: 2002-10-31 12:50:03 $
|
||||
// $Revision: 1.3 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.2 2002/10/23 09:06:59 rherveille
|
||||
// Improved many files.
|
||||
// Fixed some bugs in Run-Length-Encoder.
|
||||
// Removed dependency on ud_cnt and ro_cnt.
|
||||
// Started (Motion)JPEG hardware encoder project.
|
||||
//
|
||||
|
||||
|
||||
//synopsys translate_off
|
||||
`include "timescale.v"
|
||||
//synopsys translate_on
|
||||
|
||||
module fdct(clk, ena, rst, dstrb, din, dout, douten);
|
||||
|
||||
//
|
||||
// parameters
|
||||
//
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// ITU-T.81, ITU-T.83 & Coefficient resolution notes //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// Worst case error (all input values -128) is //
|
||||
// zero (i.e. no errors) when using 15bit coefficients //
|
||||
// //
|
||||
// Using less bits for the coefficients produces a biterror //
|
||||
// approx. equal to (15 - used_coefficient-bits). //
|
||||
// i.e. 14bit coefficients, errors in dout-bit[0] only //
|
||||
// 13bit coefficients, errors in dout-bits[1:0] //
|
||||
// 12bit coefficients, errors in dout-bits[2:0] etc. //
|
||||
// Tests with real non-continous tone image data have shown that //
|
||||
// even when using 13bit coefficients errors remain in the lsb //
|
||||
// only (i.e. dout-bit[0] //
|
||||
// //
|
||||
// The amount of coefficient-bits needed is dependent on the //
|
||||
// desired quality. //
|
||||
// The JPEG-standard compliance specs.(ITU-T.83) prescribe //
|
||||
// that the output of the combined DCT AND Quantization unit //
|
||||
// shall not exceed 1 for the desired quality. //
|
||||
// //
|
||||
// This means for high quantization levels, lesser bits //
|
||||
// for the DCT unit can be used. //
|
||||
// //
|
||||
// Looking at the recommended "quantization tables for generic //
|
||||
// compliance testing of DCT-based processes" (ITU-T.83 annex B) //
|
||||
// it can be noticed that relatively large quantization values //
|
||||
// are being used. Errors in the lower-order bits should //
|
||||
// therefore not be visible. //
|
||||
// For certain applications some of the lower-order bits could //
|
||||
// actually be discarded. When looking at the luminance and //
|
||||
// chrominance example quantization tables (ITU-T.81 annex K) //
|
||||
// it can be seen that the smallest quantization value is ten //
|
||||
// (qnt_val_min = 10). This means that the lowest 2bits can be //
|
||||
// discarded (set to zero '0') without having any effect on the //
|
||||
// final result. In this example 11 bit or 12 bit coefficients //
|
||||
// would be sufficient. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
parameter coef_width = 11;
|
||||
parameter di_width = 8;
|
||||
parameter do_width = 12;
|
||||
|
||||
//
|
||||
// inputs & outputs
|
||||
//
|
||||
input clk; // system clock
|
||||
input ena; // clock enable
|
||||
input rst; // active low asynchronous reset
|
||||
|
||||
input dstrb; // data-strobe. Present dstrb 1clk-cycle before data block
|
||||
input [di_width-1:0] din;
|
||||
output [do_width-1:0] dout;
|
||||
output douten; // data-out enable
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
|
||||
wire doe;
|
||||
|
||||
wire [do_width -1:0] // results from DCT module
|
||||
res00, res01, res02, res03, res04, res05, res06, res07,
|
||||
res10, res11, res12, res13, res14, res15, res16, res17,
|
||||
res20, res21, res22, res23, res24, res25, res26, res27,
|
||||
res30, res31, res32, res33, res34, res35, res36, res37,
|
||||
res40, res41, res42, res43, res44, res45, res46, res47,
|
||||
res50, res51, res52, res53, res54, res55, res56, res57,
|
||||
res60, res61, res62, res63, res64, res65, res66, res67,
|
||||
res70, res71, res72, res73, res74, res75, res76, res77;
|
||||
|
||||
|
||||
//
|
||||
// module body
|
||||
//
|
||||
|
||||
// Hookup DCT module
|
||||
dct #(coef_width, di_width, do_width)
|
||||
dct_mod(
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.rst(rst),
|
||||
.dstrb(dstrb),
|
||||
.din(din),
|
||||
.dout_00(res00),
|
||||
.dout_01(res01),
|
||||
.dout_02(res02),
|
||||
.dout_03(res03),
|
||||
.dout_04(res04),
|
||||
.dout_05(res05),
|
||||
.dout_06(res06),
|
||||
.dout_07(res07),
|
||||
.dout_10(res10),
|
||||
.dout_11(res11),
|
||||
.dout_12(res12),
|
||||
.dout_13(res13),
|
||||
.dout_14(res14),
|
||||
.dout_15(res15),
|
||||
.dout_16(res16),
|
||||
.dout_17(res17),
|
||||
.dout_20(res20),
|
||||
.dout_21(res21),
|
||||
.dout_22(res22),
|
||||
.dout_23(res23),
|
||||
.dout_24(res24),
|
||||
.dout_25(res25),
|
||||
.dout_26(res26),
|
||||
.dout_27(res27),
|
||||
.dout_30(res30),
|
||||
.dout_31(res31),
|
||||
.dout_32(res32),
|
||||
.dout_33(res33),
|
||||
.dout_34(res34),
|
||||
.dout_35(res35),
|
||||
.dout_36(res36),
|
||||
.dout_37(res37),
|
||||
.dout_40(res40),
|
||||
.dout_41(res41),
|
||||
.dout_42(res42),
|
||||
.dout_43(res43),
|
||||
.dout_44(res44),
|
||||
.dout_45(res45),
|
||||
.dout_46(res46),
|
||||
.dout_47(res47),
|
||||
.dout_50(res50),
|
||||
.dout_51(res51),
|
||||
.dout_52(res52),
|
||||
.dout_53(res53),
|
||||
.dout_54(res54),
|
||||
.dout_55(res55),
|
||||
.dout_56(res56),
|
||||
.dout_57(res57),
|
||||
.dout_60(res60),
|
||||
.dout_61(res61),
|
||||
.dout_62(res62),
|
||||
.dout_63(res63),
|
||||
.dout_64(res64),
|
||||
.dout_65(res65),
|
||||
.dout_66(res66),
|
||||
.dout_67(res67),
|
||||
.dout_70(res70),
|
||||
.dout_71(res71),
|
||||
.dout_72(res72),
|
||||
.dout_73(res73),
|
||||
.dout_74(res74),
|
||||
.dout_75(res75),
|
||||
.dout_76(res76),
|
||||
.dout_77(res77),
|
||||
.douten(doe)
|
||||
);
|
||||
|
||||
// Hookup ZigZag unit
|
||||
zigzag zigzag_mod(
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.dstrb(doe),
|
||||
.din_00(res00),
|
||||
.din_01(res01),
|
||||
.din_02(res02),
|
||||
.din_03(res03),
|
||||
.din_04(res04),
|
||||
.din_05(res05),
|
||||
.din_06(res06),
|
||||
.din_07(res07),
|
||||
.din_10(res10),
|
||||
.din_11(res11),
|
||||
.din_12(res12),
|
||||
.din_13(res13),
|
||||
.din_14(res14),
|
||||
.din_15(res15),
|
||||
.din_16(res16),
|
||||
.din_17(res17),
|
||||
.din_20(res20),
|
||||
.din_21(res21),
|
||||
.din_22(res22),
|
||||
.din_23(res23),
|
||||
.din_24(res24),
|
||||
.din_25(res25),
|
||||
.din_26(res26),
|
||||
.din_27(res27),
|
||||
.din_30(res30),
|
||||
.din_31(res31),
|
||||
.din_32(res32),
|
||||
.din_33(res33),
|
||||
.din_34(res34),
|
||||
.din_35(res35),
|
||||
.din_36(res36),
|
||||
.din_37(res37),
|
||||
.din_40(res40),
|
||||
.din_41(res41),
|
||||
.din_42(res42),
|
||||
.din_43(res43),
|
||||
.din_44(res44),
|
||||
.din_45(res45),
|
||||
.din_46(res46),
|
||||
.din_47(res47),
|
||||
.din_50(res50),
|
||||
.din_51(res51),
|
||||
.din_52(res52),
|
||||
.din_53(res53),
|
||||
.din_54(res54),
|
||||
.din_55(res55),
|
||||
.din_56(res56),
|
||||
.din_57(res57),
|
||||
.din_60(res60),
|
||||
.din_61(res61),
|
||||
.din_62(res62),
|
||||
.din_63(res63),
|
||||
.din_64(res64),
|
||||
.din_65(res65),
|
||||
.din_66(res66),
|
||||
.din_67(res67),
|
||||
.din_70(res70),
|
||||
.din_71(res71),
|
||||
.din_72(res72),
|
||||
.din_73(res73),
|
||||
.din_74(res74),
|
||||
.din_75(res75),
|
||||
.din_76(res76),
|
||||
.din_77(res77),
|
||||
.dout(dout),
|
||||
.douten(douten)
|
||||
);
|
||||
endmodule
|
|
@ -0,0 +1,201 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Zig-Zag Unit ////
|
||||
//// Performs zigzag-ing, as used by many DCT based encoders ////
|
||||
//// ////
|
||||
//// 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: zigzag.v,v 1.2 2002-10-23 09:06:59 rherveille Exp $
|
||||
//
|
||||
// $Date: 2002-10-23 09:06:59 $
|
||||
// $Revision: 1.2 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
`include "timescale.v"
|
||||
// synopsys translate_on
|
||||
|
||||
module zigzag(
|
||||
clk,
|
||||
ena,
|
||||
dstrb,
|
||||
din_00, din_01, din_02, din_03, din_04, din_05, din_06, din_07,
|
||||
din_10, din_11, din_12, din_13, din_14, din_15, din_16, din_17,
|
||||
din_20, din_21, din_22, din_23, din_24, din_25, din_26, din_27,
|
||||
din_30, din_31, din_32, din_33, din_34, din_35, din_36, din_37,
|
||||
din_40, din_41, din_42, din_43, din_44, din_45, din_46, din_47,
|
||||
din_50, din_51, din_52, din_53, din_54, din_55, din_56, din_57,
|
||||
din_60, din_61, din_62, din_63, din_64, din_65, din_66, din_67,
|
||||
din_70, din_71, din_72, din_73, din_74, din_75, din_76, din_77,
|
||||
dout,
|
||||
douten
|
||||
);
|
||||
|
||||
//
|
||||
// inputs & outputs
|
||||
//
|
||||
|
||||
input clk; // system clock
|
||||
input ena; // clock enable
|
||||
|
||||
input dstrb; // data-strobe. Present dstrb 1clk-cycle before data block
|
||||
input [11:0]
|
||||
din_00, din_01, din_02, din_03, din_04, din_05, din_06, din_07,
|
||||
din_10, din_11, din_12, din_13, din_14, din_15, din_16, din_17,
|
||||
din_20, din_21, din_22, din_23, din_24, din_25, din_26, din_27,
|
||||
din_30, din_31, din_32, din_33, din_34, din_35, din_36, din_37,
|
||||
din_40, din_41, din_42, din_43, din_44, din_45, din_46, din_47,
|
||||
din_50, din_51, din_52, din_53, din_54, din_55, din_56, din_57,
|
||||
din_60, din_61, din_62, din_63, din_64, din_65, din_66, din_67,
|
||||
din_70, din_71, din_72, din_73, din_74, din_75, din_76, din_77;
|
||||
output [11:0] dout;
|
||||
output douten; // data-out enable
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
|
||||
reg ld_zigzag;
|
||||
reg [11:0] sresult [63:0]; // store results for zig-zagging
|
||||
|
||||
//
|
||||
// module body
|
||||
//
|
||||
|
||||
always @(posedge clk)
|
||||
if(ena)
|
||||
ld_zigzag <= #1 dstrb;
|
||||
|
||||
assign douten = ld_zigzag;
|
||||
|
||||
|
||||
//
|
||||
// Generate zig-zag structure
|
||||
//
|
||||
// This implicates that the quantization step be performed after
|
||||
// the zig-zagging.
|
||||
//
|
||||
// 0: 1: 2: 3: 4: 5: 6: 7: 0: 1: 2: 3: 4: 5: 6: 7:
|
||||
// 0: 63 62 58 57 49 48 36 35 3f 3e 3a 39 31 30 24 23
|
||||
// 1: 61 59 56 50 47 37 34 21 3d 3b 38 32 2f 25 22 15
|
||||
// 2: 60 55 51 46 38 33 22 20 3c 37 33 2e 26 21 16 14
|
||||
// 3: 54 52 45 39 32 23 19 10 36 34 2d 27 20 17 13 0a
|
||||
// 4: 53 44 40 31 24 18 11 09 35 2c 28 1f 18 12 0b 09
|
||||
// 5: 43 41 30 25 17 12 08 03 2b 29 1e 19 11 0c 08 03
|
||||
// 6: 42 29 26 16 13 07 04 02 2a 1d 1a 10 0d 07 04 02
|
||||
// 7: 28 27 15 14 06 05 01 00 1c 1b 0f 0e 06 05 01 00
|
||||
//
|
||||
// zig-zag the DCT results
|
||||
integer n;
|
||||
|
||||
always @(posedge clk)
|
||||
if(ena)
|
||||
if(ld_zigzag) // reload results-register file
|
||||
begin
|
||||
sresult[63] <= #1 din_00;
|
||||
sresult[62] <= #1 din_01;
|
||||
sresult[61] <= #1 din_10;
|
||||
sresult[60] <= #1 din_20;
|
||||
sresult[59] <= #1 din_11;
|
||||
sresult[58] <= #1 din_02;
|
||||
sresult[57] <= #1 din_03;
|
||||
sresult[56] <= #1 din_12;
|
||||
sresult[55] <= #1 din_21;
|
||||
sresult[54] <= #1 din_30;
|
||||
sresult[53] <= #1 din_40;
|
||||
sresult[52] <= #1 din_31;
|
||||
sresult[51] <= #1 din_22;
|
||||
sresult[50] <= #1 din_13;
|
||||
sresult[49] <= #1 din_04;
|
||||
sresult[48] <= #1 din_05;
|
||||
sresult[47] <= #1 din_14;
|
||||
sresult[46] <= #1 din_23;
|
||||
sresult[45] <= #1 din_32;
|
||||
sresult[44] <= #1 din_41;
|
||||
sresult[43] <= #1 din_50;
|
||||
sresult[42] <= #1 din_60;
|
||||
sresult[41] <= #1 din_51;
|
||||
sresult[40] <= #1 din_42;
|
||||
sresult[39] <= #1 din_33;
|
||||
sresult[38] <= #1 din_24;
|
||||
sresult[37] <= #1 din_15;
|
||||
sresult[36] <= #1 din_06;
|
||||
sresult[35] <= #1 din_07;
|
||||
sresult[34] <= #1 din_16;
|
||||
sresult[33] <= #1 din_25;
|
||||
sresult[32] <= #1 din_34;
|
||||
sresult[31] <= #1 din_43;
|
||||
sresult[30] <= #1 din_52;
|
||||
sresult[29] <= #1 din_61;
|
||||
sresult[28] <= #1 din_70;
|
||||
sresult[27] <= #1 din_71;
|
||||
sresult[26] <= #1 din_62;
|
||||
sresult[25] <= #1 din_53;
|
||||
sresult[24] <= #1 din_44;
|
||||
sresult[23] <= #1 din_35;
|
||||
sresult[22] <= #1 din_26;
|
||||
sresult[21] <= #1 din_17;
|
||||
sresult[20] <= #1 din_27;
|
||||
sresult[19] <= #1 din_36;
|
||||
sresult[18] <= #1 din_45;
|
||||
sresult[17] <= #1 din_54;
|
||||
sresult[16] <= #1 din_63;
|
||||
sresult[15] <= #1 din_72;
|
||||
sresult[14] <= #1 din_73;
|
||||
sresult[13] <= #1 din_64;
|
||||
sresult[12] <= #1 din_55;
|
||||
sresult[11] <= #1 din_46;
|
||||
sresult[10] <= #1 din_37;
|
||||
sresult[09] <= #1 din_47;
|
||||
sresult[08] <= #1 din_56;
|
||||
sresult[07] <= #1 din_65;
|
||||
sresult[06] <= #1 din_74;
|
||||
sresult[05] <= #1 din_75;
|
||||
sresult[04] <= #1 din_66;
|
||||
sresult[03] <= #1 din_57;
|
||||
sresult[02] <= #1 din_67;
|
||||
sresult[01] <= #1 din_76;
|
||||
sresult[00] <= #1 din_77;
|
||||
end
|
||||
else // shift results out
|
||||
for (n=1; n<=63; n=n+1) // do not change sresult[0]
|
||||
sresult[n] <= #1 sresult[n -1];
|
||||
|
||||
assign dout = sresult[63];
|
||||
endmodule
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,63 @@
|
|||
|
||||
/*--------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------
|
||||
-- File Name : diffeq.v
|
||||
-- Author(s) : P. Sridhar
|
||||
-- Affiliation : Laboratory for Digital Design Environments
|
||||
-- Department of Electrical & Computer Engineering
|
||||
-- University of Cincinnati
|
||||
-- Date Created : June 1991.
|
||||
-- Introduction : Behavioral description of a differential equation
|
||||
-- solver written in a synthesizable subset of VHDL.
|
||||
-- Source : Written in HardwareC by Rajesh Gupta, Stanford Univ.
|
||||
-- Obtained from the Highlevel Synthesis Workshop
|
||||
-- Repository.
|
||||
--
|
||||
-- Modified For Synthesis by Jay(anta) Roy, University of Cincinnati.
|
||||
-- Date Modified : Sept, 91.
|
||||
--
|
||||
-- Disclaimer : This comes with absolutely no guarantees of any
|
||||
-- kind (just stating the obvious ...)
|
||||
--
|
||||
-- Acknowledgement : The Distributed Synthesis Systems research at
|
||||
-- the Laboratory for Digital Design Environments,
|
||||
-- University of Cincinnati, is sponsored in part
|
||||
-- by the Defense Advanced Research Projects Agency
|
||||
-- under order number 7056 monitored by the Federal
|
||||
-- Bureau of Investigation under contract number
|
||||
-- J-FBI-89-094.
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------*/
|
||||
module diffeq_f_systemC(aport, dxport, xport, yport, uport, clk, reset);
|
||||
|
||||
input clk;
|
||||
input reset;
|
||||
input [31:0]aport;
|
||||
input [31:0]dxport;
|
||||
output [31:0]xport;
|
||||
output [31:0]yport;
|
||||
output [31:0]uport;
|
||||
reg [31:0]xport;
|
||||
reg [31:0]yport;
|
||||
reg [31:0]uport;
|
||||
wire [31:0]temp;
|
||||
|
||||
assign temp = uport * dxport;
|
||||
always @(posedge clk )
|
||||
begin
|
||||
if (reset == 1'b1)
|
||||
begin
|
||||
xport <= 0;
|
||||
yport <= 0;
|
||||
uport <= 0;
|
||||
end
|
||||
else
|
||||
if (xport < aport)
|
||||
begin
|
||||
xport <= xport + dxport;
|
||||
yport <= yport + temp;//(uport * dxport);
|
||||
uport <= (uport - (temp/*(uport * dxport)*/ * (5 * xport))) - (dxport * (3 * yport));
|
||||
end
|
||||
end
|
||||
endmodule
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,589 @@
|
|||
// -----------------------------------------------------------------------------
|
||||
// title : Sensor Manager Statemachine
|
||||
// project : ULP Sensor Hub
|
||||
// -----------------------------------------------------------------------------
|
||||
// file : StateMachine.v
|
||||
// author : Glen Gomes
|
||||
// company : QuickLogic Corp
|
||||
// created : 2013/12/06
|
||||
// last update : 2013/12/06
|
||||
// platform : PolarPro III
|
||||
// standard : Verilog 2001
|
||||
// -----------------------------------------------------------------------------
|
||||
// description: The Sensor Manger Statemachine is responsible for controlling the
|
||||
// operations of the Sensor Manager. These include performing
|
||||
// transfers between Sensor Memory and various registers.
|
||||
// -----------------------------------------------------------------------------
|
||||
// copyright (c) 2013
|
||||
// -----------------------------------------------------------------------------
|
||||
// revisions :
|
||||
// date version author description
|
||||
// 2013/12/06 1.0 Glen Gomes created
|
||||
// -----------------------------------------------------------------------------
|
||||
// Comments: This solution is specifically for use with the QuickLogic
|
||||
// PolarPro III device.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
`timescale 1ns/10ps
|
||||
|
||||
module StateMachine (
|
||||
|
||||
CLK_IN,
|
||||
RESET_IN,
|
||||
|
||||
RUNTIME_ADDRESS,
|
||||
CONTROL_JUMP_REG_DCD,
|
||||
SAVE_REG_2_MEM,
|
||||
|
||||
WB_ACK_I,
|
||||
WB_BUSY_I,
|
||||
WB_BUSY_POLL_I,
|
||||
|
||||
WB_WE_O,
|
||||
WB_STB_O,
|
||||
WB_CYC_O,
|
||||
|
||||
SM_CNTL_REG_RUN,
|
||||
SM_CNTL_INIT_SEQ,
|
||||
SM_READ_DATA,
|
||||
|
||||
SM_INSTR_PTR,
|
||||
SM_READ_SELECT,
|
||||
|
||||
SM_WRITE_SELECT,
|
||||
|
||||
SM_BUSY
|
||||
|
||||
);
|
||||
|
||||
|
||||
//-----Port Signals--------------------
|
||||
//
|
||||
|
||||
input CLK_IN;
|
||||
input RESET_IN;
|
||||
|
||||
input [7:0] RUNTIME_ADDRESS;
|
||||
input CONTROL_JUMP_REG_DCD;
|
||||
input SAVE_REG_2_MEM;
|
||||
|
||||
input WB_ACK_I;
|
||||
input WB_BUSY_I;
|
||||
input WB_BUSY_POLL_I;
|
||||
|
||||
output WB_WE_O;
|
||||
output WB_STB_O;
|
||||
output WB_CYC_O;
|
||||
|
||||
input SM_CNTL_REG_RUN;
|
||||
input SM_CNTL_INIT_SEQ;
|
||||
input [7:0] SM_READ_DATA;
|
||||
|
||||
output [7:0] SM_INSTR_PTR;
|
||||
output SM_READ_SELECT;
|
||||
|
||||
output SM_WRITE_SELECT;
|
||||
|
||||
output SM_BUSY;
|
||||
|
||||
|
||||
wire CLK_IN;
|
||||
wire RESET_IN;
|
||||
|
||||
wire [7:0] RUNTIME_ADDRESS;
|
||||
wire CONTROL_JUMP_REG_DCD;
|
||||
wire SAVE_REG_2_MEM;
|
||||
|
||||
wire WB_ACK_I;
|
||||
wire WB_BUSY_I;
|
||||
wire WB_BUSY_POLL_I;
|
||||
|
||||
reg WB_WE_O;
|
||||
reg wb_we_o_nxt;
|
||||
|
||||
reg WB_STB_O;
|
||||
reg wb_stb_o_nxt;
|
||||
|
||||
reg WB_CYC_O;
|
||||
reg wb_cyc_o_nxt;
|
||||
|
||||
wire SM_CNTL_REG_RUN;
|
||||
wire SM_CNTL_INIT_SEQ;
|
||||
wire [7:0] SM_READ_DATA;
|
||||
|
||||
reg [7:0] SM_INSTR_PTR;
|
||||
reg [7:0] sm_instr_ptr_nxt;
|
||||
|
||||
reg SM_READ_SELECT;
|
||||
reg sm_read_select_nxt;
|
||||
|
||||
reg SM_WRITE_SELECT;
|
||||
reg sm_write_select_nxt;
|
||||
|
||||
reg SM_BUSY;
|
||||
reg sm_busy_nxt;
|
||||
|
||||
//-----Internal Signals--------------------
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// Define the Statemachine registers
|
||||
//
|
||||
reg [3:0] sensor_manager_sm;
|
||||
reg [3:0] sensor_manager_sm_nxt;
|
||||
|
||||
|
||||
//
|
||||
// Define the Instruction Pointer variables
|
||||
//
|
||||
|
||||
reg sm_instr_ptr_ce;
|
||||
reg sm_instr_ptr_ce_nxt;
|
||||
|
||||
reg sm_instr_ptr_ld;
|
||||
reg sm_instr_ptr_ld_nxt;
|
||||
|
||||
reg sm_instr_ptr_sel;
|
||||
reg sm_instr_ptr_sel_nxt;
|
||||
|
||||
|
||||
|
||||
//------Define Parameters---------
|
||||
//
|
||||
|
||||
//
|
||||
// Define the Sensor Manager Statemachine States
|
||||
//
|
||||
// Note: These states are chosen to allow for overlap of various signals
|
||||
// during operation. This overlap should help reduce timing
|
||||
// dependancies.
|
||||
//
|
||||
parameter SM_IDLE = 4'h0;
|
||||
parameter SM_INC_PTR = 4'h1;
|
||||
parameter SM_INST_RD = 4'h2;
|
||||
//parameter SM_INST_DCD = 4'h3; // Note: Will be used for TimeStamp Support in a future design
|
||||
parameter SM_REG_WR = 4'h4;
|
||||
parameter SM_REG_RD = 4'h5;
|
||||
parameter SM_WAIT_BUSY_ON = 4'h6;
|
||||
parameter SM_WAIT_BUSY_OFF = 4'h7;
|
||||
|
||||
|
||||
//
|
||||
// Sensor Manager Initialization Start Address
|
||||
//
|
||||
// Note: The previous IP used the reset of the "RuntimeAddress" register to
|
||||
// select the sensor initialization code. This value explicity selects
|
||||
// the value for the start (or re-start) of initialization.
|
||||
//
|
||||
parameter SM_INIT_INSTR_ADR = 8'h0; // Address for the start in initialization instructions
|
||||
|
||||
|
||||
//------Logic Operations----------
|
||||
//
|
||||
|
||||
//
|
||||
// Define the Instruction Pointer
|
||||
//
|
||||
// Note: This pointer can start at either the sensor initialization code start
|
||||
// address or the run-time code start address.
|
||||
//
|
||||
always @( SM_INSTR_PTR or
|
||||
sm_instr_ptr_ld or
|
||||
sm_instr_ptr_ce or
|
||||
sm_instr_ptr_sel or
|
||||
SM_READ_DATA or
|
||||
CONTROL_JUMP_REG_DCD or
|
||||
RUNTIME_ADDRESS
|
||||
)
|
||||
begin
|
||||
case({sm_instr_ptr_ld, sm_instr_ptr_ce})
|
||||
2'b00: sm_instr_ptr_nxt <= SM_INSTR_PTR; // Hold Current Value
|
||||
2'b01: sm_instr_ptr_nxt <= SM_INSTR_PTR + 1'b1; // Increment to the next address
|
||||
2'b10:
|
||||
begin
|
||||
case({CONTROL_JUMP_REG_DCD, sm_instr_ptr_sel})
|
||||
2'b00: sm_instr_ptr_nxt <= SM_INIT_INSTR_ADR; // Initialization Code Address
|
||||
2'b01: sm_instr_ptr_nxt <= RUNTIME_ADDRESS; // Run-time Code Address
|
||||
2'b10: sm_instr_ptr_nxt <= SM_READ_DATA[7:0]; // Jump Address
|
||||
2'b11: sm_instr_ptr_nxt <= SM_READ_DATA[7:0]; // Jump Address
|
||||
endcase
|
||||
end
|
||||
2'b11: sm_instr_ptr_nxt <= SM_INSTR_PTR; // Hold Current Value
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// Define the registers associated with the Sensor Manager Statemachine
|
||||
//
|
||||
always @(posedge CLK_IN or posedge RESET_IN)
|
||||
begin
|
||||
if (RESET_IN)
|
||||
begin
|
||||
sensor_manager_sm <= SM_IDLE;
|
||||
|
||||
SM_INSTR_PTR <= 8'h0;
|
||||
sm_instr_ptr_ce <= 1'b0;
|
||||
sm_instr_ptr_ld <= 1'b0;
|
||||
sm_instr_ptr_sel <= 1'b0;
|
||||
|
||||
WB_WE_O <= 1'b0;
|
||||
WB_STB_O <= 1'b0;
|
||||
WB_CYC_O <= 1'b0;
|
||||
|
||||
SM_READ_SELECT <= 1'b0;
|
||||
SM_WRITE_SELECT <= 1'b0;
|
||||
|
||||
SM_BUSY <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
sensor_manager_sm <= sensor_manager_sm_nxt;
|
||||
|
||||
SM_INSTR_PTR <= sm_instr_ptr_nxt;
|
||||
sm_instr_ptr_ce <= sm_instr_ptr_ce_nxt;
|
||||
sm_instr_ptr_ld <= sm_instr_ptr_ld_nxt;
|
||||
sm_instr_ptr_sel <= sm_instr_ptr_sel_nxt;
|
||||
|
||||
WB_WE_O <= wb_we_o_nxt;
|
||||
WB_STB_O <= wb_stb_o_nxt;
|
||||
WB_CYC_O <= wb_cyc_o_nxt;
|
||||
|
||||
SM_READ_SELECT <= sm_read_select_nxt;
|
||||
SM_WRITE_SELECT <= sm_write_select_nxt;
|
||||
|
||||
SM_BUSY <= sm_busy_nxt;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Define the Sensor Manager Statemachine
|
||||
//
|
||||
always @( sensor_manager_sm or
|
||||
SM_CNTL_INIT_SEQ or
|
||||
SM_CNTL_REG_RUN or
|
||||
CONTROL_JUMP_REG_DCD or
|
||||
SAVE_REG_2_MEM or
|
||||
WB_BUSY_I or
|
||||
WB_BUSY_POLL_I or
|
||||
WB_ACK_I
|
||||
)
|
||||
begin
|
||||
case(sensor_manager_sm)
|
||||
SM_IDLE:
|
||||
begin
|
||||
case({SM_CNTL_INIT_SEQ, SM_CNTL_REG_RUN})
|
||||
2'b00: // No Activity
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_IDLE;
|
||||
|
||||
sm_busy_nxt <= 1'b0;
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||
end
|
||||
2'b01: // Start at the Sensor Run-Time Code
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||
|
||||
sm_busy_nxt <= 1'b1;
|
||||
sm_instr_ptr_ld_nxt <= 1'b1;
|
||||
sm_instr_ptr_sel_nxt <= 1'b1;
|
||||
end
|
||||
2'b10: // No Activity
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_IDLE;
|
||||
|
||||
sm_busy_nxt <= 1'b0;
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||
end
|
||||
2'b11: // Start at the Sensor Initialization Code
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||
|
||||
sm_busy_nxt <= 1'b1;
|
||||
sm_instr_ptr_ld_nxt <= 1'b1;
|
||||
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||
end
|
||||
endcase
|
||||
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_read_select_nxt <= 1'b0;
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
SM_INC_PTR:
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_INST_RD;
|
||||
|
||||
sm_busy_nxt <= 1'b1;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||
|
||||
sm_read_select_nxt <= 1'b1;
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
SM_INST_RD:
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_REG_WR;
|
||||
|
||||
sm_busy_nxt <= 1'b1;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||
|
||||
sm_read_select_nxt <= 1'b0;
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b1;
|
||||
wb_stb_o_nxt <= 1'b1;
|
||||
wb_cyc_o_nxt <= 1'b1;
|
||||
end
|
||||
SM_REG_WR:
|
||||
begin
|
||||
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||
|
||||
sm_read_select_nxt <= 1'b0;
|
||||
|
||||
case(SM_CNTL_REG_RUN)
|
||||
1'b0: // A write of "0" to bit "0" of the Command register at address "0" turns off
|
||||
// the Sensor Manager's Statemachine
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_IDLE;
|
||||
|
||||
sm_busy_nxt <= 1'b0;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
1'b1: // Sensor Manager Statemachine is not stopped; continue processing
|
||||
begin
|
||||
sm_busy_nxt <= 1'b1;
|
||||
|
||||
case({WB_BUSY_POLL_I, WB_ACK_I})
|
||||
2'b00: // Wait for Wish Bone Acknowledge and no need to wait for transfer complete
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_REG_WR;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b1;
|
||||
wb_stb_o_nxt <= 1'b1;
|
||||
wb_cyc_o_nxt <= 1'b1;
|
||||
end
|
||||
2'b01: // Wish Bone Acknowledge Received and no need to wait for transfer complete
|
||||
begin
|
||||
case(SAVE_REG_2_MEM)
|
||||
1'b0:
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= CONTROL_JUMP_REG_DCD;
|
||||
sm_instr_ptr_ce_nxt <= ~CONTROL_JUMP_REG_DCD;
|
||||
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
1'b1:
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_REG_RD;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_write_select_nxt <= 1'b1;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
wb_stb_o_nxt <= 1'b1;
|
||||
wb_cyc_o_nxt <= 1'b1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
2'b10: // Wait for Wish Bone Acknowledge and will need to wait for transfer complete
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_REG_WR;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b1;
|
||||
wb_stb_o_nxt <= 1'b1;
|
||||
wb_cyc_o_nxt <= 1'b1;
|
||||
end
|
||||
2'b11: // Acknowledge received but need to wait for transfer complete
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_WAIT_BUSY_ON;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
endcase
|
||||
end
|
||||
SM_REG_RD:
|
||||
begin
|
||||
sm_busy_nxt <= 1'b1;
|
||||
|
||||
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||
|
||||
sm_read_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
|
||||
case(WB_ACK_I)
|
||||
1'b0: // Waiting for Wish Bone Acknowledge
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_REG_RD;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
|
||||
sm_write_select_nxt <= 1'b1;
|
||||
|
||||
wb_stb_o_nxt <= 1'b1;
|
||||
wb_cyc_o_nxt <= 1'b1;
|
||||
end
|
||||
1'b1: // Got Wish Bone Acknowledge
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= CONTROL_JUMP_REG_DCD;
|
||||
sm_instr_ptr_ce_nxt <= ~CONTROL_JUMP_REG_DCD;
|
||||
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
SM_WAIT_BUSY_ON:
|
||||
begin
|
||||
sm_busy_nxt <= 1'b1;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||
|
||||
sm_read_select_nxt <= 1'b0;
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
|
||||
case(WB_BUSY_I)
|
||||
1'b0: sensor_manager_sm_nxt <= SM_WAIT_BUSY_ON; // Wait for Busy from I/F
|
||||
1'b1: sensor_manager_sm_nxt <= SM_WAIT_BUSY_OFF; // Got Busy from I/F
|
||||
endcase
|
||||
end
|
||||
SM_WAIT_BUSY_OFF:
|
||||
begin
|
||||
sm_busy_nxt <= 1'b1;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||
|
||||
sm_read_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
|
||||
case({SAVE_REG_2_MEM, WB_BUSY_I})
|
||||
2'b00: // Wishbone transfer complete; no need to write anything to Sensor Manager Memory
|
||||
//
|
||||
// Note: Writes to the command register do not enter this state.
|
||||
// Therefore, there is no need to check for the end of processing.
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_INC_PTR;
|
||||
|
||||
sm_instr_ptr_ce_nxt <= 1'b1;
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
2'b01: // Wait for Wishbone transfer to complete
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_WAIT_BUSY_OFF;
|
||||
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
2'b10: // Wishbone transfer complete; Write resulting register value to Sensor Manager Memory
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_REG_RD;
|
||||
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
sm_write_select_nxt <= 1'b1;
|
||||
|
||||
wb_stb_o_nxt <= 1'b1;
|
||||
wb_cyc_o_nxt <= 1'b1;
|
||||
end
|
||||
2'b11: // Wait for Wishbone transfer to complete
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_WAIT_BUSY_OFF;
|
||||
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
default:
|
||||
begin
|
||||
sensor_manager_sm_nxt <= SM_IDLE;
|
||||
|
||||
sm_busy_nxt <= 1'b0;
|
||||
|
||||
sm_instr_ptr_ld_nxt <= 1'b0;
|
||||
sm_instr_ptr_ce_nxt <= 1'b0;
|
||||
sm_instr_ptr_sel_nxt <= 1'b0;
|
||||
|
||||
sm_read_select_nxt <= 1'b0;
|
||||
sm_write_select_nxt <= 1'b0;
|
||||
|
||||
wb_we_o_nxt <= 1'b0;
|
||||
wb_stb_o_nxt <= 1'b0;
|
||||
wb_cyc_o_nxt <= 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,598 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// 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.14 2009-01-20 10:25:29 rherveille Exp $
|
||||
//
|
||||
// $Date: 2009-01-20 10:25:29 $
|
||||
// $Revision: 1.14 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: $
|
||||
// Revision 1.14 2009/01/20 10:25:29 rherveille
|
||||
// Added clock synchronization logic
|
||||
// Fixed slave_wait signal
|
||||
//
|
||||
// Revision 1.13 2009/01/19 20:29:26 rherveille
|
||||
// Fixed synopsys miss spell (synopsis)
|
||||
// Fixed cr[0] register width
|
||||
// Fixed ! usage instead of ~
|
||||
// Fixed bit controller parameter width to 18bits
|
||||
//
|
||||
// Revision 1.12 2006/09/04 09:08:13 rherveille
|
||||
// fixed short scl high pulse after clock stretch
|
||||
// fixed slave model not returning correct '(n)ack' signal
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// QuickLogic Change History:
|
||||
//
|
||||
// Date: February 11, 2014
|
||||
// Engineer: Anthony Le
|
||||
// Issue: i2c master generates back to back stop conditions that violate i2c protocol
|
||||
// Change:
|
||||
// 1. Move the generation of cmd_ack to one clock earlier in stop_c state
|
||||
// 2. Change the condition to unset (set to 0) for cmd_ack in stop_d state
|
||||
//
|
||||
// synopsys translate_off
|
||||
// synopsys translate_on
|
||||
`timescale 1ns / 10ps
|
||||
|
||||
`include "i2c_master_defines.v"
|
||||
|
||||
module i2c_master_bit_ctrl (
|
||||
input clk, // system clock
|
||||
input rst, // synchronous active high reset
|
||||
input Reset, // asynchronous active low reset
|
||||
input ena, // core enable signal
|
||||
|
||||
input [15:0] clk_cnt, // clock prescale value
|
||||
|
||||
input [ 3:0] cmd, // command (from byte controller)
|
||||
output reg cmd_ack, // command complete acknowledge
|
||||
output reg busy, // i2c bus busy
|
||||
output reg al, // i2c bus arbitration lost
|
||||
|
||||
input din,
|
||||
output reg dout,
|
||||
|
||||
input scl_i, // i2c clock line input
|
||||
output scl_o, // i2c clock line output
|
||||
output reg scl_oen, // i2c clock line output enable (active low)
|
||||
input sda_i, // i2c data line input
|
||||
output sda_o, // i2c data line output
|
||||
output reg sda_oen, // i2c data line output enable (active low)
|
||||
output TP1,
|
||||
output TP2
|
||||
);
|
||||
|
||||
|
||||
//
|
||||
// variable declarations
|
||||
//
|
||||
|
||||
reg [ 1:0] cSCL, cSDA; // capture SCL and SDA
|
||||
reg [ 2:0] fSCL, fSDA; // SCL and SDA filter inputs
|
||||
reg sSCL, sSDA; // filtered and synchronized SCL and SDA inputs
|
||||
reg dSCL, dSDA; // delayed versions of sSCL and sSDA
|
||||
reg dscl_oen; // delayed scl_oen
|
||||
reg sda_chk; // check SDA output (Multi-master arbitration)
|
||||
reg clk_en; // clock generation signals
|
||||
reg slave_wait; // slave inserts wait states
|
||||
reg [15:0] cnt; // clock divider counter (synthesis)
|
||||
reg [13:0] filter_cnt; // clock divider for filter
|
||||
|
||||
assign TP1 = cnt[0];
|
||||
assign TP2 = cnt[1];
|
||||
|
||||
// state machine variable
|
||||
reg [17: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;
|
||||
|
||||
// slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low
|
||||
// slave_wait remains asserted until the slave releases SCL
|
||||
always @(posedge clk or posedge Reset)
|
||||
if (Reset) slave_wait <= 1'b0;
|
||||
else slave_wait <= (scl_oen & ~dscl_oen & ~sSCL) | (slave_wait & ~sSCL);
|
||||
|
||||
// master drives SCL high, but another master pulls it low
|
||||
// master start counting down its low cycle now (clock synchronization)
|
||||
wire scl_sync = dSCL & ~sSCL & scl_oen;
|
||||
|
||||
|
||||
// generate clk enable signal
|
||||
always @(posedge clk or posedge Reset)
|
||||
if (Reset)
|
||||
begin
|
||||
cnt <= #1 16'h0;
|
||||
clk_en <= #1 1'b1;
|
||||
end
|
||||
else if (rst || ~|cnt || !ena || scl_sync)
|
||||
begin
|
||||
cnt <= #1 clk_cnt;
|
||||
clk_en <= #1 1'b1;
|
||||
end
|
||||
else if (slave_wait)
|
||||
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
|
||||
|
||||
// capture SDA and SCL
|
||||
// reduce metastability risk
|
||||
always @(posedge clk or posedge Reset)
|
||||
if (Reset)
|
||||
begin
|
||||
cSCL <= #1 2'b00;
|
||||
cSDA <= #1 2'b00;
|
||||
end
|
||||
else if (rst)
|
||||
begin
|
||||
cSCL <= #1 2'b00;
|
||||
cSDA <= #1 2'b00;
|
||||
end
|
||||
else
|
||||
begin
|
||||
cSCL <= {cSCL[0],scl_i};
|
||||
cSDA <= {cSDA[0],sda_i};
|
||||
end
|
||||
|
||||
|
||||
// filter SCL and SDA signals; (attempt to) remove glitches
|
||||
always @(posedge clk or posedge Reset)
|
||||
if (Reset ) filter_cnt <= 14'h0;
|
||||
else if (rst || !ena ) filter_cnt <= 14'h0;
|
||||
else if (~|filter_cnt) filter_cnt <= clk_cnt >> 2; //16x I2C bus frequency
|
||||
else filter_cnt <= filter_cnt -1;
|
||||
|
||||
|
||||
always @(posedge clk or posedge Reset)
|
||||
if (Reset)
|
||||
begin
|
||||
fSCL <= 3'b111;
|
||||
fSDA <= 3'b111;
|
||||
end
|
||||
else if (rst)
|
||||
begin
|
||||
fSCL <= 3'b111;
|
||||
fSDA <= 3'b111;
|
||||
end
|
||||
else if (~|filter_cnt)
|
||||
begin
|
||||
fSCL <= {fSCL[1:0],cSCL[1]};
|
||||
fSDA <= {fSDA[1:0],cSDA[1]};
|
||||
end
|
||||
|
||||
|
||||
// generate filtered SCL and SDA signals
|
||||
always @(posedge clk or posedge Reset)
|
||||
if (Reset)
|
||||
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 &fSCL[2:1] | &fSCL[1:0] | (fSCL[2] & fSCL[0]);
|
||||
sSDA <= #1 &fSDA[2:1] | &fSDA[1:0] | (fSDA[2] & fSDA[0]);
|
||||
|
||||
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
|
||||
reg sta_condition;
|
||||
reg sto_condition;
|
||||
always @(posedge clk or posedge Reset)
|
||||
if (Reset)
|
||||
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 posedge Reset)
|
||||
if (Reset) 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 posedge Reset)
|
||||
if (Reset)
|
||||
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 posedge Reset)
|
||||
if (Reset)
|
||||
al <= #1 1'b0;
|
||||
else if (rst)
|
||||
al <= #1 1'b0;
|
||||
else
|
||||
al <= 0;
|
||||
// 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 [17:0] idle = 18'b0_0000_0000_0000_0000;
|
||||
parameter [17:0] start_a = 18'b0_0000_0000_0000_0001;
|
||||
parameter [17:0] start_b = 18'b0_0000_0000_0000_0010;
|
||||
parameter [17:0] start_c = 18'b0_0000_0000_0000_0100;
|
||||
parameter [17:0] start_d = 18'b0_0000_0000_0000_1000;
|
||||
parameter [17:0] start_e = 18'b0_0000_0000_0001_0000;
|
||||
parameter [17:0] stop_a = 18'b0_0000_0000_0010_0000;
|
||||
parameter [17:0] stop_b = 18'b0_0000_0000_0100_0000;
|
||||
parameter [17:0] stop_c = 18'b0_0000_0000_1000_0000;
|
||||
parameter [17:0] stop_d = 18'b0_0000_0001_0000_0000;
|
||||
parameter [17:0] rd_a = 18'b0_0000_0010_0000_0000;
|
||||
parameter [17:0] rd_b = 18'b0_0000_0100_0000_0000;
|
||||
parameter [17:0] rd_c = 18'b0_0000_1000_0000_0000;
|
||||
parameter [17:0] rd_d = 18'b0_0001_0000_0000_0000;
|
||||
parameter [17:0] wr_a = 18'b0_0010_0000_0000_0000;
|
||||
parameter [17:0] wr_b = 18'b0_0100_0000_0000_0000;
|
||||
parameter [17:0] wr_c = 18'b0_1000_0000_0000_0000;
|
||||
parameter [17:0] wr_d = 18'b1_0000_0000_0000_0000;
|
||||
|
||||
always @(posedge clk or posedge Reset)
|
||||
if (Reset)
|
||||
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
|
||||
if(clk_cnt == 0) cmd_ack <= #1 1'b1;
|
||||
end
|
||||
|
||||
start_e:
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
if(clk_cnt == 0) cmd_ack <= #1 1'b0;
|
||||
else 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;
|
||||
cmd_ack <= #1 1'b1;
|
||||
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'b0;
|
||||
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
|
||||
if (clk_cnt == 0) cmd_ack <= #1 1'b1;
|
||||
end
|
||||
|
||||
rd_d:
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
if (clk_cnt == 0) cmd_ack <= #1 0;
|
||||
else cmd_ack <= #1 1;
|
||||
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'b0; // don't check SDA output yet
|
||||
// allow some time for SDA and SCL to settle
|
||||
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
|
||||
if (clk_cnt == 0) cmd_ack <= #1 1'b1;
|
||||
end
|
||||
|
||||
wr_d:
|
||||
begin
|
||||
c_state <= #1 idle;
|
||||
if (clk_cnt == 0) cmd_ack <= #1 0;
|
||||
else cmd_ack <= #1 1;
|
||||
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
|
|
@ -0,0 +1,386 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// 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.8 2009-01-19 20:29:26 rherveille Exp $
|
||||
//
|
||||
// $Date: 2009-01-19 20:29:26 $
|
||||
// $Revision: 1.8 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// 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.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// QuickLogic Change History:
|
||||
//
|
||||
// Date: February 12, 2014
|
||||
// Engineer: Anthony Le
|
||||
// Issue: i2c SDA to SCL timing violation
|
||||
// Change:
|
||||
// 1. Generate LD during IDLE to speed up the input data to SR
|
||||
//
|
||||
|
||||
// synopsys translate_off
|
||||
// synopsys translate_on
|
||||
`timescale 1ns / 10ps
|
||||
|
||||
`include "i2c_master_defines.v"
|
||||
|
||||
module i2c_master_byte_ctrl (
|
||||
clk, rst, Reset, 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, DrivingI2cBusOut,
|
||||
TP1,
|
||||
TP2 );
|
||||
|
||||
//
|
||||
// inputs & outputs
|
||||
//
|
||||
input clk; // master clock
|
||||
input rst; // synchronous active high reset
|
||||
input Reset; // asynchronous active high 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;
|
||||
|
||||
// control signals
|
||||
output DrivingI2cBusOut;
|
||||
|
||||
// test signals
|
||||
output TP1;
|
||||
output TP2;
|
||||
|
||||
|
||||
//
|
||||
// Variable declarations
|
||||
//
|
||||
|
||||
// statemachine
|
||||
parameter [5:0] ST_IDLE = 6'b00_0000;
|
||||
parameter [5:0] ST_START = 6'b00_0001;
|
||||
parameter [5:0] ST_READ = 6'b00_0010;
|
||||
parameter [5:0] ST_WRITE = 6'b00_0100;
|
||||
parameter [5:0] ST_ACK = 6'b00_1000;
|
||||
parameter [5:0] ST_STOP = 6'b01_0000;
|
||||
parameter [5:0] ST_DLWR = 6'b10_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
|
||||
//
|
||||
assign DrivingI2cBusOut = (core_cmd != `I2C_CMD_READ);
|
||||
|
||||
// hookup bit_controller
|
||||
i2c_master_bit_ctrl bit_controller (
|
||||
.clk ( clk ),
|
||||
.rst ( rst ),
|
||||
.Reset ( Reset ),
|
||||
.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 ),
|
||||
.TP1 ( TP1 ),
|
||||
.TP2 ( TP2 )
|
||||
);
|
||||
|
||||
// generate go-signal
|
||||
assign go = (read | write | stop) & ~cmd_ack;
|
||||
|
||||
// assign dout output to shift-register
|
||||
assign dout = sr;
|
||||
|
||||
//
|
||||
// state machine
|
||||
//
|
||||
reg [5:0] c_state; // synopsys enum_state
|
||||
|
||||
// generate shift register
|
||||
// always @(posedge clk or posedge Reset)
|
||||
// if (Reset)
|
||||
// sr <= #1 8'h0;
|
||||
// else if (rst)
|
||||
// sr <= #1 8'h0;
|
||||
// else if (ld)
|
||||
// sr <= #1 din;
|
||||
// else if (shift && clk_cnt !=0)
|
||||
// sr <= #1 {sr[6:0], core_rxd};
|
||||
// else if (shift && c_state != ST_WRITE)
|
||||
// sr <= #1 {sr[6:0], core_rxd};
|
||||
|
||||
// generate counter
|
||||
always @(posedge clk or posedge Reset)
|
||||
if (Reset)
|
||||
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);
|
||||
|
||||
always @(posedge clk or posedge Reset)
|
||||
if (Reset)
|
||||
begin
|
||||
sr <= #1 8'h0;
|
||||
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
|
||||
sr <= #1 8'h0;
|
||||
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
|
||||
if (ld)
|
||||
sr <= #1 din;
|
||||
else if (shift && clk_cnt !=0)
|
||||
sr <= #1 {sr[6:0], core_rxd};
|
||||
else if (shift && c_state != ST_WRITE)
|
||||
sr <= #1 {sr[6:0], core_rxd};
|
||||
// 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_DLWR;
|
||||
core_cmd <= #1 `I2C_CMD_NOP;
|
||||
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_DLWR:
|
||||
begin
|
||||
c_state <= #1 ST_WRITE;
|
||||
core_cmd <= #1 `I2C_CMD_WRITE;
|
||||
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;
|
||||
if (clk_cnt == 0) sr <= #1 {sr[6:0], core_rxd};
|
||||
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;
|
||||
//sr <= #1 {sr[6:0], core_rxd};
|
||||
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;
|
||||
|
||||
if (clk_cnt == 0) shift <= #1 1;
|
||||
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
|
|
@ -0,0 +1,59 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// 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: not supported by cvs2svn $
|
||||
|
||||
|
||||
// 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
|
|
@ -0,0 +1,323 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// 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. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 1.12 2012-12-17 Tim Saxe
|
||||
// Changed wb_ack_o to be derived from in internal version
|
||||
// wb_ack_i
|
||||
|
||||
// CVS Log
|
||||
//
|
||||
// $Id: i2c_master_top.v,v 1.12 2009-01-19 20:29:26 rherveille Exp $
|
||||
//
|
||||
// $Date: 2009-01-19 20:29:26 $
|
||||
// $Revision: 1.12 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// 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
|
||||
// synopsys translate_on
|
||||
`timescale 1ns / 10ps
|
||||
|
||||
`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, tip_o, DrivingI2cBusOut,
|
||||
TP1,
|
||||
TP2);
|
||||
|
||||
// parameters
|
||||
|
||||
//
|
||||
// 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
|
||||
inout wb_ack_o; // bus cycle acknowledge output
|
||||
output wb_inta_o; // interrupt request signal output
|
||||
|
||||
// control signals
|
||||
output tip_o; // transfer in progress
|
||||
output DrivingI2cBusOut; // master is driving i2c bus
|
||||
|
||||
reg [7:0] wb_dat_o;
|
||||
reg wb_ack_i;
|
||||
wire wb_ack_o = wb_ack_i;
|
||||
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)
|
||||
|
||||
// test signal
|
||||
output TP1;
|
||||
output TP2;
|
||||
|
||||
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
assign tip_o = tip;
|
||||
|
||||
// generate internal reset
|
||||
wire rst_i = arst_i;
|
||||
|
||||
// generate wishbone signals
|
||||
wire wb_wacc = wb_we_i & wb_ack_i;
|
||||
|
||||
// generate acknowledge output signal
|
||||
always @(posedge wb_clk_i)
|
||||
wb_ack_i <= #1 wb_cyc_i & wb_stb_i & ~wb_ack_i; // because timing is always honored
|
||||
|
||||
// assign DAT_O
|
||||
always @(posedge wb_clk_i)
|
||||
begin
|
||||
case (wb_adr_i) // synopsys 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 posedge rst_i)
|
||||
if (rst_i)
|
||||
begin
|
||||
// prer <= #1 16'hffff;
|
||||
// ctr <= #1 8'h0;
|
||||
prer <= #1 16'h0000;
|
||||
ctr <= #1 8'h80;
|
||||
txr <= #1 8'h0;
|
||||
end
|
||||
else if (wb_rst_i)
|
||||
begin
|
||||
// prer <= #1 16'hffff;
|
||||
// ctr <= #1 8'h0;
|
||||
prer <= #1 16'h0000;
|
||||
ctr <= #1 8'h80;
|
||||
txr <= #1 8'h0;
|
||||
end
|
||||
else
|
||||
if (wb_wacc)
|
||||
case (wb_adr_i) // synopsys 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 posedge 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 1'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 ),
|
||||
.Reset ( 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 ),
|
||||
.DrivingI2cBusOut (DrivingI2cBusOut),
|
||||
.TP1 ( TP1 ),
|
||||
.TP2 ( TP2 )
|
||||
);
|
||||
|
||||
// status register block + interrupt request signal
|
||||
always @(posedge wb_clk_i or posedge 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 posedge 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
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,238 @@
|
|||
module iir (clk, reset, start, din, params, dout, ready,iir_start,iir_done);
|
||||
input clk, reset, start;
|
||||
input [7:0] din;
|
||||
input [15:0] params;
|
||||
output [7:0] dout;
|
||||
reg [7:0] dout;
|
||||
output ready;
|
||||
reg ready;
|
||||
reg temp_ready;
|
||||
reg [6:0] finite_counter;
|
||||
wire count0;
|
||||
input iir_start;
|
||||
output iir_done;
|
||||
wire iir_done;
|
||||
reg del_count0;
|
||||
|
||||
reg [15:0] a1, a2, b0, b1, b2, yk1, yk2;
|
||||
reg [7:0] uk, uk1, uk2 ;
|
||||
reg [28:0] ysum ;
|
||||
reg [26:0] yk ;
|
||||
reg [22:0] utmp;
|
||||
reg [3:0] wait_counter ;
|
||||
// temporary variable
|
||||
wire [31:0] yo1, yo2;
|
||||
//wire [23:0] b0t, b1t, b2t;
|
||||
wire [22:0] b0t, b1t, b2t;
|
||||
wire [22:0] b0tpaj, b1tpaj, b2tpaj;
|
||||
|
||||
reg [3:0] obf_state, obf_next_state ;
|
||||
|
||||
reg [7:0] temp_uk, temp_uk1, temp_uk2 ;
|
||||
reg [15:0] temp_a1, temp_a2, temp_b0, temp_b1, temp_b2, temp_yk1, temp_yk2;
|
||||
reg [28:0] temp_ysum ;
|
||||
reg [26:0] temp_yk ;
|
||||
reg [22:0] temp_utmp;
|
||||
reg [7:0] temp_dout;
|
||||
reg [3:0] temp_wait_counter ;
|
||||
|
||||
parameter
|
||||
idle = 4'b0001 ,
|
||||
load_a2 = 4'b0010 ,
|
||||
load_b0 = 4'b0011 ,
|
||||
load_b1 = 4'b0100 ,
|
||||
load_b2 = 4'b0101 ,
|
||||
wait4_start = 4'b0110 ,
|
||||
latch_din = 4'b0111 ,
|
||||
compute_a = 4'b1000 ,
|
||||
compute_b = 4'b1001 ,
|
||||
compute_yk = 4'b1010 ,
|
||||
wait4_count = 4'b1011 ,
|
||||
latch_dout = 4'b1100 ;
|
||||
|
||||
always @(obf_state or start or din or wait_counter or iir_start or count0)
|
||||
begin
|
||||
case (obf_state )
|
||||
idle :
|
||||
begin
|
||||
if (iir_start)
|
||||
obf_next_state = load_a2 ;
|
||||
else
|
||||
obf_next_state = idle;
|
||||
temp_a1 = params ;
|
||||
end
|
||||
load_a2 :
|
||||
begin
|
||||
obf_next_state = load_b0 ;
|
||||
temp_a2 = params ;
|
||||
end
|
||||
load_b0 :
|
||||
begin
|
||||
obf_next_state = load_b1 ;
|
||||
temp_b0 = params ;
|
||||
end
|
||||
load_b1 :
|
||||
begin
|
||||
obf_next_state = load_b2 ;
|
||||
temp_b1 = params ;
|
||||
end
|
||||
load_b2 :
|
||||
begin
|
||||
obf_next_state = wait4_start ;
|
||||
temp_b2 = params ;
|
||||
end
|
||||
wait4_start :
|
||||
begin
|
||||
if (start)
|
||||
begin
|
||||
obf_next_state = latch_din ;
|
||||
temp_uk = din ;
|
||||
end
|
||||
else
|
||||
begin
|
||||
obf_next_state = wait4_start ;
|
||||
temp_uk = uk;
|
||||
end
|
||||
temp_ready = wait4_start;
|
||||
end
|
||||
latch_din :
|
||||
begin
|
||||
obf_next_state = compute_a ;
|
||||
end
|
||||
compute_a :
|
||||
begin
|
||||
obf_next_state = compute_b ;
|
||||
|
||||
temp_ysum = yo1[31:3] + yo2[31:3];
|
||||
end
|
||||
compute_b :
|
||||
begin
|
||||
obf_next_state = compute_yk ;
|
||||
|
||||
// temp_utmp = b0t[23:0] + b1t[23:0] + b2t[23:0];
|
||||
temp_utmp = b0t + b1t + b2t;
|
||||
end
|
||||
compute_yk :
|
||||
begin
|
||||
obf_next_state = wait4_count ;
|
||||
temp_uk1 = uk ;
|
||||
temp_uk2 = uk1 ;
|
||||
temp_yk = ysum[26:0] + {utmp[22], utmp[22], utmp[22], utmp[22], utmp};
|
||||
temp_wait_counter = 4 ;
|
||||
end
|
||||
|
||||
wait4_count :
|
||||
begin
|
||||
if (wait_counter==0 )
|
||||
begin
|
||||
obf_next_state = latch_dout ;
|
||||
|
||||
temp_dout = yk[26:19];
|
||||
temp_yk1 = yk[26:11] ;
|
||||
temp_yk2 = yk1 ;
|
||||
end
|
||||
else
|
||||
begin
|
||||
obf_next_state = wait4_count ;
|
||||
temp_dout = dout;
|
||||
temp_yk1 = yk1;
|
||||
//temp_yk2 = yk2;
|
||||
end
|
||||
|
||||
temp_wait_counter = wait_counter - 1;
|
||||
end
|
||||
latch_dout :
|
||||
if (count0)
|
||||
obf_next_state = idle;
|
||||
else
|
||||
obf_next_state = wait4_start ;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
|
||||
//assign yo1 = mul_tc_16_16(yk1, a1, clk);
|
||||
assign yo1 = yk1 * a1;
|
||||
//assign yo2 = mul_tc_16_16(yk2, a2, clk);
|
||||
assign yo2 = yk2*a2;
|
||||
//assign b0t = mul_tc_8_16(uk, b0, clk);
|
||||
//assign b1t = mul_tc_8_16(uk1, b1, clk);
|
||||
//assign b2t = mul_tc_8_16(uk2, b2, clk);
|
||||
assign b0t = uk*b0;
|
||||
assign b1t = uk1*b1;
|
||||
assign b2t = uk2*b2;
|
||||
// paj added to solve unused high order bit
|
||||
assign b0tpaj = b0t;
|
||||
assign b1tpaj = b1t;
|
||||
assign b2tpaj = b2t;
|
||||
|
||||
// A COEFFICENTS
|
||||
always @(posedge clk or posedge reset) begin
|
||||
if (reset ) begin
|
||||
uk <= 0 ;
|
||||
uk1 <= 0 ;
|
||||
uk2 <= 0 ;
|
||||
yk1 <= 0 ;
|
||||
yk2 <= 0 ;
|
||||
yk <= 0 ;
|
||||
ysum <= 0 ;
|
||||
utmp <= 0 ;
|
||||
a1 <= 0 ;
|
||||
a2 <= 0 ;
|
||||
b0 <= 0 ;
|
||||
b1 <= 0 ;
|
||||
b2 <= 0 ;
|
||||
dout <= 0 ;
|
||||
obf_state <= idle ;
|
||||
ready <= 0;
|
||||
end
|
||||
else begin
|
||||
obf_state <= obf_next_state ;
|
||||
uk1 <= temp_uk1;
|
||||
uk2 <= temp_uk2;
|
||||
yk <= temp_yk;
|
||||
uk <= temp_uk ;
|
||||
a1 <= temp_a1 ;
|
||||
a2 <= temp_a2 ;
|
||||
b0 <= temp_b0 ;
|
||||
b1 <= temp_b1 ;
|
||||
b2 <= temp_b2 ;
|
||||
ysum <= temp_ysum;
|
||||
utmp <= temp_utmp;
|
||||
dout <= temp_dout;
|
||||
yk1 <= temp_yk1;
|
||||
yk2 <= temp_yk2;
|
||||
ready <= temp_ready;
|
||||
end
|
||||
end
|
||||
|
||||
// wait counter, count 4 clock after sum is calculated, to
|
||||
// time outputs are ready, and filter is ready to accept next
|
||||
// input
|
||||
always @(posedge clk or posedge reset ) begin
|
||||
if (reset )
|
||||
wait_counter <= 0 ;
|
||||
else begin
|
||||
wait_counter <= temp_wait_counter ;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (reset)
|
||||
finite_counter<=100;
|
||||
else
|
||||
if (iir_start)
|
||||
finite_counter<=finite_counter -1;
|
||||
else
|
||||
finite_counter<=finite_counter;
|
||||
end
|
||||
|
||||
assign count0=finite_counter==7'b0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
del_count0 <= count0;
|
||||
end
|
||||
|
||||
assign iir_done = (count0 && ~del_count0);
|
||||
|
||||
endmodule
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,157 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Non-restoring signed by unsigned divider ////
|
||||
//// Uses the non-restoring unsigned by unsigned divider ////
|
||||
//// ////
|
||||
//// 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: div_su.v,v 1.3 2002-10-31 12:52:54 rherveille Exp $
|
||||
//
|
||||
// $Date: 2002-10-31 12:52:54 $
|
||||
// $Revision: 1.3 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.2 2002/10/23 09:07:03 rherveille
|
||||
// Improved many files.
|
||||
// Fixed some bugs in Run-Length-Encoder.
|
||||
// Removed dependency on ud_cnt and ro_cnt.
|
||||
// Started (Motion)JPEG hardware encoder project.
|
||||
//
|
||||
|
||||
//synopsys translate_off
|
||||
`include "timescale.v"
|
||||
//synopsys translate_on
|
||||
|
||||
module div_su(clk, ena, z, d, q, s, div0, ovf);
|
||||
|
||||
//
|
||||
// parameters
|
||||
//
|
||||
parameter z_width = 16;
|
||||
parameter d_width = z_width /2;
|
||||
|
||||
//
|
||||
// inputs & outputs
|
||||
//
|
||||
input clk; // system clock
|
||||
input ena; // clock enable
|
||||
|
||||
input [z_width-1:0] z; // divident
|
||||
input [d_width-1:0] d; // divisor
|
||||
output [d_width :0] q; // quotient
|
||||
output [d_width-1:0] s; // remainder
|
||||
output div0;
|
||||
output ovf;
|
||||
|
||||
reg [d_width :0] q;
|
||||
reg [d_width-1:0] s;
|
||||
reg div0;
|
||||
reg ovf;
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
reg [z_width -1:0] iz;
|
||||
reg [d_width -1:0] id;
|
||||
reg [d_width +1:0] spipe;
|
||||
|
||||
wire [d_width -1:0] iq, is;
|
||||
wire idiv0, iovf;
|
||||
|
||||
//
|
||||
// module body
|
||||
//
|
||||
|
||||
// delay d
|
||||
always @(posedge clk)
|
||||
if (ena)
|
||||
id <= #1 d;
|
||||
|
||||
// check z, take abs value
|
||||
always @(posedge clk)
|
||||
if (ena)
|
||||
if (z[z_width-1])
|
||||
iz <= #1 ~z +1'h1;
|
||||
else
|
||||
iz <= #1 z;
|
||||
|
||||
// generate spipe (sign bit pipe)
|
||||
integer n;
|
||||
always @(posedge clk)
|
||||
if(ena)
|
||||
begin
|
||||
spipe[0] <= #1 z[z_width-1];
|
||||
|
||||
for(n=1; n <= d_width+1; n=n+1)
|
||||
spipe[n] <= #1 spipe[n-1];
|
||||
end
|
||||
|
||||
// hookup non-restoring divider
|
||||
div_uu #(z_width, d_width)
|
||||
divider (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.z(iz),
|
||||
.d(id),
|
||||
.q(iq),
|
||||
.s(is),
|
||||
.div0(idiv0),
|
||||
.ovf(iovf)
|
||||
);
|
||||
|
||||
// correct divider results if 'd' was negative
|
||||
always @(posedge clk)
|
||||
if(ena)
|
||||
if(spipe[d_width+1])
|
||||
begin
|
||||
q <= #1 (~iq) + 1'h1;
|
||||
s <= #1 (~is) + 1'h1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
q <= #1 {1'b0, iq};
|
||||
s <= #1 {1'b0, is};
|
||||
end
|
||||
|
||||
// delay flags same as results
|
||||
always @(posedge clk)
|
||||
if(ena)
|
||||
begin
|
||||
div0 <= #1 idiv0;
|
||||
ovf <= #1 iovf;
|
||||
end
|
||||
endmodule
|
|
@ -0,0 +1,202 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Non-restoring unsinged divider ////
|
||||
//// ////
|
||||
//// 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: div_uu.v,v 1.3 2002-10-31 12:52:55 rherveille Exp $
|
||||
//
|
||||
// $Date: 2002-10-31 12:52:55 $
|
||||
// $Revision: 1.3 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.2 2002/10/23 09:07:03 rherveille
|
||||
// Improved many files.
|
||||
// Fixed some bugs in Run-Length-Encoder.
|
||||
// Removed dependency on ud_cnt and ro_cnt.
|
||||
// Started (Motion)JPEG hardware encoder project.
|
||||
//
|
||||
|
||||
//synopsys translate_off
|
||||
`include "timescale.v"
|
||||
//synopsys translate_on
|
||||
|
||||
module div_uu(clk, ena, z, d, q, s, div0, ovf);
|
||||
|
||||
//
|
||||
// parameters
|
||||
//
|
||||
parameter z_width = 16;
|
||||
parameter d_width = z_width /2;
|
||||
|
||||
//
|
||||
// inputs & outputs
|
||||
//
|
||||
input clk; // system clock
|
||||
input ena; // clock enable
|
||||
|
||||
input [z_width -1:0] z; // divident
|
||||
input [d_width -1:0] d; // divisor
|
||||
output [d_width -1:0] q; // quotient
|
||||
reg [d_width-1:0] q;
|
||||
output [d_width -1:0] s; // remainder
|
||||
reg [d_width-1:0] s;
|
||||
output div0;
|
||||
reg div0;
|
||||
output ovf;
|
||||
reg ovf;
|
||||
|
||||
//
|
||||
// functions
|
||||
//
|
||||
function [z_width:0] gen_s;
|
||||
input [z_width:0] si;
|
||||
input [z_width:0] di;
|
||||
begin
|
||||
if(si[z_width])
|
||||
gen_s = {si[z_width-1:0], 1'b0} + di;
|
||||
else
|
||||
gen_s = {si[z_width-1:0], 1'b0} - di;
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [d_width-1:0] gen_q;
|
||||
input [d_width-1:0] qi;
|
||||
input [z_width:0] si;
|
||||
begin
|
||||
gen_q = {qi[d_width-2:0], ~si[z_width]};
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [d_width-1:0] assign_s;
|
||||
input [z_width:0] si;
|
||||
input [z_width:0] di;
|
||||
reg [z_width:0] tmp;
|
||||
begin
|
||||
if(si[z_width])
|
||||
tmp = si + di;
|
||||
else
|
||||
tmp = si;
|
||||
|
||||
assign_s = tmp[z_width-1:z_width-4];
|
||||
end
|
||||
endfunction
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
reg [d_width-1:0] q_pipe [d_width-1:0];
|
||||
reg [z_width:0] s_pipe [d_width:0];
|
||||
reg [z_width:0] d_pipe [d_width:0];
|
||||
|
||||
reg [d_width:0] div0_pipe, ovf_pipe;
|
||||
//
|
||||
// perform parameter checks
|
||||
//
|
||||
// synopsys translate_off
|
||||
initial
|
||||
begin
|
||||
if(d_width !== z_width / 2)
|
||||
$display("div.v parameter error (d_width != z_width/2).");
|
||||
end
|
||||
// synopsys translate_on
|
||||
|
||||
integer n0, n1, n2, n3;
|
||||
|
||||
// generate divisor (d) pipe
|
||||
always @(d)
|
||||
d_pipe[0] <= {1'b0, d, {(z_width-d_width){1'b0}} };
|
||||
|
||||
always @(posedge clk)
|
||||
if(ena)
|
||||
for(n0=1; n0 <= d_width; n0=n0+1)
|
||||
d_pipe[n0] <= #1 d_pipe[n0-1];
|
||||
|
||||
// generate internal remainder pipe
|
||||
always @(z)
|
||||
s_pipe[0] <= z;
|
||||
|
||||
always @(posedge clk)
|
||||
if(ena)
|
||||
for(n1=1; n1 <= d_width; n1=n1+1)
|
||||
s_pipe[n1] <= #1 gen_s(s_pipe[n1-1], d_pipe[n1-1]);
|
||||
|
||||
// generate quotient pipe
|
||||
always @(posedge clk)
|
||||
q_pipe[0] <= #1 0;
|
||||
|
||||
always @(posedge clk)
|
||||
if(ena)
|
||||
for(n2=1; n2 < d_width; n2=n2+1)
|
||||
q_pipe[n2] <= #1 gen_q(q_pipe[n2-1], s_pipe[n2]);
|
||||
|
||||
|
||||
// flags (divide_by_zero, overflow)
|
||||
always @(z or d)
|
||||
begin
|
||||
ovf_pipe[0] <= !(z[z_width-1:d_width] < d);
|
||||
div0_pipe[0] <= ~|d;
|
||||
end
|
||||
|
||||
always @(posedge clk)
|
||||
if(ena)
|
||||
for(n3=1; n3 <= d_width; n3=n3+1)
|
||||
begin
|
||||
ovf_pipe[n3] <= #1 ovf_pipe[n3-1];
|
||||
div0_pipe[n3] <= #1 div0_pipe[n3-1];
|
||||
end
|
||||
|
||||
// assign outputs
|
||||
always @(posedge clk)
|
||||
if(ena)
|
||||
ovf <= #1 ovf_pipe[d_width];
|
||||
|
||||
always @(posedge clk)
|
||||
if(ena)
|
||||
div0 <= #1 div0_pipe[d_width];
|
||||
|
||||
always @(posedge clk)
|
||||
if(ena)
|
||||
q <= #1 gen_q(q_pipe[d_width-1], s_pipe[d_width]);
|
||||
|
||||
always @(posedge clk)
|
||||
if(ena)
|
||||
s <= #1 assign_s(s_pipe[d_width], d_pipe[d_width]);
|
||||
endmodule
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// JPEG Quantization & Rounding Core ////
|
||||
//// ////
|
||||
//// 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: jpeg_qnr.v,v 1.3 2002-10-31 12:52:55 rherveille Exp $
|
||||
//
|
||||
// $Date: 2002-10-31 12:52:55 $
|
||||
// $Revision: 1.3 $
|
||||
// $Author: rherveille $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.2 2002/10/23 09:07:03 rherveille
|
||||
// Improved many files.
|
||||
// Fixed some bugs in Run-Length-Encoder.
|
||||
// Removed dependency on ud_cnt and ro_cnt.
|
||||
// Started (Motion)JPEG hardware encoder project.
|
||||
//
|
||||
|
||||
//synopsys translate_off
|
||||
`include "timescale.v"
|
||||
//synopsys translate_on
|
||||
|
||||
module jpeg_qnr(clk, ena, rst, dstrb, din, qnt_val, qnt_cnt, dout, douten);
|
||||
|
||||
//
|
||||
// parameters
|
||||
//
|
||||
parameter d_width = 12;
|
||||
parameter z_width = 2 * d_width;
|
||||
|
||||
//
|
||||
// inputs & outputs
|
||||
//
|
||||
input clk; // system clock
|
||||
input ena; // clock enable
|
||||
input rst; // asynchronous active low reset
|
||||
|
||||
input dstrb; // present dstrb 1clk cycle before din
|
||||
input [d_width-1:0] din; // data input
|
||||
input [ 7:0] qnt_val; // quantization value
|
||||
|
||||
output [ 5:0] qnt_cnt; // sample number (get quantization value qnt_cnt)
|
||||
output [10:0] dout; // data output
|
||||
output douten;
|
||||
|
||||
//
|
||||
// variables
|
||||
//
|
||||
wire [z_width-1:0] iz; // intermediate divident value
|
||||
wire [d_width-1:0] id; // intermediate dividor value
|
||||
wire [d_width :0] iq; // intermediate result divider
|
||||
reg [d_width :0] rq; // rounded q-value
|
||||
reg [d_width+3:0] dep;// data enable pipeline
|
||||
|
||||
// generate sample counter
|
||||
reg [5:0] qnt_cnt;
|
||||
wire dcnt = &qnt_cnt;
|
||||
|
||||
always @(posedge clk or negedge rst)
|
||||
if (~rst)
|
||||
qnt_cnt <= #1 6'h0;
|
||||
else if (dstrb)
|
||||
qnt_cnt <= #1 6'h0;
|
||||
else if (ena)
|
||||
qnt_cnt <= #1 qnt_cnt + 6'h1;
|
||||
|
||||
// generate intermediate dividor/divident values
|
||||
assign id = { {(d_width - 8){1'b0}}, qnt_val};
|
||||
assign iz = { {(z_width - d_width){din[d_width-1]}}, din};
|
||||
|
||||
// hookup division unit
|
||||
div_su #(z_width)
|
||||
divider (
|
||||
.clk(clk),
|
||||
.ena(ena),
|
||||
.z(iz),
|
||||
.d(id),
|
||||
.q(iq),
|
||||
.s(),
|
||||
.div0(),
|
||||
.ovf()
|
||||
);
|
||||
|
||||
// round result to the nearest integer
|
||||
always @(posedge clk)
|
||||
if (ena)
|
||||
if (iq[0])
|
||||
if (iq[d_width])
|
||||
rq <= #1 iq - 1'h1;
|
||||
else
|
||||
rq <= #1 iq + 1'h1;
|
||||
else
|
||||
rq <= #1 iq;
|
||||
|
||||
// assign dout signal
|
||||
assign dout = rq[d_width -1: d_width-11];
|
||||
|
||||
|
||||
// generate data-out enable signal
|
||||
// This is a pipeline, data is not dependant on sample-count
|
||||
integer n;
|
||||
always @(posedge clk or negedge rst)
|
||||
if (!rst)
|
||||
dep <= #1 0;
|
||||
else if(ena)
|
||||
begin
|
||||
dep[0] <= #1 dstrb;
|
||||
|
||||
for (n=1; n <= d_width +3; n = n +1)
|
||||
dep[n] <= #1 dep[n-1];
|
||||
end
|
||||
|
||||
assign douten = dep[d_width +3];
|
||||
endmodule
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,110 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
// Created by SmartDesign Tue Jan 16 17:22:21 2018
|
||||
// Version: v11.8 11.8.0.26
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
`timescale 1ns / 100ps
|
||||
|
||||
// TOP_multi_enc_decx2x4
|
||||
module multi_enc_decx2x4(
|
||||
// Inputs
|
||||
clock,
|
||||
datain,
|
||||
datain1,
|
||||
datain1_0,
|
||||
datain_0,
|
||||
reset,
|
||||
// Outputs
|
||||
dataout,
|
||||
dataout1,
|
||||
dataout1_0,
|
||||
dataout_0
|
||||
);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Input
|
||||
//--------------------------------------------------------------------
|
||||
input clock;
|
||||
input [127:0] datain;
|
||||
input [127:0] datain1;
|
||||
input [127:0] datain1_0;
|
||||
input [127:0] datain_0;
|
||||
input reset;
|
||||
//--------------------------------------------------------------------
|
||||
// Output
|
||||
//--------------------------------------------------------------------
|
||||
output [127:0] dataout;
|
||||
output [127:0] dataout1;
|
||||
output [127:0] dataout1_0;
|
||||
output [127:0] dataout_0;
|
||||
//--------------------------------------------------------------------
|
||||
// Nets
|
||||
//--------------------------------------------------------------------
|
||||
wire clock;
|
||||
wire [127:0] datain;
|
||||
wire [127:0] datain1;
|
||||
wire [127:0] datain1_0;
|
||||
wire [127:0] datain_0;
|
||||
wire [127:0] dataout_net_0;
|
||||
wire [127:0] dataout1_net_0;
|
||||
wire [127:0] dataout1_0_net_0;
|
||||
wire [127:0] dataout_0_net_0;
|
||||
wire reset;
|
||||
wire [127:0] top_0_dataout;
|
||||
wire [127:0] top_1_dataout1;
|
||||
wire [127:0] dataout_net_1;
|
||||
wire [127:0] dataout1_net_1;
|
||||
wire [127:0] dataout1_0_net_1;
|
||||
wire [127:0] dataout_0_net_1;
|
||||
//--------------------------------------------------------------------
|
||||
// Top level output port assignments
|
||||
//--------------------------------------------------------------------
|
||||
assign dataout_net_1 = dataout_net_0;
|
||||
assign dataout[127:0] = dataout_net_1;
|
||||
assign dataout1_net_1 = dataout1_net_0;
|
||||
assign dataout1[127:0] = dataout1_net_1;
|
||||
assign dataout1_0_net_1 = dataout1_0_net_0;
|
||||
assign dataout1_0[127:0] = dataout1_0_net_1;
|
||||
assign dataout_0_net_1 = dataout_0_net_0;
|
||||
assign dataout_0[127:0] = dataout_0_net_1;
|
||||
//--------------------------------------------------------------------
|
||||
// Component instances
|
||||
//--------------------------------------------------------------------
|
||||
//--------top
|
||||
top top_0(
|
||||
// Inputs
|
||||
.clock ( clock ),
|
||||
.reset ( reset ),
|
||||
.datain ( datain ),
|
||||
.datain1 ( datain1 ),
|
||||
// Outputs
|
||||
.dataout ( top_0_dataout ),
|
||||
.dataout1 ( dataout1_0_net_0 )
|
||||
);
|
||||
|
||||
//--------top
|
||||
top top_1(
|
||||
// Inputs
|
||||
.clock ( clock ),
|
||||
.reset ( reset ),
|
||||
.datain ( datain_0 ),
|
||||
.datain1 ( datain1_0 ),
|
||||
// Outputs
|
||||
.dataout ( dataout_0_net_0 ),
|
||||
.dataout1 ( top_1_dataout1 )
|
||||
);
|
||||
|
||||
//--------top
|
||||
top top_2(
|
||||
// Inputs
|
||||
.clock ( clock ),
|
||||
.reset ( reset ),
|
||||
.datain ( top_0_dataout ),
|
||||
.datain1 ( top_1_dataout1 ),
|
||||
// Outputs
|
||||
.dataout ( dataout_net_0 ),
|
||||
.dataout1 ( dataout1_net_0 )
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,147 @@
|
|||
module decoder128(datain,dataout);
|
||||
|
||||
input [6:0] datain;
|
||||
output [127:0] dataout;
|
||||
reg [127:0] dataout;
|
||||
|
||||
always @(datain)
|
||||
|
||||
begin
|
||||
|
||||
case (datain)
|
||||
|
||||
7'b0000000: dataout <= 128'h00000000000000000000000000000001;
|
||||
7'b0000001: dataout <= 128'h00000000000000000000000000000002;
|
||||
7'b0000010: dataout <= 128'h00000000000000000000000000000004;
|
||||
7'b0000011: dataout <= 128'h00000000000000000000000000000008;
|
||||
7'b0000100: dataout <= 128'h00000000000000000000000000000010;
|
||||
7'b0000101: dataout <= 128'h00000000000000000000000000000020;
|
||||
7'b0000110: dataout <= 128'h00000000000000000000000000000040;
|
||||
7'b0000111: dataout <= 128'h00000000000000000000000000000080;
|
||||
7'b0001000: dataout <= 128'h00000000000000000000000000000100;
|
||||
7'b0001001: dataout <= 128'h00000000000000000000000000000200;
|
||||
7'b0001010: dataout <= 128'h00000000000000000000000000000400;
|
||||
7'b0001011: dataout <= 128'h00000000000000000000000000000800;
|
||||
7'b0001100: dataout <= 128'h00000000000000000000000000001000;
|
||||
7'b0001101: dataout <= 128'h00000000000000000000000000002000;
|
||||
7'b0001110: dataout <= 128'h00000000000000000000000000004000;
|
||||
7'b0001111: dataout <= 128'h00000000000000000000000000008000;
|
||||
7'b0010000: dataout <= 128'h00000000000000000000000000010000;
|
||||
7'b0010001: dataout <= 128'h00000000000000000000000000020000;
|
||||
7'b0010010: dataout <= 128'h00000000000000000000000000040000;
|
||||
7'b0010011: dataout <= 128'h00000000000000000000000000080000;
|
||||
7'b0010100: dataout <= 128'h00000000000000000000000000100000;
|
||||
7'b0010101: dataout <= 128'h00000000000000000000000000200000;
|
||||
7'b0010110: dataout <= 128'h00000000000000000000000000400000;
|
||||
7'b0010111: dataout <= 128'h00000000000000000000000000800000;
|
||||
7'b0011000: dataout <= 128'h00000000000000000000000001000000;
|
||||
7'b0011001: dataout <= 128'h00000000000000000000000002000000;
|
||||
7'b0011010: dataout <= 128'h00000000000000000000000004000000;
|
||||
7'b0011011: dataout <= 128'h00000000000000000000000008000000;
|
||||
7'b0011100: dataout <= 128'h00000000000000000000000010000000;
|
||||
7'b0011101: dataout <= 128'h00000000000000000000000020000000;
|
||||
7'b0011110: dataout <= 128'h00000000000000000000000040000000;
|
||||
7'b0011111: dataout <= 128'h00000000000000000000000080000000;
|
||||
7'b0100000: dataout <= 128'h00000000000000000000000100000000;
|
||||
7'b0100001: dataout <= 128'h00000000000000000000000200000000;
|
||||
7'b0100010: dataout <= 128'h00000000000000000000000400000000;
|
||||
7'b0100011: dataout <= 128'h00000000000000000000000800000000;
|
||||
7'b0100100: dataout <= 128'h00000000000000000000001000000000;
|
||||
7'b0100101: dataout <= 128'h00000000000000000000002000000000;
|
||||
7'b0100110: dataout <= 128'h00000000000000000000004000000000;
|
||||
7'b0100111: dataout <= 128'h00000000000000000000008000000000;
|
||||
7'b0101000: dataout <= 128'h00000000000000000000010000000000;
|
||||
7'b0101001: dataout <= 128'h00000000000000000000020000000000;
|
||||
7'b0101010: dataout <= 128'h00000000000000000000040000000000;
|
||||
7'b0101011: dataout <= 128'h00000000000000000000080000000000;
|
||||
7'b0101100: dataout <= 128'h00000000000000000000100000000000;
|
||||
7'b0101101: dataout <= 128'h00000000000000000000200000000000;
|
||||
7'b0101110: dataout <= 128'h00000000000000000000400000000000;
|
||||
7'b0101111: dataout <= 128'h00000000000000000000800000000000;
|
||||
7'b0110000: dataout <= 128'h00000000000000000001000000000000;
|
||||
7'b0110001: dataout <= 128'h00000000000000000002000000000000;
|
||||
7'b0110010: dataout <= 128'h00000000000000000004000000000000;
|
||||
7'b0110011: dataout <= 128'h00000000000000000008000000000000;
|
||||
7'b0110100: dataout <= 128'h00000000000000000010000000000000;
|
||||
7'b0110101: dataout <= 128'h00000000000000000020000000000000;
|
||||
7'b0110110: dataout <= 128'h00000000000000000040000000000000;
|
||||
7'b0110111: dataout <= 128'h00000000000000000080000000000000;
|
||||
7'b0111000: dataout <= 128'h00000000000000000100000000000000;
|
||||
7'b0111001: dataout <= 128'h00000000000000000200000000000000;
|
||||
7'b0111010: dataout <= 128'h00000000000000000400000000000000;
|
||||
7'b0111011: dataout <= 128'h00000000000000000800000000000000;
|
||||
7'b0111100: dataout <= 128'h00000000000000001000000000000000;
|
||||
7'b0111101: dataout <= 128'h00000000000000002000000000000000;
|
||||
7'b0111110: dataout <= 128'h00000000000000004000000000000000;
|
||||
7'b0111111: dataout <= 128'h00000000000000008000000000000000;
|
||||
7'b1000000: dataout <= 128'h00000000000000010000000000000000;
|
||||
7'b1000001: dataout <= 128'h00000000000000020000000000000000;
|
||||
7'b1000010: dataout <= 128'h00000000000000040000000000000000;
|
||||
7'b1000011: dataout <= 128'h00000000000000080000000000000000;
|
||||
7'b1000100: dataout <= 128'h00000000000000100000000000000000;
|
||||
7'b1000101: dataout <= 128'h00000000000000200000000000000000;
|
||||
7'b1000110: dataout <= 128'h00000000000000400000000000000000;
|
||||
7'b1000111: dataout <= 128'h00000000000000800000000000000000;
|
||||
7'b1001000: dataout <= 128'h00000000000001000000000000000000;
|
||||
7'b1001001: dataout <= 128'h00000000000002000000000000000000;
|
||||
7'b1001010: dataout <= 128'h00000000000004000000000000000000;
|
||||
7'b1001011: dataout <= 128'h00000000000008000000000000000000;
|
||||
7'b1001100: dataout <= 128'h00000000000010000000000000000000;
|
||||
7'b1001101: dataout <= 128'h00000000000020000000000000000000;
|
||||
7'b1001110: dataout <= 128'h00000000000040000000000000000000;
|
||||
7'b1001111: dataout <= 128'h00000000000080000000000000000000;
|
||||
7'b1010000: dataout <= 128'h00000000000100000000000000000000;
|
||||
7'b1010001: dataout <= 128'h00000000000200000000000000000000;
|
||||
7'b1010010: dataout <= 128'h00000000000400000000000000000000;
|
||||
7'b1010011: dataout <= 128'h00000000000800000000000000000000;
|
||||
7'b1010100: dataout <= 128'h00000000001000000000000000000000;
|
||||
7'b1010101: dataout <= 128'h00000000002000000000000000000000;
|
||||
7'b1010110: dataout <= 128'h00000000004000000000000000000000;
|
||||
7'b1010111: dataout <= 128'h00000000008000000000000000000000;
|
||||
7'b1011000: dataout <= 128'h00000000010000000000000000000000;
|
||||
7'b1011001: dataout <= 128'h00000000020000000000000000000000;
|
||||
7'b1011010: dataout <= 128'h00000000040000000000000000000000;
|
||||
7'b1011011: dataout <= 128'h00000000080000000000000000000000;
|
||||
7'b1011100: dataout <= 128'h00000000100000000000000000000000;
|
||||
7'b1011101: dataout <= 128'h00000000200000000000000000000000;
|
||||
7'b1011110: dataout <= 128'h00000000400000000000000000000000;
|
||||
7'b1011111: dataout <= 128'h00000000800000000000000000000000;
|
||||
7'b1100000: dataout <= 128'h00000001000000000000000000000000;
|
||||
7'b1100001: dataout <= 128'h00000002000000000000000000000000;
|
||||
7'b1100010: dataout <= 128'h00000004000000000000000000000000;
|
||||
7'b1100011: dataout <= 128'h00000008000000000000000000000000;
|
||||
7'b1100100: dataout <= 128'h00000010000000000000000000000000;
|
||||
7'b1100101: dataout <= 128'h00000020000000000000000000000000;
|
||||
7'b1100110: dataout <= 128'h00000040000000000000000000000000;
|
||||
7'b1100111: dataout <= 128'h00000080000000000000000000000000;
|
||||
7'b1101000: dataout <= 128'h00000100000000000000000000000000;
|
||||
7'b1101001: dataout <= 128'h00000200000000000000000000000000;
|
||||
7'b1101010: dataout <= 128'h00000400000000000000000000000000;
|
||||
7'b1101011: dataout <= 128'h00000800000000000000000000000000;
|
||||
7'b1101100: dataout <= 128'h00001000000000000000000000000000;
|
||||
7'b1101101: dataout <= 128'h00002000000000000000000000000000;
|
||||
7'b1101110: dataout <= 128'h00004000000000000000000000000000;
|
||||
7'b1101111: dataout <= 128'h00008000000000000000000000000000;
|
||||
7'b1110000: dataout <= 128'h00010000000000000000000000000000;
|
||||
7'b1110001: dataout <= 128'h00020000000000000000000000000000;
|
||||
7'b1110010: dataout <= 128'h00040000000000000000000000000000;
|
||||
7'b1110011: dataout <= 128'h00080000000000000000000000000000;
|
||||
7'b1110100: dataout <= 128'h00100000000000000000000000000000;
|
||||
7'b1110101: dataout <= 128'h00200000000000000000000000000000;
|
||||
7'b1110110: dataout <= 128'h00400000000000000000000000000000;
|
||||
7'b1110111: dataout <= 128'h00800000000000000000000000000000;
|
||||
7'b1111000: dataout <= 128'h01000000000000000000000000000000;
|
||||
7'b1111001: dataout <= 128'h02000000000000000000000000000000;
|
||||
7'b1111010: dataout <= 128'h04000000000000000000000000000000;
|
||||
7'b1111011: dataout <= 128'h08000000000000000000000000000000;
|
||||
7'b1111100: dataout <= 128'h10000000000000000000000000000000;
|
||||
7'b1111101: dataout <= 128'h20000000000000000000000000000000;
|
||||
7'b1111110: dataout <= 128'h40000000000000000000000000000000;
|
||||
7'b1111111: dataout <= 128'h80000000000000000000000000000000;
|
||||
|
||||
|
||||
|
||||
default: dataout<=128'h0;
|
||||
endcase
|
||||
end
|
||||
endmodule
|
|
@ -0,0 +1,149 @@
|
|||
module encoder128(datain,dataout);
|
||||
|
||||
input [127:0] datain;
|
||||
output [6:0] dataout;
|
||||
reg [6:0] dataout;
|
||||
|
||||
always @(datain)
|
||||
|
||||
begin
|
||||
|
||||
case (datain)
|
||||
|
||||
128'h00000000000000000000000000000001 : dataout<=7'b0000000;
|
||||
128'h00000000000000000000000000000002 : dataout<=7'b0000001;
|
||||
128'h00000000000000000000000000000004 : dataout<=7'b0000010;
|
||||
128'h00000000000000000000000000000008 : dataout<=7'b0000011;
|
||||
128'h00000000000000000000000000000010 : dataout<=7'b0000100;
|
||||
128'h00000000000000000000000000000020 : dataout<=7'b0000101;
|
||||
128'h00000000000000000000000000000040 : dataout<=7'b0000110;
|
||||
128'h00000000000000000000000000000080 : dataout<=7'b0000111;
|
||||
128'h00000000000000000000000000000100 : dataout<=7'b0001000;
|
||||
128'h00000000000000000000000000000200 : dataout<=7'b0001001;
|
||||
128'h00000000000000000000000000000400 : dataout<=7'b0001010;
|
||||
128'h00000000000000000000000000000800 : dataout<=7'b0001011;
|
||||
128'h00000000000000000000000000001000 : dataout<=7'b0001000;
|
||||
128'h00000000000000000000000000002000 : dataout<=7'b0001101;
|
||||
128'h00000000000000000000000000004000 : dataout<=7'b0001110;
|
||||
128'h00000000000000000000000000008000 : dataout<=7'b0001111;
|
||||
128'h00000000000000000000000000010000 : dataout<=7'b0010000;
|
||||
128'h00000000000000000000000000020000 : dataout<=7'b0010001;
|
||||
128'h00000000000000000000000000040000 : dataout<=7'b0010010;
|
||||
128'h00000000000000000000000000080000 : dataout<=7'b0010011;
|
||||
128'h00000000000000000000000000100000 : dataout<=7'b0010100;
|
||||
128'h00000000000000000000000000200000 : dataout<=7'b0010101;
|
||||
128'h00000000000000000000000000400000 : dataout<=7'b0010110;
|
||||
128'h00000000000000000000000000800000 : dataout<=7'b0010111;
|
||||
128'h00000000000000000000000001000000 : dataout<=7'b0011000;
|
||||
128'h00000000000000000000000002000000 : dataout<=7'b0011001;
|
||||
128'h00000000000000000000000004000000 : dataout<=7'b0011010;
|
||||
128'h00000000000000000000000008000000 : dataout<=7'b0011011;
|
||||
128'h00000000000000000000000010000000 : dataout<=7'b0011000;
|
||||
128'h00000000000000000000000020000000 : dataout<=7'b0011101;
|
||||
128'h00000000000000000000000040000000 : dataout<=7'b0011110;
|
||||
128'h00000000000000000000000080000000 : dataout<=7'b0011111;
|
||||
|
||||
128'h00000000000000000000000100000000 : dataout<=7'b0100000;
|
||||
128'h00000000000000000000000200000000 : dataout<=7'b0100001;
|
||||
128'h00000000000000000000000400000000 : dataout<=7'b0100010;
|
||||
128'h00000000000000000000000800000000 : dataout<=7'b0100011;
|
||||
128'h00000000000000000000001000000000 : dataout<=7'b0100100;
|
||||
128'h00000000000000000000002000000000 : dataout<=7'b0100101;
|
||||
128'h00000000000000000000004000000000 : dataout<=7'b0100110;
|
||||
128'h00000000000000000000008000000000 : dataout<=7'b0100111;
|
||||
128'h00000000000000000000010000000000 : dataout<=7'b0101000;
|
||||
128'h00000000000000000000020000000000 : dataout<=7'b0101001;
|
||||
128'h00000000000000000000040000000000 : dataout<=7'b0101010;
|
||||
128'h00000000000000000000080000000000 : dataout<=7'b0101011;
|
||||
128'h00000000000000000000100000000000 : dataout<=7'b0101000;
|
||||
128'h00000000000000000000200000000000 : dataout<=7'b0101101;
|
||||
128'h00000000000000000000400000000000 : dataout<=7'b0101110;
|
||||
128'h00000000000000000000800000000000 : dataout<=7'b0101111;
|
||||
128'h00000000000000000001000000000000 : dataout<=7'b0110000;
|
||||
128'h00000000000000000002000000000000 : dataout<=7'b0110001;
|
||||
128'h00000000000000000004000000000000 : dataout<=7'b0110010;
|
||||
128'h00000000000000000008000000000000 : dataout<=7'b0110011;
|
||||
128'h00000000000000000010000000000000 : dataout<=7'b0110100;
|
||||
128'h00000000000000000020000000000000 : dataout<=7'b0110101;
|
||||
128'h00000000000000000040000000000000 : dataout<=7'b0110110;
|
||||
128'h00000000000000000080000000000000 : dataout<=7'b0110111;
|
||||
128'h00000000000000000100000000000000 : dataout<=7'b0111000;
|
||||
128'h00000000000000000200000000000000 : dataout<=7'b0111001;
|
||||
128'h00000000000000000400000000000000 : dataout<=7'b0111010;
|
||||
128'h00000000000000000800000000000000 : dataout<=7'b0111011;
|
||||
128'h00000000000000001000000000000000 : dataout<=7'b0111000;
|
||||
128'h00000000000000002000000000000000 : dataout<=7'b0111101;
|
||||
128'h00000000000000004000000000000000 : dataout<=7'b0111110;
|
||||
128'h00000000000000008000000000000000 : dataout<=7'b0111111;
|
||||
|
||||
128'h00000000000000010000000000000000 : dataout<=7'b1000000;
|
||||
128'h00000000000000020000000000000000 : dataout<=7'b1000001;
|
||||
128'h00000000000000040000000000000000 : dataout<=7'b1000010;
|
||||
128'h00000000000000080000000000000000 : dataout<=7'b1000011;
|
||||
128'h00000000000000100000000000000000 : dataout<=7'b1000100;
|
||||
128'h00000000000000200000000000000000 : dataout<=7'b1000101;
|
||||
128'h00000000000000400000000000000000 : dataout<=7'b1000110;
|
||||
128'h00000000000000800000000000000000 : dataout<=7'b1000111;
|
||||
128'h00000000000001000000000000000000 : dataout<=7'b1001000;
|
||||
128'h00000000000002000000000000000000 : dataout<=7'b1001001;
|
||||
128'h00000000000004000000000000000000 : dataout<=7'b1001010;
|
||||
128'h00000000000008000000000000000000 : dataout<=7'b1001011;
|
||||
128'h00000000000010000000000000000000 : dataout<=7'b1001000;
|
||||
128'h00000000000020000000000000000000 : dataout<=7'b1001101;
|
||||
128'h00000000000040000000000000000000 : dataout<=7'b1001110;
|
||||
128'h00000000000080000000000000000000 : dataout<=7'b1001111;
|
||||
128'h00000000000100000000000000000000 : dataout<=7'b1010000;
|
||||
128'h00000000000200000000000000000000 : dataout<=7'b1010001;
|
||||
128'h00000000000400000000000000000000 : dataout<=7'b1010010;
|
||||
128'h00000000000800000000000000000000 : dataout<=7'b1010011;
|
||||
128'h00000000001000000000000000000000 : dataout<=7'b1010100;
|
||||
128'h00000000002000000000000000000000 : dataout<=7'b1010101;
|
||||
128'h00000000004000000000000000000000 : dataout<=7'b1010110;
|
||||
128'h00000000008000000000000000000000 : dataout<=7'b1010111;
|
||||
128'h00000000010000000000000000000000 : dataout<=7'b1011000;
|
||||
128'h00000000020000000000000000000000 : dataout<=7'b1011001;
|
||||
128'h00000000040000000000000000000000 : dataout<=7'b1011010;
|
||||
128'h00000000080000000000000000000000 : dataout<=7'b1011011;
|
||||
128'h00000000100000000000000000000000 : dataout<=7'b1011000;
|
||||
128'h00000000200000000000000000000000 : dataout<=7'b1011101;
|
||||
128'h00000000400000000000000000000000 : dataout<=7'b1011110;
|
||||
128'h00000000800000000000000000000000 : dataout<=7'b1011111;
|
||||
|
||||
128'h00000001000000000000000000000000 : dataout<=7'b1100000;
|
||||
128'h00000002000000000000000000000000 : dataout<=7'b1100001;
|
||||
128'h00000004000000000000000000000000 : dataout<=7'b1100010;
|
||||
128'h00000008000000000000000000000000 : dataout<=7'b1100011;
|
||||
128'h00000010000000000000000000000000 : dataout<=7'b1100100;
|
||||
128'h00000020000000000000000000000000 : dataout<=7'b1100101;
|
||||
128'h00000040000000000000000000000000 : dataout<=7'b1100110;
|
||||
128'h00000080000000000000000000000000 : dataout<=7'b1100111;
|
||||
128'h00000100000000000000000000000000 : dataout<=7'b1101000;
|
||||
128'h00000200000000000000000000000000 : dataout<=7'b1101001;
|
||||
128'h00000400000000000000000000000000 : dataout<=7'b1101010;
|
||||
128'h00000800000000000000000000000000 : dataout<=7'b1101011;
|
||||
128'h00001000000000000000000000000000 : dataout<=7'b1101000;
|
||||
128'h00002000000000000000000000000000 : dataout<=7'b1101101;
|
||||
128'h00004000000000000000000000000000 : dataout<=7'b1101110;
|
||||
128'h00008000000000000000000000000000 : dataout<=7'b1101111;
|
||||
128'h00010000000000000000000000000000 : dataout<=7'b1110000;
|
||||
128'h00020000000000000000000000000000 : dataout<=7'b1110001;
|
||||
128'h00040000000000000000000000000000 : dataout<=7'b1110010;
|
||||
128'h00080000000000000000000000000000 : dataout<=7'b1110011;
|
||||
128'h00100000000000000000000000000000 : dataout<=7'b1110100;
|
||||
128'h00200000000000000000000000000000 : dataout<=7'b1110101;
|
||||
128'h00400000000000000000000000000000 : dataout<=7'b1110110;
|
||||
128'h00800000000000000000000000000000 : dataout<=7'b1110111;
|
||||
128'h01000000000000000000000000000000 : dataout<=7'b1111000;
|
||||
128'h02000000000000000000000000000000 : dataout<=7'b1111001;
|
||||
128'h04000000000000000000000000000000 : dataout<=7'b1111010;
|
||||
128'h08000000000000000000000000000000 : dataout<=7'b1111011;
|
||||
128'h10000000000000000000000000000000 : dataout<=7'b1111000;
|
||||
128'h20000000000000000000000000000000 : dataout<=7'b1111101;
|
||||
128'h40000000000000000000000000000000 : dataout<=7'b1111110;
|
||||
128'h80000000000000000000000000000000 : dataout<=7'b1111111;
|
||||
|
||||
|
||||
default: dataout<=7'b0000000;
|
||||
endcase
|
||||
end
|
||||
endmodule
|
|
@ -0,0 +1,104 @@
|
|||
|
||||
module top(clock,reset,datain,dataout,datain1,dataout1);
|
||||
|
||||
|
||||
input clock,reset;
|
||||
|
||||
input [127:0] datain;
|
||||
output [127:0] dataout;
|
||||
|
||||
input [127:0] datain1;
|
||||
output [127:0] dataout1;
|
||||
|
||||
wire [6:0] enc_out;
|
||||
reg [127:0] data_encin;
|
||||
reg [6:0] data_encout;
|
||||
|
||||
wire [6:0] enc_out1;
|
||||
reg [127:0] data_encin1;
|
||||
reg [6:0] data_encout1;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
encoder128 U01(.datain(data_encin),.dataout(enc_out));
|
||||
decoder128 U02(.datain(data_encout),.dataout(dataout));
|
||||
|
||||
encoder128 U011(.datain(data_encin1),.dataout(enc_out1));
|
||||
decoder128 U021(.datain(data_encout1),.dataout(dataout1));
|
||||
|
||||
|
||||
|
||||
always @(posedge clock)
|
||||
|
||||
begin
|
||||
|
||||
if (reset)
|
||||
|
||||
data_encin <= 127'h00000;
|
||||
|
||||
else
|
||||
|
||||
data_encin <= datain;
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
always @(posedge clock)
|
||||
|
||||
begin
|
||||
|
||||
if (reset)
|
||||
|
||||
data_encout <= 7'h0;
|
||||
|
||||
else
|
||||
|
||||
data_encout<= enc_out;
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
always @(posedge clock)
|
||||
|
||||
begin
|
||||
|
||||
if (reset)
|
||||
|
||||
data_encin1 <= 127'h00000;
|
||||
|
||||
else
|
||||
|
||||
data_encin1 <= datain1;
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
always @(posedge clock)
|
||||
|
||||
begin
|
||||
|
||||
if (reset)
|
||||
|
||||
data_encout1 <= 7'h0;
|
||||
|
||||
else
|
||||
|
||||
data_encout1<= enc_out1;
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
endmodule
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,75 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE SD Card Controller IP Core ////
|
||||
//// ////
|
||||
//// bistable_domain_cross.v ////
|
||||
//// ////
|
||||
//// This file is part of the WISHBONE SD Card ////
|
||||
//// Controller IP Core project ////
|
||||
//// http://opencores.org/project,sd_card_controller ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// Clock synchronisation beetween two clock domains. ////
|
||||
//// Assumption is that input signal duration has to be at least ////
|
||||
//// one clk_b clock period. ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013 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 ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
module bistable_domain_cross(
|
||||
rst,
|
||||
clk_a,
|
||||
in,
|
||||
clk_b,
|
||||
out
|
||||
);
|
||||
parameter width = 1;
|
||||
input rst;
|
||||
input clk_a;
|
||||
input [width-1:0] in;
|
||||
input clk_b;
|
||||
output [width-1:0] out;
|
||||
|
||||
// We use a two-stages shift-register to synchronize in to the clk_b clock domain
|
||||
reg [width-1:0] sync_clk_b [1:0];
|
||||
always @(posedge clk_b or posedge rst)
|
||||
begin
|
||||
if (rst == 1) begin
|
||||
sync_clk_b[0] <= 0;
|
||||
sync_clk_b[1] <= 0;
|
||||
end else begin
|
||||
sync_clk_b[0] <= in;
|
||||
sync_clk_b[1] <= sync_clk_b[0];
|
||||
end
|
||||
end
|
||||
|
||||
assign out = sync_clk_b[1]; // new signal synchronized to (=ready to be used in) clk_b domain
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,64 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE SD Card Controller IP Core ////
|
||||
//// ////
|
||||
//// edge_detect.v ////
|
||||
//// ////
|
||||
//// This file is part of the WISHBONE SD Card ////
|
||||
//// Controller IP Core project ////
|
||||
//// http://opencores.org/project,sd_card_controller ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// Signal edge detection. If input signal transitions between ////
|
||||
//// two states, output signal is generated for one clock cycle. ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013 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 ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
module edge_detect (
|
||||
input rst,
|
||||
input clk,
|
||||
input sig,
|
||||
output rise,
|
||||
output fall
|
||||
);
|
||||
|
||||
reg [1:0] sig_reg;
|
||||
|
||||
always @(posedge clk or posedge rst)
|
||||
if (rst == 1'b1)
|
||||
sig_reg <= 2'b00;
|
||||
else
|
||||
sig_reg <= {sig_reg[0], sig};
|
||||
|
||||
assign rise = sig_reg[0] == 1'b1 && sig_reg[1] == 1'b0 ? 1'b1 : 1'b0;
|
||||
assign fall = sig_reg[0] == 1'b0 && sig_reg[1] == 1'b1 ? 1'b1 : 1'b0;
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,501 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Generic Dual-Port Synchronous RAM ////
|
||||
//// ////
|
||||
//// This file is part of memory library available from ////
|
||||
//// http://www.opencores.org/cvsweb.shtml/generic_memories/ ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// This block is a wrapper with common dual-port ////
|
||||
//// synchronous memory interface for different ////
|
||||
//// types of ASIC and FPGA RAMs. Beside universal memory ////
|
||||
//// interface it also provides behavioral model of generic ////
|
||||
//// dual-port synchronous RAM. ////
|
||||
//// It also contains a fully synthesizeable model for FPGAs. ////
|
||||
//// It should be used in all OPENCORES designs that want to be ////
|
||||
//// portable accross different target technologies and ////
|
||||
//// independent of target memory. ////
|
||||
//// ////
|
||||
//// Supported ASIC RAMs are: ////
|
||||
//// - Artisan Dual-Port Sync RAM ////
|
||||
//// - Avant! Two-Port Sync RAM (*) ////
|
||||
//// - Virage 2-port Sync RAM ////
|
||||
//// ////
|
||||
//// Supported FPGA RAMs are: ////
|
||||
//// - Generic FPGA (VENDOR_FPGA) ////
|
||||
//// Tested RAMs: Altera, Xilinx ////
|
||||
//// Synthesis tools: LeonardoSpectrum, Synplicity ////
|
||||
//// - Xilinx (VENDOR_XILINX) ////
|
||||
//// - Altera (VENDOR_ALTERA) ////
|
||||
//// ////
|
||||
//// To Do: ////
|
||||
//// - fix Avant! ////
|
||||
//// - add additional RAMs (VS etc) ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Richard Herveille, richard@asics.ws ////
|
||||
//// - Damjan Lampret, lampret@opencores.org ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from http://www.opencores.org/lgpl.shtml ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CVS Revision History
|
||||
//
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.3 2001/11/09 00:34:18 samg
|
||||
// minor changes: unified with all common rams
|
||||
//
|
||||
// Revision 1.2 2001/11/08 19:11:31 samg
|
||||
// added valid checks to behvioral model
|
||||
//
|
||||
// Revision 1.1.1.1 2001/09/14 09:57:10 rherveille
|
||||
// Major cleanup.
|
||||
// Files are now compliant to Altera & Xilinx memories.
|
||||
// Memories are now compatible, i.e. drop-in replacements.
|
||||
// Added synthesizeable generic FPGA description.
|
||||
// Created "generic_memories" cvs entry.
|
||||
//
|
||||
// Revision 1.1.1.2 2001/08/21 13:09:27 damjan
|
||||
// *** empty log message ***
|
||||
//
|
||||
// Revision 1.1 2001/08/20 18:23:20 damjan
|
||||
// Initial revision
|
||||
//
|
||||
// Revision 1.1 2001/08/09 13:39:33 lampret
|
||||
// Major clean-up.
|
||||
//
|
||||
// Revision 1.2 2001/07/30 05:38:02 lampret
|
||||
// Adding empty directories required by HDL coding guidelines
|
||||
//
|
||||
//
|
||||
|
||||
//`include "timescale.v"
|
||||
|
||||
`define VENDOR_FPGA
|
||||
//`define VENDOR_XILINX
|
||||
//`define VENDOR_ALTERA
|
||||
|
||||
module generic_dpram(
|
||||
// Generic synchronous dual-port RAM interface
|
||||
rclk, rrst, rce, oe, raddr, do,
|
||||
wclk, wrst, wce, we, waddr, di
|
||||
);
|
||||
|
||||
//
|
||||
// Default address and data buses width
|
||||
//
|
||||
parameter aw = 5; // number of bits in address-bus
|
||||
parameter dw = 16; // number of bits in data-bus
|
||||
|
||||
//
|
||||
// Generic synchronous double-port RAM interface
|
||||
//
|
||||
// read port
|
||||
input rclk; // read clock, rising edge trigger
|
||||
input rrst; // read port reset, active high
|
||||
input rce; // read port chip enable, active high
|
||||
input oe; // output enable, active high
|
||||
input [aw-1:0] raddr; // read address
|
||||
output [dw-1:0] do; // data output
|
||||
|
||||
// write port
|
||||
input wclk; // write clock, rising edge trigger
|
||||
input wrst; // write port reset, active high
|
||||
input wce; // write port chip enable, active high
|
||||
input we; // write enable, active high
|
||||
input [aw-1:0] waddr; // write address
|
||||
input [dw-1:0] di; // data input
|
||||
|
||||
//
|
||||
// Module body
|
||||
//
|
||||
|
||||
`ifdef VENDOR_FPGA
|
||||
//
|
||||
// Instantiation synthesizeable FPGA memory
|
||||
//
|
||||
// This code has been tested using LeonardoSpectrum and Synplicity.
|
||||
// The code correctly instantiates Altera EABs and Xilinx BlockRAMs.
|
||||
//
|
||||
reg [dw-1:0] mem [(1<<aw) -1:0]; //pragma attribute mem block_ram false
|
||||
reg [aw-1:0] ra; // register read address
|
||||
|
||||
// read operation
|
||||
always @(posedge rclk)
|
||||
if (rce)
|
||||
ra <= raddr;
|
||||
|
||||
assign do = mem[ra];
|
||||
|
||||
// write operation
|
||||
always@(posedge wclk)
|
||||
if (we && wce)
|
||||
mem[waddr] <= di;
|
||||
|
||||
`else
|
||||
|
||||
`ifdef VENDOR_XILINX
|
||||
//
|
||||
// Instantiation of FPGA memory:
|
||||
//
|
||||
// Virtex/Spartan2 BlockRAMs
|
||||
//
|
||||
xilinx_ram_dp xilinx_ram(
|
||||
// read port
|
||||
.CLKA(rclk),
|
||||
.RSTA(rrst),
|
||||
.ENA(rce),
|
||||
.ADDRA(raddr),
|
||||
.DIA( {dw{1'b0}} ),
|
||||
.WEA(1'b0),
|
||||
.DOA(do),
|
||||
|
||||
// write port
|
||||
.CLKB(wclk),
|
||||
.RSTB(wrst),
|
||||
.ENB(wce),
|
||||
.ADDRB(waddr),
|
||||
.DIB(di),
|
||||
.WEB(we),
|
||||
.DOB()
|
||||
);
|
||||
|
||||
defparam
|
||||
xilinx_ram.dwidth = dw,
|
||||
xilinx_ram.awidth = aw;
|
||||
|
||||
`else
|
||||
|
||||
`ifdef VENDOR_ALTERA
|
||||
//
|
||||
// Instantiation of FPGA memory:
|
||||
//
|
||||
// Altera FLEX/APEX EABs
|
||||
//
|
||||
altera_ram_dp altera_ram(
|
||||
// read port
|
||||
.rdclock(rclk),
|
||||
.rdclocken(rce),
|
||||
.rdaddress(raddr),
|
||||
.q(do),
|
||||
|
||||
// write port
|
||||
.wrclock(wclk),
|
||||
.wrclocken(wce),
|
||||
.wren(we),
|
||||
.wraddress(waddr),
|
||||
.data(di)
|
||||
);
|
||||
|
||||
defparam
|
||||
altera_ram.dwidth = dw,
|
||||
altera_ram.awidth = aw;
|
||||
|
||||
`else
|
||||
|
||||
`ifdef VENDOR_ARTISAN
|
||||
|
||||
//
|
||||
// Instantiation of ASIC memory:
|
||||
//
|
||||
// Artisan Synchronous Double-Port RAM (ra2sh)
|
||||
//
|
||||
art_hsdp #(dw, 1<<aw, aw) artisan_sdp(
|
||||
// read port
|
||||
.qa(do),
|
||||
.clka(rclk),
|
||||
.cena(~rce),
|
||||
.wena(1'b1),
|
||||
.aa(raddr),
|
||||
.da( {dw{1'b0}} ),
|
||||
.oena(~oe),
|
||||
|
||||
// write port
|
||||
.qb(),
|
||||
.clkb(wclk),
|
||||
.cenb(~wce),
|
||||
.wenb(~we),
|
||||
.ab(waddr),
|
||||
.db(di),
|
||||
.oenb(1'b1)
|
||||
);
|
||||
|
||||
`else
|
||||
|
||||
`ifdef VENDOR_AVANT
|
||||
|
||||
//
|
||||
// Instantiation of ASIC memory:
|
||||
//
|
||||
// Avant! Asynchronous Two-Port RAM
|
||||
//
|
||||
avant_atp avant_atp(
|
||||
.web(~we),
|
||||
.reb(),
|
||||
.oeb(~oe),
|
||||
.rcsb(),
|
||||
.wcsb(),
|
||||
.ra(raddr),
|
||||
.wa(waddr),
|
||||
.di(di),
|
||||
.do(do)
|
||||
);
|
||||
|
||||
`else
|
||||
|
||||
`ifdef VENDOR_VIRAGE
|
||||
|
||||
//
|
||||
// Instantiation of ASIC memory:
|
||||
//
|
||||
// Virage Synchronous 2-port R/W RAM
|
||||
//
|
||||
virage_stp virage_stp(
|
||||
// read port
|
||||
.CLKA(rclk),
|
||||
.MEA(rce_a),
|
||||
.ADRA(raddr),
|
||||
.DA( {dw{1'b0}} ),
|
||||
.WEA(1'b0),
|
||||
.OEA(oe),
|
||||
.QA(do),
|
||||
|
||||
// write port
|
||||
.CLKB(wclk),
|
||||
.MEB(wce),
|
||||
.ADRB(waddr),
|
||||
.DB(di),
|
||||
.WEB(we),
|
||||
.OEB(1'b1),
|
||||
.QB()
|
||||
);
|
||||
|
||||
`else
|
||||
|
||||
//
|
||||
// Generic dual-port synchronous RAM model
|
||||
//
|
||||
|
||||
//
|
||||
// Generic RAM's registers and wires
|
||||
//
|
||||
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
|
||||
reg [dw-1:0] do_reg; // RAM data output register
|
||||
|
||||
//
|
||||
// Data output drivers
|
||||
//
|
||||
assign do = (oe & rce) ? do_reg : {dw{1'bz}};
|
||||
|
||||
// read operation
|
||||
always @(posedge rclk)
|
||||
if (rce)
|
||||
do_reg <= (we && (waddr==raddr)) ? {dw{1'b x}} : mem[raddr];
|
||||
|
||||
// write operation
|
||||
always @(posedge wclk)
|
||||
if (wce && we)
|
||||
mem[waddr] <= di;
|
||||
|
||||
|
||||
// Task prints range of memory
|
||||
// *** Remember that tasks are non reentrant, don't call this task in parallel for multiple instantiations.
|
||||
task print_ram;
|
||||
input [aw-1:0] start;
|
||||
input [aw-1:0] finish;
|
||||
integer rnum;
|
||||
begin
|
||||
for (rnum=start;rnum<=finish;rnum=rnum+1)
|
||||
$display("Addr %h = %h",rnum,mem[rnum]);
|
||||
end
|
||||
endtask
|
||||
|
||||
`endif // !VENDOR_VIRAGE
|
||||
`endif // !VENDOR_AVANT
|
||||
`endif // !VENDOR_ARTISAN
|
||||
`endif // !VENDOR_ALTERA
|
||||
`endif // !VENDOR_XILINX
|
||||
`endif // !VENDOR_FPGA
|
||||
|
||||
endmodule
|
||||
|
||||
//
|
||||
// Black-box modules
|
||||
//
|
||||
|
||||
`ifdef VENDOR_ALTERA
|
||||
module altera_ram_dp(
|
||||
data,
|
||||
wraddress,
|
||||
rdaddress,
|
||||
wren,
|
||||
wrclock,
|
||||
wrclocken,
|
||||
rdclock,
|
||||
rdclocken,
|
||||
q) /* synthesis black_box */;
|
||||
|
||||
parameter awidth = 7;
|
||||
parameter dwidth = 8;
|
||||
|
||||
input [dwidth -1:0] data;
|
||||
input [awidth -1:0] wraddress;
|
||||
input [awidth -1:0] rdaddress;
|
||||
input wren;
|
||||
input wrclock;
|
||||
input wrclocken;
|
||||
input rdclock;
|
||||
input rdclocken;
|
||||
output [dwidth -1:0] q;
|
||||
|
||||
// synopsis translate_off
|
||||
// exemplar translate_off
|
||||
|
||||
syn_dpram_rowr #(
|
||||
"UNUSED",
|
||||
dwidth,
|
||||
awidth,
|
||||
1 << awidth
|
||||
)
|
||||
altera_dpram_model (
|
||||
// read port
|
||||
.RdClock(rdclock),
|
||||
.RdClken(rdclocken),
|
||||
.RdAddress(rdaddress),
|
||||
.RdEn(1'b1),
|
||||
.Q(q),
|
||||
|
||||
// write port
|
||||
.WrClock(wrclock),
|
||||
.WrClken(wrclocken),
|
||||
.WrAddress(wraddress),
|
||||
.WrEn(wren),
|
||||
.Data(data)
|
||||
);
|
||||
|
||||
// exemplar translate_on
|
||||
// synopsis translate_on
|
||||
|
||||
endmodule
|
||||
`endif // VENDOR_ALTERA
|
||||
|
||||
`ifdef VENDOR_XILINX
|
||||
module xilinx_ram_dp (
|
||||
ADDRA,
|
||||
CLKA,
|
||||
ADDRB,
|
||||
CLKB,
|
||||
DIA,
|
||||
WEA,
|
||||
DIB,
|
||||
WEB,
|
||||
ENA,
|
||||
ENB,
|
||||
RSTA,
|
||||
RSTB,
|
||||
DOA,
|
||||
DOB) /* synthesis black_box */ ;
|
||||
|
||||
parameter awidth = 7;
|
||||
parameter dwidth = 8;
|
||||
|
||||
// port_a
|
||||
input CLKA;
|
||||
input RSTA;
|
||||
input ENA;
|
||||
input [awidth-1:0] ADDRA;
|
||||
input [dwidth-1:0] DIA;
|
||||
input WEA;
|
||||
output [dwidth-1:0] DOA;
|
||||
|
||||
// port_b
|
||||
input CLKB;
|
||||
input RSTB;
|
||||
input ENB;
|
||||
input [awidth-1:0] ADDRB;
|
||||
input [dwidth-1:0] DIB;
|
||||
input WEB;
|
||||
output [dwidth-1:0] DOB;
|
||||
|
||||
// insert simulation model
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
// exemplar translate_off
|
||||
|
||||
C_MEM_DP_BLOCK_V1_0 #(
|
||||
awidth,
|
||||
awidth,
|
||||
1,
|
||||
1,
|
||||
"0",
|
||||
1 << awidth,
|
||||
1 << awidth,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
"",
|
||||
16,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
dwidth,
|
||||
dwidth)
|
||||
xilinx_dpram_model (
|
||||
.ADDRA(ADDRA),
|
||||
.CLKA(CLKA),
|
||||
.ADDRB(ADDRB),
|
||||
.CLKB(CLKB),
|
||||
.DIA(DIA),
|
||||
.WEA(WEA),
|
||||
.DIB(DIB),
|
||||
.WEB(WEB),
|
||||
.ENA(ENA),
|
||||
.ENB(ENB),
|
||||
.RSTA(RSTA),
|
||||
.RSTB(RSTB),
|
||||
.DOA(DOA),
|
||||
.DOB(DOB));
|
||||
|
||||
// exemplar translate_on
|
||||
// synopsys translate_on
|
||||
|
||||
endmodule
|
||||
`endif // VENDOR_XILINX
|
|
@ -0,0 +1,324 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Universal FIFO Dual Clock, gray encoded ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Author: Rudolf Usselmann ////
|
||||
//// rudi@asics.ws ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// D/L from: http://www.opencores.org/cores/generic_fifos/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// 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: generic_fifo_dc_gray.v,v 1.2 2004-01-13 09:11:55 rudi Exp $
|
||||
//
|
||||
// $Date: 2004-01-13 09:11:55 $
|
||||
// $Revision: 1.2 $
|
||||
// $Author: rudi $
|
||||
// $Locker: $
|
||||
// $State: Exp $
|
||||
//
|
||||
// Change History:
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.1 2003/10/14 09:34:41 rudi
|
||||
// Dual clock FIFO Gray Code encoded version.
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
//`include "timescale.v"
|
||||
|
||||
/*
|
||||
|
||||
Description
|
||||
===========
|
||||
|
||||
I/Os
|
||||
----
|
||||
rd_clk Read Port Clock
|
||||
wr_clk Write Port Clock
|
||||
rst low active, either sync. or async. master reset (see below how to select)
|
||||
clr synchronous clear (just like reset but always synchronous), high active
|
||||
re read enable, synchronous, high active
|
||||
we read enable, synchronous, high active
|
||||
din Data Input
|
||||
dout Data Output
|
||||
|
||||
full Indicates the FIFO is full (driven at the rising edge of wr_clk)
|
||||
empty Indicates the FIFO is empty (driven at the rising edge of rd_clk)
|
||||
|
||||
wr_level indicates the FIFO level:
|
||||
2'b00 0-25% full
|
||||
2'b01 25-50% full
|
||||
2'b10 50-75% full
|
||||
2'b11 %75-100% full
|
||||
|
||||
rd_level indicates the FIFO level:
|
||||
2'b00 0-25% empty
|
||||
2'b01 25-50% empty
|
||||
2'b10 50-75% empty
|
||||
2'b11 %75-100% empty
|
||||
|
||||
Status Timing
|
||||
-------------
|
||||
All status outputs are registered. They are asserted immediately
|
||||
as the full/empty condition occurs, however, there is a 2 cycle
|
||||
delay before they are de-asserted once the condition is not true
|
||||
anymore.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
The FIFO takes 2 parameters:
|
||||
dw Data bus width
|
||||
aw Address bus width (Determines the FIFO size by evaluating 2^aw)
|
||||
|
||||
Synthesis Results
|
||||
-----------------
|
||||
In a Spartan 2e a 8 bit wide, 8 entries deep FIFO, takes 97 LUTs and runs
|
||||
at about 113 MHz (IO insertion disabled).
|
||||
|
||||
Misc
|
||||
----
|
||||
This design assumes you will do appropriate status checking externally.
|
||||
|
||||
IMPORTANT ! writing while the FIFO is full or reading while the FIFO is
|
||||
empty will place the FIFO in an undefined state.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
module generic_fifo_dc_gray( rd_clk, wr_clk, rst, clr, din, we,
|
||||
dout, re, full, empty, wr_level, rd_level );
|
||||
|
||||
parameter dw=16;
|
||||
parameter aw=8;
|
||||
|
||||
input rd_clk, wr_clk, rst, clr;
|
||||
input [dw-1:0] din;
|
||||
input we;
|
||||
output [dw-1:0] dout;
|
||||
input re;
|
||||
output full;
|
||||
output empty;
|
||||
output [1:0] wr_level;
|
||||
output [1:0] rd_level;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Local Wires
|
||||
//
|
||||
|
||||
reg [aw:0] wp_bin, wp_gray;
|
||||
reg [aw:0] rp_bin, rp_gray;
|
||||
reg [aw:0] wp_s, rp_s;
|
||||
reg full, empty;
|
||||
|
||||
wire [aw:0] wp_bin_next, wp_gray_next;
|
||||
wire [aw:0] rp_bin_next, rp_gray_next;
|
||||
|
||||
wire [aw:0] wp_bin_x, rp_bin_x;
|
||||
reg [aw-1:0] d1, d2;
|
||||
|
||||
reg rd_rst, wr_rst;
|
||||
reg rd_rst_r, wr_rst_r;
|
||||
reg rd_clr, wr_clr;
|
||||
reg rd_clr_r, wr_clr_r;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Reset Logic
|
||||
//
|
||||
|
||||
always @(posedge rd_clk or negedge rst)
|
||||
if(!rst) rd_rst <= 1'b0;
|
||||
else
|
||||
if(rd_rst_r) rd_rst <= 1'b1; // Release Reset
|
||||
|
||||
always @(posedge rd_clk or negedge rst)
|
||||
if(!rst) rd_rst_r <= 1'b0;
|
||||
else rd_rst_r <= 1'b1;
|
||||
|
||||
always @(posedge wr_clk or negedge rst)
|
||||
if(!rst) wr_rst <= 1'b0;
|
||||
else
|
||||
if(wr_rst_r) wr_rst <= 1'b1; // Release Reset
|
||||
|
||||
always @(posedge wr_clk or negedge rst)
|
||||
if(!rst) wr_rst_r <= 1'b0;
|
||||
else wr_rst_r <= 1'b1;
|
||||
|
||||
always @(posedge rd_clk or posedge clr)
|
||||
if(clr) rd_clr <= 1'b1;
|
||||
else
|
||||
if(!rd_clr_r) rd_clr <= 1'b0; // Release Clear
|
||||
|
||||
always @(posedge rd_clk or posedge clr)
|
||||
if(clr) rd_clr_r <= 1'b1;
|
||||
else rd_clr_r <= 1'b0;
|
||||
|
||||
always @(posedge wr_clk or posedge clr)
|
||||
if(clr) wr_clr <= 1'b1;
|
||||
else
|
||||
if(!wr_clr_r) wr_clr <= 1'b0; // Release Clear
|
||||
|
||||
always @(posedge wr_clk or posedge clr)
|
||||
if(clr) wr_clr_r <= 1'b1;
|
||||
else wr_clr_r <= 1'b0;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Memory Block
|
||||
//
|
||||
|
||||
generic_dpram #(aw,dw) u0(
|
||||
.rclk( rd_clk ),
|
||||
.rrst( !rd_rst ),
|
||||
.rce( 1'b1 ),
|
||||
.oe( 1'b1 ),
|
||||
.raddr( rp_bin[aw-1:0] ),
|
||||
.do( dout ),
|
||||
.wclk( wr_clk ),
|
||||
.wrst( !wr_rst ),
|
||||
.wce( 1'b1 ),
|
||||
.we( we ),
|
||||
.waddr( wp_bin[aw-1:0] ),
|
||||
.di( din )
|
||||
);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Read/Write Pointers Logic
|
||||
//
|
||||
|
||||
always @(posedge wr_clk)
|
||||
if(!wr_rst) wp_bin <= {aw+1{1'b0}};
|
||||
else
|
||||
if(wr_clr) wp_bin <= {aw+1{1'b0}};
|
||||
else
|
||||
if(we) wp_bin <= wp_bin_next;
|
||||
|
||||
always @(posedge wr_clk)
|
||||
if(!wr_rst) wp_gray <= {aw+1{1'b0}};
|
||||
else
|
||||
if(wr_clr) wp_gray <= {aw+1{1'b0}};
|
||||
else
|
||||
if(we) wp_gray <= wp_gray_next;
|
||||
|
||||
assign wp_bin_next = wp_bin + {{aw{1'b0}},1'b1};
|
||||
assign wp_gray_next = wp_bin_next ^ {1'b0, wp_bin_next[aw:1]};
|
||||
|
||||
always @(posedge rd_clk)
|
||||
if(!rd_rst) rp_bin <= {aw+1{1'b0}};
|
||||
else
|
||||
if(rd_clr) rp_bin <= {aw+1{1'b0}};
|
||||
else
|
||||
if(re) rp_bin <= rp_bin_next;
|
||||
|
||||
always @(posedge rd_clk)
|
||||
if(!rd_rst) rp_gray <= {aw+1{1'b0}};
|
||||
else
|
||||
if(rd_clr) rp_gray <= {aw+1{1'b0}};
|
||||
else
|
||||
if(re) rp_gray <= rp_gray_next;
|
||||
|
||||
assign rp_bin_next = rp_bin + {{aw{1'b0}},1'b1};
|
||||
assign rp_gray_next = rp_bin_next ^ {1'b0, rp_bin_next[aw:1]};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Synchronization Logic
|
||||
//
|
||||
|
||||
// write pointer
|
||||
always @(posedge rd_clk) wp_s <= wp_gray;
|
||||
|
||||
// read pointer
|
||||
always @(posedge wr_clk) rp_s <= rp_gray;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Registered Full & Empty Flags
|
||||
//
|
||||
|
||||
assign wp_bin_x = wp_s ^ {1'b0, wp_bin_x[aw:1]}; // convert gray to binary
|
||||
assign rp_bin_x = rp_s ^ {1'b0, rp_bin_x[aw:1]}; // convert gray to binary
|
||||
|
||||
always @(posedge rd_clk)
|
||||
empty <= (wp_s == rp_gray) | (re & (wp_s == rp_gray_next));
|
||||
|
||||
always @(posedge wr_clk)
|
||||
full <= ((wp_bin[aw-1:0] == rp_bin_x[aw-1:0]) & (wp_bin[aw] != rp_bin_x[aw])) |
|
||||
(we & (wp_bin_next[aw-1:0] == rp_bin_x[aw-1:0]) & (wp_bin_next[aw] != rp_bin_x[aw]));
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Registered Level Indicators
|
||||
//
|
||||
reg [1:0] wr_level;
|
||||
reg [1:0] rd_level;
|
||||
reg [aw-1:0] wp_bin_xr, rp_bin_xr;
|
||||
reg full_rc;
|
||||
reg full_wc;
|
||||
|
||||
always @(posedge wr_clk) full_wc <= full;
|
||||
always @(posedge wr_clk) rp_bin_xr <= ~rp_bin_x[aw-1:0] + {{aw-1{1'b0}}, 1'b1};
|
||||
always @(posedge wr_clk) d1 <= wp_bin[aw-1:0] + rp_bin_xr[aw-1:0];
|
||||
|
||||
always @(posedge wr_clk) wr_level <= {d1[aw-1] | full | full_wc, d1[aw-2] | full | full_wc};
|
||||
|
||||
always @(posedge rd_clk) wp_bin_xr <= ~wp_bin_x[aw-1:0];
|
||||
always @(posedge rd_clk) d2 <= rp_bin[aw-1:0] + wp_bin_xr[aw-1:0];
|
||||
|
||||
always @(posedge rd_clk) full_rc <= full;
|
||||
always @(posedge rd_clk) rd_level <= full_rc ? 2'h0 : {d2[aw-1] | empty, d2[aw-2] | empty};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Sanity Check
|
||||
//
|
||||
|
||||
// synopsys translate_off
|
||||
//always @(posedge wr_clk)
|
||||
// if(we && full)
|
||||
// $display("%m WARNING: Writing while fifo is FULL (%t)",$time);
|
||||
|
||||
//always @(posedge rd_clk)
|
||||
// if(re && empty)
|
||||
// $display("%m WARNING: Reading while fifo is EMPTY (%t)",$time);
|
||||
// synopsys translate_on
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE SD Card Controller IP Core ////
|
||||
//// ////
|
||||
//// monostable_domain_cross.v ////
|
||||
//// ////
|
||||
//// This file is part of the WISHBONE SD Card ////
|
||||
//// Controller IP Core project ////
|
||||
//// http://opencores.org/project,sd_card_controller ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// Clock synchronisation beetween two clock domains. ////
|
||||
//// Assumption is that input signal duration is always ////
|
||||
//// one clk_a clock period. If that is true output signal ////
|
||||
//// duration is always one clk_b clock period. ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013 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 ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
module monostable_domain_cross(
|
||||
input rst,
|
||||
input clk_a,
|
||||
input in,
|
||||
input clk_b,
|
||||
output out
|
||||
);
|
||||
|
||||
// this changes level when the in is seen in clk_a
|
||||
reg toggle_clk_a;
|
||||
always @(posedge clk_a or posedge rst)
|
||||
begin
|
||||
if (rst)
|
||||
toggle_clk_a <= 0;
|
||||
else
|
||||
toggle_clk_a <= toggle_clk_a ^ in;
|
||||
end
|
||||
|
||||
// which can then be sync-ed to clk_b
|
||||
reg [2:0] sync_clk_b;
|
||||
always @(posedge clk_b or posedge rst)
|
||||
begin
|
||||
if (rst)
|
||||
sync_clk_b <= 0;
|
||||
else
|
||||
sync_clk_b <= {sync_clk_b[1:0], toggle_clk_a};
|
||||
end
|
||||
|
||||
// and recreate the flag in clk_b
|
||||
assign out = (sync_clk_b[2] ^ sync_clk_b[1]);
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,79 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE SD Card Controller IP Core ////
|
||||
//// ////
|
||||
//// sd_clock_divider.v ////
|
||||
//// ////
|
||||
//// This file is part of the WISHBONE SD Card ////
|
||||
//// Controller IP Core project ////
|
||||
//// http://opencores.org/project,sd_card_controller ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// Control of sd card clock rate ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 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 ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
module sd_clock_divider (
|
||||
input CLK,
|
||||
input [7:0] DIVIDER,
|
||||
input RST,
|
||||
output SD_CLK
|
||||
);
|
||||
|
||||
reg [7:0] ClockDiv;
|
||||
reg SD_CLK_O;
|
||||
|
||||
//assign SD_CLK = DIVIDER[7] ? CLK : SD_CLK_O;
|
||||
assign SD_CLK = SD_CLK_O;
|
||||
|
||||
always @(posedge CLK or posedge RST)
|
||||
begin
|
||||
if (RST) begin
|
||||
ClockDiv <= 8'b0000_0000;
|
||||
SD_CLK_O <= 0;
|
||||
end
|
||||
else if (ClockDiv == DIVIDER) begin
|
||||
ClockDiv <= 0;
|
||||
SD_CLK_O <= ~SD_CLK_O;
|
||||
end else begin
|
||||
ClockDiv <= ClockDiv + 8'h1;
|
||||
SD_CLK_O <= SD_CLK_O;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE SD Card Controller IP Core ////
|
||||
//// ////
|
||||
//// sd_cmd_master.v ////
|
||||
//// ////
|
||||
//// This file is part of the WISHBONE SD Card ////
|
||||
//// Controller IP Core project ////
|
||||
//// http://opencores.org/project,sd_card_controller ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// State machine resposible for controlling command transfers ////
|
||||
//// on 1-bit sd card command interface ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 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 "sd_defines.h"
|
||||
|
||||
module sd_cmd_master(
|
||||
input sd_clk,
|
||||
input rst,
|
||||
input start_i,
|
||||
input int_status_rst_i,
|
||||
output [1:0] setting_o,
|
||||
output reg start_xfr_o,
|
||||
output reg go_idle_o,
|
||||
output reg [39:0] cmd_o,
|
||||
input [119:0] response_i,
|
||||
input crc_ok_i,
|
||||
input index_ok_i,
|
||||
input finish_i,
|
||||
input busy_i, //direct signal from data sd data input (data[0])
|
||||
//input card_detect,
|
||||
input [31:0] argument_i,
|
||||
input [`CMD_REG_SIZE-1:0] command_i,
|
||||
input [15:0] timeout_i,
|
||||
output [`INT_CMD_SIZE-1:0] int_status_o,
|
||||
output reg [31:0] response_0_o,
|
||||
output reg [31:0] response_1_o,
|
||||
output reg [31:0] response_2_o,
|
||||
output reg [31:0] response_3_o
|
||||
);
|
||||
|
||||
//-----------Types--------------------------------------------------------
|
||||
reg [15:0] timeout_reg;
|
||||
reg crc_check;
|
||||
reg index_check;
|
||||
reg busy_check;
|
||||
reg expect_response;
|
||||
reg long_response;
|
||||
reg [`INT_CMD_SIZE-1:0] int_status_reg;
|
||||
//reg card_present;
|
||||
//reg [3:0]debounce;
|
||||
reg [15:0] watchdog;
|
||||
parameter SIZE = 2;
|
||||
reg [SIZE-1:0] state;
|
||||
reg [SIZE-1:0] next_state;
|
||||
parameter IDLE = 2'b00;
|
||||
parameter EXECUTE = 2'b01;
|
||||
parameter BUSY_CHECK = 2'b10;
|
||||
|
||||
assign setting_o[1:0] = {long_response, expect_response};
|
||||
assign int_status_o = state == IDLE ? int_status_reg : 5'h0;
|
||||
|
||||
//---------------Input ports---------------
|
||||
|
||||
// always @ (posedge sd_clk or posedge rst )
|
||||
// begin
|
||||
// if (rst) begin
|
||||
// debounce<=0;
|
||||
// card_present<=0;
|
||||
// end
|
||||
// else begin
|
||||
// if (!card_detect) begin//Card present
|
||||
// if (debounce!=4'b1111)
|
||||
// debounce<=debounce+1'b1;
|
||||
// end
|
||||
// else
|
||||
// debounce<=0;
|
||||
//
|
||||
// if (debounce==4'b1111)
|
||||
// card_present<=1'b1;
|
||||
// else
|
||||
// card_present<=1'b0;
|
||||
// end
|
||||
// end
|
||||
|
||||
always @(state or start_i or finish_i or go_idle_o or busy_check or busy_i)
|
||||
begin: FSM_COMBO
|
||||
case(state)
|
||||
IDLE: begin
|
||||
if (start_i)
|
||||
next_state <= EXECUTE;
|
||||
else
|
||||
next_state <= IDLE;
|
||||
end
|
||||
EXECUTE: begin
|
||||
if ((finish_i && !busy_check) || go_idle_o)
|
||||
next_state <= IDLE;
|
||||
else if (finish_i && busy_check)
|
||||
next_state <= BUSY_CHECK;
|
||||
else
|
||||
next_state <= EXECUTE;
|
||||
end
|
||||
BUSY_CHECK: begin
|
||||
if (!busy_i)
|
||||
next_state <= IDLE;
|
||||
else
|
||||
next_state <= BUSY_CHECK;
|
||||
end
|
||||
default: next_state <= IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge sd_clk or posedge rst)
|
||||
begin: FSM_SEQ
|
||||
if (rst) begin
|
||||
state <= IDLE;
|
||||
end
|
||||
else begin
|
||||
state <= next_state;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge sd_clk or posedge rst)
|
||||
begin
|
||||
if (rst) begin
|
||||
crc_check <= 0;
|
||||
response_0_o <= 0;
|
||||
response_1_o <= 0;
|
||||
response_2_o <= 0;
|
||||
response_3_o <= 0;
|
||||
int_status_reg <= 0;
|
||||
expect_response <= 0;
|
||||
long_response <= 0;
|
||||
cmd_o <= 0;
|
||||
start_xfr_o <= 0;
|
||||
index_check <= 0;
|
||||
busy_check <= 0;
|
||||
watchdog <= 0;
|
||||
timeout_reg <= 0;
|
||||
go_idle_o <= 0;
|
||||
end
|
||||
else begin
|
||||
case(state)
|
||||
IDLE: begin
|
||||
go_idle_o <= 0;
|
||||
index_check <= command_i[`CMD_IDX_CHECK];
|
||||
crc_check <= command_i[`CMD_CRC_CHECK];
|
||||
busy_check <= command_i[`CMD_BUSY_CHECK];
|
||||
if (command_i[`CMD_RESPONSE_CHECK] == 2'b10 || command_i[`CMD_RESPONSE_CHECK] == 2'b11) begin
|
||||
expect_response <= 1;
|
||||
long_response <= 1;
|
||||
end
|
||||
else if (command_i[`CMD_RESPONSE_CHECK] == 2'b01) begin
|
||||
expect_response <= 1;
|
||||
long_response <= 0;
|
||||
end
|
||||
else begin
|
||||
expect_response <= 0;
|
||||
long_response <= 0;
|
||||
end
|
||||
cmd_o[39:38] <= 2'b01;
|
||||
cmd_o[37:32] <= command_i[`CMD_INDEX]; //CMD_INDEX
|
||||
cmd_o[31:0] <= argument_i; //CMD_Argument
|
||||
timeout_reg <= timeout_i;
|
||||
watchdog <= 0;
|
||||
if (start_i) begin
|
||||
start_xfr_o <= 1;
|
||||
int_status_reg <= 0;
|
||||
end
|
||||
end
|
||||
EXECUTE: begin
|
||||
start_xfr_o <= 0;
|
||||
watchdog <= watchdog + 16'd1;
|
||||
if (watchdog > timeout_reg) begin
|
||||
int_status_reg[`INT_CMD_CTE] <= 1;
|
||||
int_status_reg[`INT_CMD_EI] <= 1;
|
||||
go_idle_o <= 1;
|
||||
end
|
||||
//Incoming New Status
|
||||
else begin //if ( req_in_int == 1) begin
|
||||
if (finish_i) begin //Data avaible
|
||||
if (crc_check & !crc_ok_i) begin
|
||||
int_status_reg[`INT_CMD_CCRCE] <= 1;
|
||||
int_status_reg[`INT_CMD_EI] <= 1;
|
||||
end
|
||||
if (index_check & !index_ok_i) begin
|
||||
int_status_reg[`INT_CMD_CIE] <= 1;
|
||||
int_status_reg[`INT_CMD_EI] <= 1;
|
||||
end
|
||||
int_status_reg[`INT_CMD_CC] <= 1;
|
||||
if (expect_response != 0) begin
|
||||
response_0_o <= response_i[119:88];
|
||||
response_1_o <= response_i[87:56];
|
||||
response_2_o <= response_i[55:24];
|
||||
response_3_o <= {response_i[23:0], 8'h00};
|
||||
end
|
||||
// end
|
||||
end ////Data avaible
|
||||
end //Status change
|
||||
end //EXECUTE state
|
||||
BUSY_CHECK: begin
|
||||
start_xfr_o <= 0;
|
||||
go_idle_o <= 0;
|
||||
end
|
||||
endcase
|
||||
if (int_status_rst_i)
|
||||
int_status_reg <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,336 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE SD Card Controller IP Core ////
|
||||
//// ////
|
||||
//// sd_cmd_serial_host.v ////
|
||||
//// ////
|
||||
//// This file is part of the WISHBONE SD Card ////
|
||||
//// Controller IP Core project ////
|
||||
//// http://opencores.org/project,sd_card_controller ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// Module resposible for sending and receiving commands ////
|
||||
//// through 1-bit sd card command interface ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 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 ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
module sd_cmd_serial_host (
|
||||
sd_clk,
|
||||
rst,
|
||||
setting_i,
|
||||
cmd_i,
|
||||
start_i,
|
||||
response_o,
|
||||
crc_ok_o,
|
||||
index_ok_o,
|
||||
finish_o,
|
||||
cmd_dat_i,
|
||||
cmd_out_o,
|
||||
cmd_oe_o
|
||||
);
|
||||
|
||||
//---------------Input ports---------------
|
||||
input sd_clk;
|
||||
input rst;
|
||||
input [1:0] setting_i;
|
||||
input [39:0] cmd_i;
|
||||
input start_i;
|
||||
input cmd_dat_i;
|
||||
//---------------Output ports---------------
|
||||
output reg [119:0] response_o;
|
||||
output reg finish_o;
|
||||
output reg crc_ok_o;
|
||||
output reg index_ok_o;
|
||||
output reg cmd_oe_o;
|
||||
output reg cmd_out_o;
|
||||
|
||||
//-------------Internal Constant-------------
|
||||
parameter INIT_DELAY = 4;
|
||||
parameter BITS_TO_SEND = 48;
|
||||
parameter CMD_SIZE = 40;
|
||||
parameter RESP_SIZE = 128;
|
||||
|
||||
//---------------Internal variable-----------
|
||||
reg cmd_dat_reg;
|
||||
integer resp_len;
|
||||
reg with_response;
|
||||
reg [CMD_SIZE-1:0] cmd_buff;
|
||||
reg [RESP_SIZE-1:0] resp_buff;
|
||||
integer resp_idx;
|
||||
//CRC
|
||||
reg crc_rst;
|
||||
reg [6:0]crc_in;
|
||||
wire [6:0] crc_val;
|
||||
reg crc_enable;
|
||||
reg crc_bit;
|
||||
reg crc_ok;
|
||||
//-Internal Counterns
|
||||
integer counter;
|
||||
//-State Machine
|
||||
parameter STATE_SIZE = 10;
|
||||
parameter
|
||||
INIT = 7'h00,
|
||||
IDLE = 7'h01,
|
||||
SETUP_CRC = 7'h02,
|
||||
WRITE = 7'h04,
|
||||
READ_WAIT = 7'h08,
|
||||
READ = 7'h10,
|
||||
FINISH_WR = 7'h20,
|
||||
FINISH_WO = 7'h40;
|
||||
reg [STATE_SIZE-1:0] state;
|
||||
reg [STATE_SIZE-1:0] next_state;
|
||||
//Misc
|
||||
`define cmd_idx (CMD_SIZE-1-counter)
|
||||
|
||||
//sd cmd input pad register
|
||||
always @(posedge sd_clk)
|
||||
cmd_dat_reg <= cmd_dat_i;
|
||||
|
||||
//------------------------------------------
|
||||
sd_crc_7 CRC_7(
|
||||
crc_bit,
|
||||
crc_enable,
|
||||
sd_clk,
|
||||
crc_rst,
|
||||
crc_val);
|
||||
|
||||
//------------------------------------------
|
||||
always @(state or counter or start_i or with_response or cmd_dat_reg or resp_len)
|
||||
begin: FSM_COMBO
|
||||
case(state)
|
||||
INIT: begin
|
||||
if (counter >= INIT_DELAY) begin
|
||||
next_state <= IDLE;
|
||||
end
|
||||
else begin
|
||||
next_state <= INIT;
|
||||
end
|
||||
end
|
||||
IDLE: begin
|
||||
if (start_i) begin
|
||||
next_state <= SETUP_CRC;
|
||||
end
|
||||
else begin
|
||||
next_state <= IDLE;
|
||||
end
|
||||
end
|
||||
SETUP_CRC:
|
||||
next_state <= WRITE;
|
||||
WRITE:
|
||||
if (counter >= BITS_TO_SEND && with_response) begin
|
||||
next_state <= READ_WAIT;
|
||||
end
|
||||
else if (counter >= BITS_TO_SEND) begin
|
||||
next_state <= FINISH_WO;
|
||||
end
|
||||
else begin
|
||||
next_state <= WRITE;
|
||||
end
|
||||
READ_WAIT:
|
||||
if (!cmd_dat_reg) begin
|
||||
next_state <= READ;
|
||||
end
|
||||
else begin
|
||||
next_state <= READ_WAIT;
|
||||
end
|
||||
FINISH_WO:
|
||||
next_state <= IDLE;
|
||||
READ:
|
||||
if (counter >= resp_len+8) begin
|
||||
next_state <= FINISH_WR;
|
||||
end
|
||||
else begin
|
||||
next_state <= READ;
|
||||
end
|
||||
FINISH_WR:
|
||||
next_state <= IDLE;
|
||||
default:
|
||||
next_state <= INIT;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge sd_clk or posedge rst)
|
||||
begin: COMMAND_DECODER
|
||||
if (rst) begin
|
||||
resp_len <= 0;
|
||||
with_response <= 0;
|
||||
cmd_buff <= 0;
|
||||
end
|
||||
else begin
|
||||
if (start_i == 1) begin
|
||||
resp_len <= setting_i[1] ? 127 : 39;
|
||||
with_response <= setting_i[0];
|
||||
cmd_buff <= cmd_i;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//----------------Seq logic------------
|
||||
always @(posedge sd_clk or posedge rst)
|
||||
begin: FSM_SEQ
|
||||
if (rst) begin
|
||||
state <= INIT;
|
||||
end
|
||||
else begin
|
||||
state <= next_state;
|
||||
end
|
||||
end
|
||||
|
||||
//-------------OUTPUT_LOGIC-------
|
||||
always @(posedge sd_clk or posedge rst)
|
||||
begin: FSM_OUT
|
||||
if (rst) begin
|
||||
crc_enable <= 0;
|
||||
resp_idx <= 0;
|
||||
cmd_oe_o <= 1;
|
||||
cmd_out_o <= 1;
|
||||
resp_buff <= 0;
|
||||
finish_o <= 0;
|
||||
crc_rst <= 1;
|
||||
crc_bit <= 0;
|
||||
crc_in <= 0;
|
||||
response_o <= 0;
|
||||
index_ok_o <= 0;
|
||||
crc_ok_o <= 0;
|
||||
crc_ok <= 0;
|
||||
counter <= 0;
|
||||
end
|
||||
else begin
|
||||
case(state)
|
||||
INIT: begin
|
||||
counter <= counter+1;
|
||||
cmd_oe_o <= 1;
|
||||
cmd_out_o <= 1;
|
||||
end
|
||||
IDLE: begin
|
||||
cmd_oe_o <= 0; //Put CMD to Z
|
||||
counter <= 0;
|
||||
crc_rst <= 1;
|
||||
crc_enable <= 0;
|
||||
response_o <= 0;
|
||||
resp_idx <= 0;
|
||||
crc_ok_o <= 0;
|
||||
index_ok_o <= 0;
|
||||
finish_o <= 0;
|
||||
end
|
||||
SETUP_CRC: begin
|
||||
crc_rst <= 0;
|
||||
crc_enable <= 1;
|
||||
crc_bit <= cmd_buff[`cmd_idx];
|
||||
end
|
||||
WRITE: begin
|
||||
if (counter < BITS_TO_SEND-8) begin // 1->40 CMD, (41 >= CNT && CNT <=47) CRC, 48 stop_bit
|
||||
cmd_oe_o <= 1;
|
||||
cmd_out_o <= cmd_buff[`cmd_idx];
|
||||
if (counter < BITS_TO_SEND-9) begin //1 step ahead
|
||||
crc_bit <= cmd_buff[`cmd_idx-1];
|
||||
end else begin
|
||||
crc_enable <= 0;
|
||||
end
|
||||
end
|
||||
else if (counter < BITS_TO_SEND-1) begin
|
||||
cmd_oe_o <= 1;
|
||||
crc_enable <= 0;
|
||||
cmd_out_o <= crc_val[BITS_TO_SEND-counter-2];
|
||||
end
|
||||
else if (counter == BITS_TO_SEND-1) begin
|
||||
cmd_oe_o <= 1;
|
||||
cmd_out_o <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
cmd_oe_o <= 0;
|
||||
cmd_out_o <= 1'b1;
|
||||
end
|
||||
counter <= counter+1;
|
||||
end
|
||||
READ_WAIT: begin
|
||||
crc_enable <= 0;
|
||||
crc_rst <= 1;
|
||||
counter <= 1;
|
||||
cmd_oe_o <= 0;
|
||||
resp_buff[RESP_SIZE-1] <= cmd_dat_reg;
|
||||
end
|
||||
FINISH_WO: begin
|
||||
finish_o <= 1;
|
||||
crc_enable <= 0;
|
||||
crc_rst <= 1;
|
||||
counter <= 0;
|
||||
cmd_oe_o <= 0;
|
||||
end
|
||||
READ: begin
|
||||
crc_rst <= 0;
|
||||
crc_enable <= (resp_len != RESP_SIZE-1 || counter > 7);
|
||||
cmd_oe_o <= 0;
|
||||
if (counter <= resp_len) begin
|
||||
if (counter < 8) //1+1+6 (S,T,Index)
|
||||
resp_buff[RESP_SIZE-1-counter] <= cmd_dat_reg;
|
||||
else begin
|
||||
resp_idx <= resp_idx + 1;
|
||||
resp_buff[RESP_SIZE-9-resp_idx] <= cmd_dat_reg;
|
||||
end
|
||||
crc_bit <= cmd_dat_reg;
|
||||
end
|
||||
else if (counter-resp_len <= 7) begin
|
||||
crc_in[(resp_len+7)-(counter)] <= cmd_dat_reg;
|
||||
crc_enable <= 0;
|
||||
end
|
||||
else begin
|
||||
crc_enable <= 0;
|
||||
if (crc_in == crc_val) crc_ok <= 1;
|
||||
else crc_ok <= 0;
|
||||
end
|
||||
counter <= counter + 1;
|
||||
end
|
||||
FINISH_WR: begin
|
||||
if (cmd_buff[37:32] == resp_buff[125:120])
|
||||
index_ok_o <= 1;
|
||||
else
|
||||
index_ok_o <= 0;
|
||||
crc_ok_o <= crc_ok;
|
||||
finish_o <= 1;
|
||||
crc_enable <= 0;
|
||||
crc_rst <= 1;
|
||||
counter <= 0;
|
||||
cmd_oe_o <= 0;
|
||||
response_o <= resp_buff[119:0];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -0,0 +1,195 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE SD Card Controller IP Core ////
|
||||
//// ////
|
||||
//// sd_controller_wb.v ////
|
||||
//// ////
|
||||
//// This file is part of the WISHBONE SD Card ////
|
||||
//// Controller IP Core project ////
|
||||
//// http://opencores.org/project,sd_card_controller ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// Wishbone interface responsible for comunication with core ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 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 "sd_defines.h"
|
||||
|
||||
module sd_controller_wb(
|
||||
// WISHBONE slave
|
||||
wb_clk_i, wb_rst_i, wb_dat_i, wb_dat_o,
|
||||
wb_adr_i, wb_sel_i, wb_we_i, wb_cyc_i, wb_stb_i, wb_ack_o,
|
||||
cmd_start,
|
||||
data_int_rst,
|
||||
cmd_int_rst,
|
||||
argument_reg,
|
||||
command_reg,
|
||||
response_0_reg,
|
||||
response_1_reg,
|
||||
response_2_reg,
|
||||
response_3_reg,
|
||||
software_reset_reg,
|
||||
timeout_reg,
|
||||
block_size_reg,
|
||||
controll_setting_reg,
|
||||
cmd_int_status_reg,
|
||||
cmd_int_enable_reg,
|
||||
clock_divider_reg,
|
||||
block_count_reg,
|
||||
dma_addr_reg,
|
||||
data_int_status_reg,
|
||||
data_int_enable_reg
|
||||
);
|
||||
|
||||
// WISHBONE common
|
||||
input wb_clk_i; // WISHBONE clock
|
||||
input wb_rst_i; // WISHBONE reset
|
||||
input [31:0] wb_dat_i; // WISHBONE data input
|
||||
output reg [31:0] wb_dat_o; // WISHBONE data output
|
||||
// WISHBONE error output
|
||||
|
||||
// WISHBONE slave
|
||||
input [7:0] wb_adr_i; // WISHBONE address input
|
||||
input [3:0] wb_sel_i; // WISHBONE byte select input
|
||||
input wb_we_i; // WISHBONE write enable input
|
||||
input wb_cyc_i; // WISHBONE cycle input
|
||||
input wb_stb_i; // WISHBONE strobe input
|
||||
output reg wb_ack_o; // WISHBONE acknowledge output
|
||||
output reg cmd_start;
|
||||
//Buss accessible registers
|
||||
output reg [31:0] argument_reg;
|
||||
output reg [`CMD_REG_SIZE-1:0] command_reg;
|
||||
input wire [31:0] response_0_reg;
|
||||
input wire [31:0] response_1_reg;
|
||||
input wire [31:0] response_2_reg;
|
||||
input wire [31:0] response_3_reg;
|
||||
output reg [0:0] software_reset_reg;
|
||||
output reg [15:0] timeout_reg;
|
||||
output reg [`BLKSIZE_W-1:0] block_size_reg;
|
||||
output reg [15:0] controll_setting_reg;
|
||||
input wire [`INT_CMD_SIZE-1:0] cmd_int_status_reg;
|
||||
output reg [`INT_CMD_SIZE-1:0] cmd_int_enable_reg;
|
||||
output reg [7:0] clock_divider_reg;
|
||||
input wire [`INT_DATA_SIZE-1:0] data_int_status_reg;
|
||||
output reg [`INT_DATA_SIZE-1:0] data_int_enable_reg;
|
||||
//Register Controll
|
||||
output reg data_int_rst;
|
||||
output reg cmd_int_rst;
|
||||
output reg [`BLKCNT_W-1:0]block_count_reg;
|
||||
output reg [31:0] dma_addr_reg;
|
||||
|
||||
parameter voltage_controll_reg = `SUPPLY_VOLTAGE_mV;
|
||||
parameter capabilies_reg = 16'b0000_0000_0000_0000;
|
||||
|
||||
always @(posedge wb_clk_i or posedge wb_rst_i)
|
||||
begin
|
||||
if (wb_rst_i)begin
|
||||
argument_reg <= 0;
|
||||
command_reg <= 0;
|
||||
software_reset_reg <= 0;
|
||||
timeout_reg <= 0;
|
||||
block_size_reg <= `RESET_BLOCK_SIZE;
|
||||
controll_setting_reg <= 0;
|
||||
cmd_int_enable_reg <= 0;
|
||||
clock_divider_reg <= `RESET_CLK_DIV;
|
||||
wb_ack_o <= 0;
|
||||
cmd_start <= 0;
|
||||
data_int_rst <= 0;
|
||||
data_int_enable_reg <= 0;
|
||||
cmd_int_rst <= 0;
|
||||
block_count_reg <= 0;
|
||||
dma_addr_reg <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
cmd_start <= 1'b0;
|
||||
data_int_rst <= 0;
|
||||
cmd_int_rst <= 0;
|
||||
if ((wb_stb_i & wb_cyc_i) || wb_ack_o)begin
|
||||
if (wb_we_i) begin
|
||||
case (wb_adr_i)
|
||||
`argument: begin
|
||||
argument_reg <= wb_dat_i;
|
||||
cmd_start <= 1'b1;
|
||||
end
|
||||
`command: command_reg <= wb_dat_i[`CMD_REG_SIZE-1:0];
|
||||
`reset: software_reset_reg <= wb_dat_i[0];
|
||||
`timeout: timeout_reg <= wb_dat_i[15:0];
|
||||
`blksize: block_size_reg <= wb_dat_i[`BLKSIZE_W-1:0];
|
||||
`controller: controll_setting_reg <= wb_dat_i[15:0];
|
||||
`cmd_iser: cmd_int_enable_reg <= wb_dat_i[4:0];
|
||||
`cmd_isr: cmd_int_rst <= 1;
|
||||
`clock_d: clock_divider_reg <= wb_dat_i[7:0];
|
||||
`data_isr: data_int_rst <= 1;
|
||||
`data_iser: data_int_enable_reg <= wb_dat_i[`INT_DATA_SIZE-1:0];
|
||||
`dst_src_addr: dma_addr_reg <= wb_dat_i;
|
||||
`blkcnt: block_count_reg <= wb_dat_i[`BLKCNT_W-1:0];
|
||||
endcase
|
||||
end
|
||||
wb_ack_o <= wb_cyc_i & wb_stb_i & ~wb_ack_o;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge wb_clk_i or posedge wb_rst_i)begin
|
||||
if (wb_rst_i == 1)
|
||||
wb_dat_o <= 0;
|
||||
else
|
||||
if (wb_stb_i & wb_cyc_i) begin //CS
|
||||
case (wb_adr_i)
|
||||
`argument: wb_dat_o <= argument_reg;
|
||||
`command: wb_dat_o <= command_reg;
|
||||
`resp0: wb_dat_o <= response_0_reg;
|
||||
`resp1: wb_dat_o <= response_1_reg;
|
||||
`resp2: wb_dat_o <= response_2_reg;
|
||||
`resp3: wb_dat_o <= response_3_reg;
|
||||
`controller: wb_dat_o <= controll_setting_reg;
|
||||
`blksize: wb_dat_o <= block_size_reg;
|
||||
`voltage: wb_dat_o <= voltage_controll_reg;
|
||||
`reset: wb_dat_o <= software_reset_reg;
|
||||
`timeout: wb_dat_o <= timeout_reg;
|
||||
`cmd_isr: wb_dat_o <= cmd_int_status_reg;
|
||||
`cmd_iser: wb_dat_o <= cmd_int_enable_reg;
|
||||
`clock_d: wb_dat_o <= clock_divider_reg;
|
||||
`capa: wb_dat_o <= capabilies_reg;
|
||||
`data_isr: wb_dat_o <= data_int_status_reg;
|
||||
`blkcnt: wb_dat_o <= block_count_reg;
|
||||
`data_iser: wb_dat_o <= data_int_enable_reg;
|
||||
`dst_src_addr: wb_dat_o <= dma_addr_reg;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,43 @@
|
|||
// ==========================================================================
|
||||
// CRC Generation Unit - Linear Feedback Shift Register implementation
|
||||
// (c) Kay Gorontzi, GHSi.de, distributed under the terms of LGPL
|
||||
// ==========================================================================
|
||||
module sd_crc_16(BITVAL, ENABLE, BITSTRB, CLEAR, CRC);
|
||||
input BITVAL; // Next input bit
|
||||
input ENABLE; // Enable calculation
|
||||
input BITSTRB; // Current bit valid (Clock)
|
||||
input CLEAR; // Init CRC value
|
||||
output [15:0] CRC; // Current output CRC value
|
||||
|
||||
reg [15:0] CRC; // We need output registers
|
||||
wire inv;
|
||||
|
||||
assign inv = BITVAL ^ CRC[15]; // XOR required?
|
||||
|
||||
always @(posedge BITSTRB or posedge CLEAR) begin
|
||||
if (CLEAR) begin
|
||||
CRC <= 0; // Init before calculation
|
||||
end
|
||||
else begin
|
||||
if (ENABLE == 1) begin
|
||||
CRC[15] <= CRC[14];
|
||||
CRC[14] <= CRC[13];
|
||||
CRC[13] <= CRC[12];
|
||||
CRC[12] <= CRC[11] ^ inv;
|
||||
CRC[11] <= CRC[10];
|
||||
CRC[10] <= CRC[9];
|
||||
CRC[9] <= CRC[8];
|
||||
CRC[8] <= CRC[7];
|
||||
CRC[7] <= CRC[6];
|
||||
CRC[6] <= CRC[5];
|
||||
CRC[5] <= CRC[4] ^ inv;
|
||||
CRC[4] <= CRC[3];
|
||||
CRC[3] <= CRC[2];
|
||||
CRC[2] <= CRC[1];
|
||||
CRC[1] <= CRC[0];
|
||||
CRC[0] <= inv;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,34 @@
|
|||
// ==========================================================================
|
||||
// CRC Generation Unit - Linear Feedback Shift Register implementation
|
||||
// (c) Kay Gorontzi, GHSi.de, distributed under the terms of LGPL
|
||||
// ==========================================================================
|
||||
module sd_crc_7(BITVAL, ENABLE, BITSTRB, CLEAR, CRC);
|
||||
input BITVAL; // Next input bit
|
||||
input ENABLE; // Enable calculation
|
||||
input BITSTRB; // Current bit valid (Clock)
|
||||
input CLEAR; // Init CRC value
|
||||
output [6:0] CRC; // Current output CRC value
|
||||
|
||||
reg [6:0] CRC; // We need output registers
|
||||
wire inv;
|
||||
|
||||
assign inv = BITVAL ^ CRC[6]; // XOR required?
|
||||
|
||||
always @(posedge BITSTRB or posedge CLEAR) begin
|
||||
if (CLEAR) begin
|
||||
CRC <= 0; // Init before calculation
|
||||
end
|
||||
else begin
|
||||
if (ENABLE == 1) begin
|
||||
CRC[6] <= CRC[5];
|
||||
CRC[5] <= CRC[4];
|
||||
CRC[4] <= CRC[3];
|
||||
CRC[3] <= CRC[2] ^ inv;
|
||||
CRC[2] <= CRC[1];
|
||||
CRC[1] <= CRC[0];
|
||||
CRC[0] <= inv;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,209 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE SD Card Controller IP Core ////
|
||||
//// ////
|
||||
//// sd_data_master.v ////
|
||||
//// ////
|
||||
//// This file is part of the WISHBONE SD Card ////
|
||||
//// Controller IP Core project ////
|
||||
//// http://opencores.org/project,sd_card_controller ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// State machine resposible for controlling data transfers ////
|
||||
//// on 4-bit sd card data interface ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 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 "sd_defines.h"
|
||||
|
||||
module sd_data_master (
|
||||
input sd_clk,
|
||||
input rst,
|
||||
input start_tx_i,
|
||||
input start_rx_i,
|
||||
//Output to SD-Host Reg
|
||||
output reg d_write_o,
|
||||
output reg d_read_o,
|
||||
//To fifo filler
|
||||
output reg start_tx_fifo_o,
|
||||
output reg start_rx_fifo_o,
|
||||
input tx_fifo_empty_i,
|
||||
input tx_fifo_full_i,
|
||||
input rx_fifo_full_i,
|
||||
//SD-DATA_Host
|
||||
input xfr_complete_i,
|
||||
input crc_ok_i,
|
||||
//status output
|
||||
output reg [`INT_DATA_SIZE-1:0] int_status_o,
|
||||
input int_status_rst_i
|
||||
);
|
||||
|
||||
reg tx_cycle;
|
||||
parameter SIZE = 3;
|
||||
reg [SIZE-1:0] state;
|
||||
reg [SIZE-1:0] next_state;
|
||||
parameter IDLE = 3'b000;
|
||||
parameter START_TX_FIFO = 3'b001;
|
||||
parameter START_RX_FIFO = 3'b010;
|
||||
parameter DATA_TRANSFER = 3'b100;
|
||||
|
||||
reg trans_done;
|
||||
|
||||
always @(state or start_tx_i or start_rx_i or tx_fifo_full_i or xfr_complete_i or trans_done)
|
||||
begin: FSM_COMBO
|
||||
case(state)
|
||||
IDLE: begin
|
||||
if (start_tx_i == 1) begin
|
||||
next_state <= START_TX_FIFO;
|
||||
end
|
||||
else if (start_rx_i == 1) begin
|
||||
next_state <= START_RX_FIFO;
|
||||
end
|
||||
else begin
|
||||
next_state <= IDLE;
|
||||
end
|
||||
end
|
||||
START_TX_FIFO: begin
|
||||
if (tx_fifo_full_i == 1 && xfr_complete_i == 0)
|
||||
next_state <= DATA_TRANSFER;
|
||||
else
|
||||
next_state <= START_TX_FIFO;
|
||||
end
|
||||
START_RX_FIFO: begin
|
||||
if (xfr_complete_i == 0)
|
||||
next_state <= DATA_TRANSFER;
|
||||
else
|
||||
next_state <= START_RX_FIFO;
|
||||
end
|
||||
DATA_TRANSFER: begin
|
||||
if (trans_done)
|
||||
next_state <= IDLE;
|
||||
else
|
||||
next_state <= DATA_TRANSFER;
|
||||
end
|
||||
default: next_state <= IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
//----------------Seq logic------------
|
||||
always @(posedge sd_clk or posedge rst)
|
||||
begin: FSM_SEQ
|
||||
if (rst) begin
|
||||
state <= IDLE;
|
||||
end
|
||||
else begin
|
||||
state <= next_state;
|
||||
end
|
||||
end
|
||||
|
||||
//Output logic-----------------
|
||||
always @(posedge sd_clk or posedge rst)
|
||||
begin
|
||||
if (rst) begin
|
||||
start_tx_fifo_o <= 0;
|
||||
start_rx_fifo_o <= 0;
|
||||
d_write_o <= 0;
|
||||
d_read_o <= 0;
|
||||
trans_done <= 0;
|
||||
tx_cycle <= 0;
|
||||
int_status_o <= 0;
|
||||
end
|
||||
else begin
|
||||
case(state)
|
||||
IDLE: begin
|
||||
start_tx_fifo_o <= 0;
|
||||
start_rx_fifo_o <= 0;
|
||||
d_write_o <= 0;
|
||||
d_read_o <= 0;
|
||||
trans_done <= 0;
|
||||
tx_cycle <= 0;
|
||||
end
|
||||
START_RX_FIFO: begin
|
||||
start_rx_fifo_o <= 1;
|
||||
start_tx_fifo_o <= 0;
|
||||
tx_cycle <= 0;
|
||||
d_read_o <= 1;
|
||||
end
|
||||
START_TX_FIFO: begin
|
||||
start_rx_fifo_o <= 0;
|
||||
start_tx_fifo_o <= 1;
|
||||
tx_cycle <= 1;
|
||||
if (tx_fifo_full_i == 1)
|
||||
d_write_o <= 1;
|
||||
end
|
||||
DATA_TRANSFER: begin
|
||||
d_read_o <= 0;
|
||||
d_write_o <= 0;
|
||||
if (tx_cycle) begin
|
||||
if (tx_fifo_empty_i) begin
|
||||
if (!trans_done)
|
||||
int_status_o[`INT_DATA_CFE] <= 1;
|
||||
trans_done <= 1;
|
||||
//stop sd_data_serial_host
|
||||
d_write_o <= 1;
|
||||
d_read_o <= 1;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
if (rx_fifo_full_i) begin
|
||||
if (!trans_done)
|
||||
int_status_o[`INT_DATA_CFE] <= 1;
|
||||
trans_done <= 1;
|
||||
//stop sd_data_serial_host
|
||||
d_write_o <= 1;
|
||||
d_read_o <= 1;
|
||||
end
|
||||
end
|
||||
if (xfr_complete_i) begin //Transfer complete
|
||||
d_write_o <= 0;
|
||||
d_read_o <= 0;
|
||||
trans_done <= 1;
|
||||
if (!crc_ok_i) begin //Wrong CRC and Data line free.
|
||||
if (!trans_done)
|
||||
int_status_o[`INT_DATA_CCRCE] <= 1;
|
||||
end
|
||||
else if (crc_ok_i) begin //Data Line free
|
||||
if (!trans_done)
|
||||
int_status_o[`INT_DATA_CC] <= 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
if (int_status_rst_i)
|
||||
int_status_o<=0;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,374 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE SD Card Controller IP Core ////
|
||||
//// ////
|
||||
//// sd_data_serial_host.v ////
|
||||
//// ////
|
||||
//// This file is part of the WISHBONE SD Card ////
|
||||
//// Controller IP Core project ////
|
||||
//// http://opencores.org/project,sd_card_controller ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// Module resposible for sending and receiving data through ////
|
||||
//// 4-bit sd card data interface ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 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 "sd_defines.h"
|
||||
|
||||
module sd_data_serial_host(
|
||||
input sd_clk,
|
||||
input rst,
|
||||
//Tx Fifo
|
||||
input [31:0] data_in,
|
||||
output reg rd,
|
||||
//Rx Fifo
|
||||
output reg [31:0] data_out,
|
||||
output reg we,
|
||||
//tristate data
|
||||
output reg DAT_oe_o,
|
||||
output reg[3:0] DAT_dat_o,
|
||||
input [3:0] DAT_dat_i,
|
||||
//Controll signals
|
||||
input [`BLKSIZE_W-1:0] blksize,
|
||||
input bus_4bit,
|
||||
input [`BLKCNT_W-1:0] blkcnt,
|
||||
input [1:0] start,
|
||||
output sd_data_busy,
|
||||
output busy,
|
||||
output reg crc_ok
|
||||
);
|
||||
|
||||
reg [3:0] DAT_dat_reg;
|
||||
reg [`BLKSIZE_W-1+3:0] data_cycles;
|
||||
reg bus_4bit_reg;
|
||||
//CRC16
|
||||
reg [3:0] crc_in;
|
||||
reg crc_en;
|
||||
reg crc_rst;
|
||||
wire [15:0] crc_out [3:0];
|
||||
reg [15:0] transf_cnt;
|
||||
parameter SIZE = 6;
|
||||
reg [SIZE-1:0] state;
|
||||
reg [SIZE-1:0] next_state;
|
||||
parameter IDLE = 6'b000001;
|
||||
parameter WRITE_DAT = 6'b000010;
|
||||
parameter WRITE_CRC = 6'b000100;
|
||||
parameter WRITE_BUSY = 6'b001000;
|
||||
parameter READ_WAIT = 6'b010000;
|
||||
parameter READ_DAT = 6'b100000;
|
||||
reg [2:0] crc_status;
|
||||
reg busy_int;
|
||||
reg [`BLKCNT_W-1:0] blkcnt_reg;
|
||||
reg next_block;
|
||||
wire start_bit;
|
||||
reg [4:0] crc_c;
|
||||
reg [3:0] last_din;
|
||||
reg [2:0] crc_s ;
|
||||
reg [4:0] data_send_index;
|
||||
|
||||
//sd data input pad register
|
||||
always @(posedge sd_clk)
|
||||
DAT_dat_reg <= DAT_dat_i;
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for(i=0; i<4; i=i+1) begin: CRC_16_gen
|
||||
sd_crc_16 CRC_16_i (crc_in[i],crc_en, sd_clk, crc_rst, crc_out[i]);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign busy = (state != IDLE);
|
||||
assign start_bit = !DAT_dat_reg[0];
|
||||
assign sd_data_busy = !DAT_dat_reg[0];
|
||||
|
||||
always @(state or start or start_bit or transf_cnt or data_cycles or crc_status or crc_ok or busy_int or next_block)
|
||||
begin: FSM_COMBO
|
||||
case(state)
|
||||
IDLE: begin
|
||||
if (start == 2'b01)
|
||||
next_state <= WRITE_DAT;
|
||||
else if (start == 2'b10)
|
||||
next_state <= READ_WAIT;
|
||||
else
|
||||
next_state <= IDLE;
|
||||
end
|
||||
WRITE_DAT: begin
|
||||
if (transf_cnt >= data_cycles+21 && start_bit)
|
||||
next_state <= WRITE_CRC;
|
||||
else if (start == 2'b11)
|
||||
next_state <= IDLE;
|
||||
else
|
||||
next_state <= WRITE_DAT;
|
||||
end
|
||||
WRITE_CRC: begin
|
||||
if (crc_status == 3)
|
||||
next_state <= WRITE_BUSY;
|
||||
else
|
||||
next_state <= WRITE_CRC;
|
||||
end
|
||||
WRITE_BUSY: begin
|
||||
if (!busy_int && next_block && crc_ok)
|
||||
next_state <= WRITE_DAT;
|
||||
else if (!busy_int)
|
||||
next_state <= IDLE;
|
||||
else
|
||||
next_state <= WRITE_BUSY;
|
||||
end
|
||||
READ_WAIT: begin
|
||||
if (start_bit)
|
||||
next_state <= READ_DAT;
|
||||
else
|
||||
next_state <= READ_WAIT;
|
||||
end
|
||||
READ_DAT: begin
|
||||
if (transf_cnt == data_cycles+17 && next_block && crc_ok)
|
||||
next_state <= READ_WAIT;
|
||||
else if (transf_cnt == data_cycles+17)
|
||||
next_state <= IDLE;
|
||||
else if (start == 2'b11)
|
||||
next_state <= IDLE;
|
||||
else
|
||||
next_state <= READ_DAT;
|
||||
end
|
||||
default: next_state <= IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge sd_clk or posedge rst)
|
||||
begin: FSM_OUT
|
||||
if (rst) begin
|
||||
state <= IDLE;
|
||||
DAT_oe_o <= 0;
|
||||
crc_en <= 0;
|
||||
crc_rst <= 1;
|
||||
transf_cnt <= 0;
|
||||
crc_c <= 15;
|
||||
rd <= 0;
|
||||
last_din <= 0;
|
||||
crc_c <= 0;
|
||||
crc_in <= 0;
|
||||
DAT_dat_o <= 0;
|
||||
crc_status <= 0;
|
||||
crc_s <= 0;
|
||||
we <= 0;
|
||||
data_out <= 0;
|
||||
crc_ok <= 0;
|
||||
busy_int <= 0;
|
||||
data_send_index <= 0;
|
||||
next_block <= 0;
|
||||
blkcnt_reg <= 0;
|
||||
data_cycles <= 0;
|
||||
bus_4bit_reg <= 0;
|
||||
end
|
||||
else begin
|
||||
state <= next_state;
|
||||
case(state)
|
||||
IDLE: begin
|
||||
DAT_oe_o <= 0;
|
||||
DAT_dat_o <= 4'b1111;
|
||||
crc_en <= 0;
|
||||
crc_rst <= 1;
|
||||
transf_cnt <= 0;
|
||||
crc_c <= 16;
|
||||
crc_status <= 0;
|
||||
crc_s <= 0;
|
||||
we <= 0;
|
||||
rd <= 0;
|
||||
data_send_index <= 0;
|
||||
next_block <= 0;
|
||||
blkcnt_reg <= blkcnt;
|
||||
data_cycles <= (bus_4bit ? (blksize << 1) : (blksize << 3));
|
||||
bus_4bit_reg <= bus_4bit;
|
||||
end
|
||||
WRITE_DAT: begin
|
||||
crc_ok <= 0;
|
||||
transf_cnt <= transf_cnt + 16'h1;
|
||||
next_block <= 0;
|
||||
rd <= 0;
|
||||
if (transf_cnt == 1) begin
|
||||
crc_rst <= 0;
|
||||
crc_en <= 1;
|
||||
if (bus_4bit_reg) begin
|
||||
last_din <= data_in[31:28];
|
||||
crc_in <= data_in[31:28];
|
||||
end
|
||||
else begin
|
||||
last_din <= {3'h7, data_in[31]};
|
||||
crc_in <= {3'h7, data_in[31]};
|
||||
end
|
||||
DAT_oe_o <= 1;
|
||||
DAT_dat_o <= bus_4bit_reg ? 4'h0 : 4'he;
|
||||
data_send_index <= 1;
|
||||
end
|
||||
else if ((transf_cnt >= 2) && (transf_cnt <= data_cycles+1)) begin
|
||||
DAT_oe_o<=1;
|
||||
if (bus_4bit_reg) begin
|
||||
last_din <= {
|
||||
data_in[31-(data_send_index[2:0]<<2)],
|
||||
data_in[30-(data_send_index[2:0]<<2)],
|
||||
data_in[29-(data_send_index[2:0]<<2)],
|
||||
data_in[28-(data_send_index[2:0]<<2)]
|
||||
};
|
||||
crc_in <= {
|
||||
data_in[31-(data_send_index[2:0]<<2)],
|
||||
data_in[30-(data_send_index[2:0]<<2)],
|
||||
data_in[29-(data_send_index[2:0]<<2)],
|
||||
data_in[28-(data_send_index[2:0]<<2)]
|
||||
};
|
||||
if (data_send_index[2:0] == 3'h5/*not 7 - read delay !!!*/) begin
|
||||
rd <= 1;
|
||||
end
|
||||
if (data_send_index[2:0] == 3'h7) begin
|
||||
data_send_index <= 0;
|
||||
end
|
||||
else
|
||||
data_send_index<=data_send_index + 5'h1;
|
||||
end
|
||||
else begin
|
||||
last_din <= {3'h7, data_in[31-data_send_index]};
|
||||
crc_in <= {3'h7, data_in[31-data_send_index]};
|
||||
if (data_send_index == 29/*not 31 - read delay !!!*/) begin
|
||||
rd <= 1;
|
||||
end
|
||||
if (data_send_index == 31) begin
|
||||
data_send_index <= 0;
|
||||
end
|
||||
else
|
||||
data_send_index<=data_send_index + 5'h1;
|
||||
end
|
||||
DAT_dat_o<= last_din;
|
||||
if (transf_cnt == data_cycles+1)
|
||||
crc_en<=0;
|
||||
end
|
||||
else if (transf_cnt > data_cycles+1 & crc_c!=0) begin
|
||||
crc_en <= 0;
|
||||
crc_c <= crc_c - 5'h1;
|
||||
DAT_oe_o <= 1;
|
||||
DAT_dat_o[0] <= crc_out[0][crc_c-1];
|
||||
if (bus_4bit_reg)
|
||||
DAT_dat_o[3:1] <= {crc_out[3][crc_c-1], crc_out[2][crc_c-1], crc_out[1][crc_c-1]};
|
||||
else
|
||||
DAT_dat_o[3:1] <= {3'h7};
|
||||
end
|
||||
else if (transf_cnt == data_cycles+18) begin
|
||||
DAT_oe_o <= 1;
|
||||
DAT_dat_o <= 4'hf;
|
||||
end
|
||||
else if (transf_cnt >= data_cycles+19) begin
|
||||
DAT_oe_o <= 0;
|
||||
end
|
||||
end
|
||||
WRITE_CRC: begin
|
||||
DAT_oe_o <= 0;
|
||||
if (crc_status < 3)
|
||||
crc_s[crc_status] <= DAT_dat_reg[0];
|
||||
crc_status <= crc_status + 3'h1;
|
||||
busy_int <= 1;
|
||||
end
|
||||
WRITE_BUSY: begin
|
||||
if (crc_s == 3'b010)
|
||||
crc_ok <= 1;
|
||||
else
|
||||
crc_ok <= 0;
|
||||
busy_int <= !DAT_dat_reg[0];
|
||||
next_block <= (blkcnt_reg != 0);
|
||||
if (next_state != WRITE_BUSY) begin
|
||||
blkcnt_reg <= blkcnt_reg - `BLKCNT_W'h1;
|
||||
crc_rst <= 1;
|
||||
crc_c <= 16;
|
||||
crc_status <= 0;
|
||||
end
|
||||
transf_cnt <= 0;
|
||||
end
|
||||
READ_WAIT: begin
|
||||
DAT_oe_o <= 0;
|
||||
crc_rst <= 0;
|
||||
crc_en <= 1;
|
||||
crc_in <= 0;
|
||||
crc_c <= 15;// end
|
||||
next_block <= 0;
|
||||
transf_cnt <= 0;
|
||||
end
|
||||
READ_DAT: begin
|
||||
if (transf_cnt < data_cycles) begin
|
||||
if (bus_4bit_reg) begin
|
||||
we <= (transf_cnt[2:0] == 7);
|
||||
data_out[31-(transf_cnt[2:0]<<2)] <= DAT_dat_reg[3];
|
||||
data_out[30-(transf_cnt[2:0]<<2)] <= DAT_dat_reg[2];
|
||||
data_out[29-(transf_cnt[2:0]<<2)] <= DAT_dat_reg[1];
|
||||
data_out[28-(transf_cnt[2:0]<<2)] <= DAT_dat_reg[0];
|
||||
end
|
||||
else begin
|
||||
we <= (transf_cnt[4:0] == 31);
|
||||
data_out[31-transf_cnt[4:0]] <= DAT_dat_reg[0];
|
||||
end
|
||||
crc_in <= DAT_dat_reg;
|
||||
crc_ok <= 1;
|
||||
transf_cnt <= transf_cnt + 16'h1;
|
||||
end
|
||||
else if (transf_cnt <= data_cycles+16) begin
|
||||
transf_cnt <= transf_cnt + 16'h1;
|
||||
crc_en <= 0;
|
||||
last_din <= DAT_dat_reg;
|
||||
we<=0;
|
||||
if (transf_cnt > data_cycles) begin
|
||||
crc_c <= crc_c - 5'h1;
|
||||
if (crc_out[0][crc_c] != last_din[0])
|
||||
crc_ok <= 0;
|
||||
if (crc_out[1][crc_c] != last_din[1] && bus_4bit_reg)
|
||||
crc_ok<=0;
|
||||
if (crc_out[2][crc_c] != last_din[2] && bus_4bit_reg)
|
||||
crc_ok <= 0;
|
||||
if (crc_out[3][crc_c] != last_din[3] && bus_4bit_reg)
|
||||
crc_ok <= 0;
|
||||
if (crc_c == 0) begin
|
||||
next_block <= (blkcnt_reg != 0);
|
||||
blkcnt_reg <= blkcnt_reg - `BLKCNT_W'h1;
|
||||
crc_rst <= 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE SD Card Controller IP Core ////
|
||||
//// ////
|
||||
//// sd_data_xfer_trig.v ////
|
||||
//// ////
|
||||
//// This file is part of the WISHBONE SD Card ////
|
||||
//// Controller IP Core project ////
|
||||
//// http://opencores.org/project,sd_card_controller ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// Module resposible for triggering data transfer based on ////
|
||||
//// command transfer completition code ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013 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 "sd_defines.h"
|
||||
|
||||
module sd_data_xfer_trig (
|
||||
input sd_clk,
|
||||
input rst,
|
||||
input cmd_with_data_start_i,
|
||||
input r_w_i,
|
||||
input [`INT_CMD_SIZE-1:0] cmd_int_status_i,
|
||||
output reg start_tx_o,
|
||||
output reg start_rx_o
|
||||
);
|
||||
|
||||
reg r_w_reg;
|
||||
parameter SIZE = 2;
|
||||
reg [SIZE-1:0] state;
|
||||
reg [SIZE-1:0] next_state;
|
||||
parameter IDLE = 2'b00;
|
||||
parameter WAIT_FOR_CMD_INT = 2'b01;
|
||||
parameter TRIGGER_XFER = 2'b10;
|
||||
|
||||
always @(state or cmd_with_data_start_i or r_w_i or cmd_int_status_i)
|
||||
begin: FSM_COMBO
|
||||
case(state)
|
||||
IDLE: begin
|
||||
if (cmd_with_data_start_i & r_w_i)
|
||||
next_state <= TRIGGER_XFER;
|
||||
else if (cmd_with_data_start_i)
|
||||
next_state <= WAIT_FOR_CMD_INT;
|
||||
else
|
||||
next_state <= IDLE;
|
||||
end
|
||||
WAIT_FOR_CMD_INT: begin
|
||||
if (cmd_int_status_i[`INT_CMD_CC])
|
||||
next_state <= TRIGGER_XFER;
|
||||
else if (cmd_int_status_i[`INT_CMD_EI])
|
||||
next_state <= IDLE;
|
||||
else
|
||||
next_state <= WAIT_FOR_CMD_INT;
|
||||
end
|
||||
TRIGGER_XFER: begin
|
||||
next_state <= IDLE;
|
||||
end
|
||||
default: next_state <= IDLE;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge sd_clk or posedge rst)
|
||||
begin: FSM_SEQ
|
||||
if (rst) begin
|
||||
state <= IDLE;
|
||||
end
|
||||
else begin
|
||||
state <= next_state;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge sd_clk or posedge rst)
|
||||
begin
|
||||
if (rst) begin
|
||||
start_tx_o <= 0;
|
||||
start_rx_o <= 0;
|
||||
r_w_reg <= 0;
|
||||
end
|
||||
else begin
|
||||
case(state)
|
||||
IDLE: begin
|
||||
start_tx_o <= 0;
|
||||
start_rx_o <= 0;
|
||||
r_w_reg <= r_w_i;
|
||||
end
|
||||
WAIT_FOR_CMD_INT: begin
|
||||
start_tx_o <= 0;
|
||||
start_rx_o <= 0;
|
||||
end
|
||||
TRIGGER_XFER: begin
|
||||
start_tx_o <= ~r_w_reg;
|
||||
start_rx_o <= r_w_reg;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
|
@ -0,0 +1,148 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE SD Card Controller IP Core ////
|
||||
//// ////
|
||||
//// sd_fifo_filler.v ////
|
||||
//// ////
|
||||
//// This file is part of the WISHBONE SD Card ////
|
||||
//// Controller IP Core project ////
|
||||
//// http://opencores.org/project,sd_card_controller ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// Fifo interface between sd card and wishbone clock domains ////
|
||||
//// and DMA engine eble to write/read to/from CPU memory ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 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 ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
module sd_fifo_filler(
|
||||
input wb_clk,
|
||||
input rst,
|
||||
//WB Signals
|
||||
output [31:0] wbm_adr_o,
|
||||
output wbm_we_o,
|
||||
output [31:0] wbm_dat_o,
|
||||
input [31:0] wbm_dat_i,
|
||||
output wbm_cyc_o,
|
||||
output wbm_stb_o,
|
||||
input wbm_ack_i,
|
||||
//Data Master Control signals
|
||||
input en_rx_i,
|
||||
input en_tx_i,
|
||||
input [31:0] adr_i,
|
||||
//Data Serial signals
|
||||
input sd_clk,
|
||||
input [31:0] dat_i,
|
||||
output [31:0] dat_o,
|
||||
input wr_i,
|
||||
input rd_i,
|
||||
output sd_full_o,
|
||||
output sd_empty_o,
|
||||
output wb_full_o,
|
||||
output wb_empty_o
|
||||
);
|
||||
|
||||
`define FIFO_MEM_ADR_SIZE 4
|
||||
`define MEM_OFFSET 4
|
||||
|
||||
wire reset_fifo;
|
||||
wire fifo_rd;
|
||||
reg [31:0] offset;
|
||||
reg fifo_rd_ack;
|
||||
reg fifo_rd_reg;
|
||||
|
||||
assign fifo_rd = wbm_cyc_o & wbm_ack_i;
|
||||
assign reset_fifo = !en_rx_i & !en_tx_i;
|
||||
|
||||
assign wbm_we_o = en_rx_i & !wb_empty_o;
|
||||
assign wbm_cyc_o = en_rx_i ? en_rx_i & !wb_empty_o : en_tx_i & !wb_full_o;
|
||||
assign wbm_stb_o = en_rx_i ? wbm_cyc_o & fifo_rd_ack : wbm_cyc_o;
|
||||
|
||||
generic_fifo_dc_gray #(
|
||||
.dw(32),
|
||||
.aw(`FIFO_MEM_ADR_SIZE)
|
||||
) generic_fifo_dc_gray0 (
|
||||
.rd_clk(wb_clk),
|
||||
.wr_clk(sd_clk),
|
||||
.rst(!(rst | reset_fifo)),
|
||||
.clr(1'b0),
|
||||
.din(dat_i),
|
||||
.we(wr_i),
|
||||
.dout(wbm_dat_o),
|
||||
.re(en_rx_i & wbm_cyc_o & wbm_ack_i),
|
||||
.full(sd_full_o),
|
||||
.empty(wb_empty_o),
|
||||
.wr_level(),
|
||||
.rd_level()
|
||||
);
|
||||
|
||||
generic_fifo_dc_gray #(
|
||||
.dw(32),
|
||||
.aw(`FIFO_MEM_ADR_SIZE)
|
||||
) generic_fifo_dc_gray1 (
|
||||
.rd_clk(sd_clk),
|
||||
.wr_clk(wb_clk),
|
||||
.rst(!(rst | reset_fifo)),
|
||||
.clr(1'b0),
|
||||
.din(wbm_dat_i),
|
||||
.we(en_tx_i & wbm_cyc_o & wbm_stb_o & wbm_ack_i),
|
||||
.dout(dat_o),
|
||||
.re(rd_i),
|
||||
.full(wb_full_o),
|
||||
.empty(sd_empty_o),
|
||||
.wr_level(),
|
||||
.rd_level()
|
||||
);
|
||||
|
||||
assign wbm_adr_o = adr_i+offset;
|
||||
|
||||
always @(posedge wb_clk or posedge rst)
|
||||
if (rst) begin
|
||||
offset <= 0;
|
||||
fifo_rd_reg <= 0;
|
||||
fifo_rd_ack <= 1;
|
||||
end
|
||||
else begin
|
||||
fifo_rd_reg <= fifo_rd;
|
||||
fifo_rd_ack <= fifo_rd_reg | !fifo_rd;
|
||||
if (wbm_cyc_o & wbm_stb_o & wbm_ack_i)
|
||||
offset <= offset + `MEM_OFFSET;
|
||||
else if (reset_fifo)
|
||||
offset <= 0;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
@ -0,0 +1,411 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// WISHBONE SD Card Controller IP Core ////
|
||||
//// ////
|
||||
//// sdc_controller.v ////
|
||||
//// ////
|
||||
//// This file is part of the WISHBONE SD Card ////
|
||||
//// Controller IP Core project ////
|
||||
//// http://opencores.org/project,sd_card_controller ////
|
||||
//// ////
|
||||
//// Description ////
|
||||
//// Top level entity. ////
|
||||
//// This core is based on the "sd card controller" project from ////
|
||||
//// http://opencores.org/project,sdcard_mass_storage_controller ////
|
||||
//// but has been largely rewritten. A lot of effort has been ////
|
||||
//// made to make the core more generic and easily usable ////
|
||||
//// with OSs like Linux. ////
|
||||
//// - data transfer commands are not fixed ////
|
||||
//// - data transfer block size is configurable ////
|
||||
//// - multiple block transfer support ////
|
||||
//// - R2 responses (136 bit) support ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// - Marek Czerski, ma.czerski@gmail.com ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2013 Authors ////
|
||||
//// ////
|
||||
//// Based on original work by ////
|
||||
//// Adam Edvardsson (adam.edvardsson@orsoc.se) ////
|
||||
//// ////
|
||||
//// Copyright (C) 2009 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 "sd_defines.h"
|
||||
|
||||
module sdc_controller(
|
||||
// WISHBONE common
|
||||
wb_clk_i,
|
||||
wb_rst_i,
|
||||
// WISHBONE slave
|
||||
wb_dat_i,
|
||||
wb_dat_o,
|
||||
wb_adr_i,
|
||||
wb_sel_i,
|
||||
wb_we_i,
|
||||
wb_cyc_i,
|
||||
wb_stb_i,
|
||||
wb_ack_o,
|
||||
// WISHBONE master
|
||||
m_wb_dat_o,
|
||||
m_wb_dat_i,
|
||||
m_wb_adr_o,
|
||||
m_wb_sel_o,
|
||||
m_wb_we_o,
|
||||
m_wb_cyc_o,
|
||||
m_wb_stb_o,
|
||||
m_wb_ack_i,
|
||||
m_wb_cti_o,
|
||||
m_wb_bte_o,
|
||||
//SD BUS
|
||||
sd_cmd_dat_i,
|
||||
sd_cmd_out_o,
|
||||
sd_cmd_oe_o,
|
||||
//card_detect,
|
||||
sd_dat_dat_i,
|
||||
sd_dat_out_o,
|
||||
sd_dat_oe_o,
|
||||
sd_clk_o_pad,
|
||||
sd_clk_i_pad,
|
||||
int_cmd,
|
||||
int_data
|
||||
);
|
||||
|
||||
input wb_clk_i;
|
||||
input wb_rst_i;
|
||||
input [31:0] wb_dat_i;
|
||||
output [31:0] wb_dat_o;
|
||||
//input card_detect;
|
||||
input [7:0] wb_adr_i;
|
||||
input [3:0] wb_sel_i;
|
||||
input wb_we_i;
|
||||
input wb_cyc_i;
|
||||
input wb_stb_i;
|
||||
output wb_ack_o;
|
||||
output [31:0] m_wb_adr_o;
|
||||
output [3:0] m_wb_sel_o;
|
||||
output m_wb_we_o;
|
||||
input [31:0] m_wb_dat_i;
|
||||
output [31:0] m_wb_dat_o;
|
||||
output m_wb_cyc_o;
|
||||
output m_wb_stb_o;
|
||||
input m_wb_ack_i;
|
||||
output [2:0] m_wb_cti_o;
|
||||
output [1:0] m_wb_bte_o;
|
||||
input wire [3:0] sd_dat_dat_i;
|
||||
output wire [3:0] sd_dat_out_o;
|
||||
output wire sd_dat_oe_o;
|
||||
input wire sd_cmd_dat_i;
|
||||
output wire sd_cmd_out_o;
|
||||
output wire sd_cmd_oe_o;
|
||||
output sd_clk_o_pad;
|
||||
input wire sd_clk_i_pad;
|
||||
output int_cmd, int_data;
|
||||
|
||||
//SD clock
|
||||
wire sd_clk_o; //Sd_clk used in the system
|
||||
|
||||
wire go_idle;
|
||||
wire cmd_start_wb_clk;
|
||||
wire cmd_start_sd_clk;
|
||||
wire cmd_start;
|
||||
wire [1:0] cmd_setting;
|
||||
wire cmd_start_tx;
|
||||
wire [39:0] cmd;
|
||||
wire [119:0] cmd_response;
|
||||
wire cmd_crc_ok;
|
||||
wire cmd_index_ok;
|
||||
wire cmd_finish;
|
||||
|
||||
wire d_write;
|
||||
wire d_read;
|
||||
wire [31:0] data_in_rx_fifo;
|
||||
wire [31:0] data_out_tx_fifo;
|
||||
wire start_tx_fifo;
|
||||
wire start_rx_fifo;
|
||||
wire tx_fifo_empty;
|
||||
wire tx_fifo_full;
|
||||
wire rx_fifo_full;
|
||||
wire sd_data_busy;
|
||||
wire data_busy;
|
||||
wire data_crc_ok;
|
||||
wire rd_fifo;
|
||||
wire we_fifo;
|
||||
|
||||
wire data_start_rx;
|
||||
wire data_start_tx;
|
||||
wire cmd_int_rst_wb_clk;
|
||||
wire cmd_int_rst_sd_clk;
|
||||
wire cmd_int_rst;
|
||||
wire data_int_rst_wb_clk;
|
||||
wire data_int_rst_sd_clk;
|
||||
wire data_int_rst;
|
||||
|
||||
//wb accessible registers
|
||||
wire [31:0] argument_reg_wb_clk;
|
||||
wire [`CMD_REG_SIZE-1:0] command_reg_wb_clk;
|
||||
wire [15:0] timeout_reg_wb_clk;
|
||||
wire [0:0] software_reset_reg_wb_clk;
|
||||
wire [31:0] response_0_reg_wb_clk;
|
||||
wire [31:0] response_1_reg_wb_clk;
|
||||
wire [31:0] response_2_reg_wb_clk;
|
||||
wire [31:0] response_3_reg_wb_clk;
|
||||
wire [`BLKSIZE_W-1:0] block_size_reg_wb_clk;
|
||||
wire [15:0] controll_setting_reg_wb_clk;
|
||||
wire [`INT_CMD_SIZE-1:0] cmd_int_status_reg_wb_clk;
|
||||
wire [`INT_DATA_SIZE-1:0] data_int_status_reg_wb_clk;
|
||||
wire [`INT_CMD_SIZE-1:0] cmd_int_enable_reg_wb_clk;
|
||||
wire [`INT_DATA_SIZE-1:0] data_int_enable_reg_wb_clk;
|
||||
wire [`BLKCNT_W-1:0] block_count_reg_wb_clk;
|
||||
wire [31:0] dma_addr_reg_wb_clk;
|
||||
wire [7:0] clock_divider_reg_wb_clk;
|
||||
|
||||
wire [31:0] argument_reg_sd_clk;
|
||||
wire [`CMD_REG_SIZE-1:0] command_reg_sd_clk;
|
||||
wire [15:0] timeout_reg_sd_clk;
|
||||
wire [0:0] software_reset_reg_sd_clk;
|
||||
wire [31:0] response_0_reg_sd_clk;
|
||||
wire [31:0] response_1_reg_sd_clk;
|
||||
wire [31:0] response_2_reg_sd_clk;
|
||||
wire [31:0] response_3_reg_sd_clk;
|
||||
wire [`BLKSIZE_W-1:0] block_size_reg_sd_clk;
|
||||
wire [15:0] controll_setting_reg_sd_clk;
|
||||
wire [`INT_CMD_SIZE-1:0] cmd_int_status_reg_sd_clk;
|
||||
wire [2:0] data_int_status_reg_sd_clk;
|
||||
wire [`INT_CMD_SIZE-1:0] cmd_int_enable_reg_sd_clk;
|
||||
wire [2:0] data_int_enable_reg_sd_clk;
|
||||
wire [`BLKCNT_W-1:0] block_count_reg_sd_clk;
|
||||
wire [31:0] dma_addr_reg_sd_clk;
|
||||
wire [7:0] clock_divider_reg_sd_clk;
|
||||
|
||||
sd_clock_divider clock_divider0(
|
||||
.CLK (sd_clk_i_pad),
|
||||
.DIVIDER (clock_divider_reg_sd_clk),
|
||||
.RST (wb_rst_i),
|
||||
.SD_CLK (sd_clk_o)
|
||||
);
|
||||
|
||||
assign sd_clk_o_pad = sd_clk_o ;
|
||||
|
||||
sd_cmd_master sd_cmd_master0(
|
||||
.sd_clk (sd_clk_o),
|
||||
.rst (wb_rst_i | software_reset_reg_sd_clk[0]),
|
||||
.start_i (cmd_start_sd_clk),
|
||||
.int_status_rst_i(cmd_int_rst_sd_clk),
|
||||
.setting_o (cmd_setting),
|
||||
.start_xfr_o (cmd_start_tx),
|
||||
.go_idle_o (go_idle),
|
||||
.cmd_o (cmd),
|
||||
.response_i (cmd_response),
|
||||
.crc_ok_i (cmd_crc_ok),
|
||||
.index_ok_i (cmd_index_ok),
|
||||
.busy_i (sd_data_busy),
|
||||
.finish_i (cmd_finish),
|
||||
//input card_detect,
|
||||
.argument_i (argument_reg_sd_clk),
|
||||
.command_i (command_reg_sd_clk),
|
||||
.timeout_i (timeout_reg_sd_clk),
|
||||
.int_status_o (cmd_int_status_reg_sd_clk),
|
||||
.response_0_o (response_0_reg_sd_clk),
|
||||
.response_1_o (response_1_reg_sd_clk),
|
||||
.response_2_o (response_2_reg_sd_clk),
|
||||
.response_3_o (response_3_reg_sd_clk)
|
||||
);
|
||||
|
||||
sd_cmd_serial_host cmd_serial_host0(
|
||||
.sd_clk (sd_clk_o),
|
||||
.rst (wb_rst_i | software_reset_reg_sd_clk[0] | go_idle),
|
||||
.setting_i (cmd_setting),
|
||||
.cmd_i (cmd),
|
||||
.start_i (cmd_start_tx),
|
||||
.finish_o (cmd_finish),
|
||||
.response_o (cmd_response),
|
||||
.crc_ok_o (cmd_crc_ok),
|
||||
.index_ok_o (cmd_index_ok),
|
||||
.cmd_dat_i (sd_cmd_dat_i),
|
||||
.cmd_out_o (sd_cmd_out_o),
|
||||
.cmd_oe_o (sd_cmd_oe_o)
|
||||
);
|
||||
|
||||
sd_data_master sd_data_master0(
|
||||
.sd_clk (sd_clk_o),
|
||||
.rst (wb_rst_i | software_reset_reg_sd_clk[0]),
|
||||
.start_tx_i (data_start_tx),
|
||||
.start_rx_i (data_start_rx),
|
||||
.d_write_o (d_write),
|
||||
.d_read_o (d_read),
|
||||
.start_tx_fifo_o (start_tx_fifo),
|
||||
.start_rx_fifo_o (start_rx_fifo),
|
||||
.tx_fifo_empty_i (tx_fifo_empty),
|
||||
.tx_fifo_full_i (tx_fifo_full),
|
||||
.rx_fifo_full_i (rx_fifo_full),
|
||||
.xfr_complete_i (!data_busy),
|
||||
.crc_ok_i (data_crc_ok),
|
||||
.int_status_o (data_int_status_reg_sd_clk),
|
||||
.int_status_rst_i (data_int_rst_sd_clk)
|
||||
);
|
||||
|
||||
sd_data_serial_host sd_data_serial_host0(
|
||||
.sd_clk (sd_clk_o),
|
||||
.rst (wb_rst_i | software_reset_reg_sd_clk[0]),
|
||||
.data_in (data_out_tx_fifo),
|
||||
.rd (rd_fifo),
|
||||
.data_out (data_in_rx_fifo),
|
||||
.we (we_fifo),
|
||||
.DAT_oe_o (sd_dat_oe_o),
|
||||
.DAT_dat_o (sd_dat_out_o),
|
||||
.DAT_dat_i (sd_dat_dat_i),
|
||||
.blksize (block_size_reg_sd_clk),
|
||||
.bus_4bit (controll_setting_reg_sd_clk[0]),
|
||||
.blkcnt (block_count_reg_sd_clk),
|
||||
.start ({d_read, d_write}),
|
||||
.sd_data_busy (sd_data_busy),
|
||||
.busy (data_busy),
|
||||
.crc_ok (data_crc_ok)
|
||||
);
|
||||
|
||||
sd_fifo_filler sd_fifo_filler0(
|
||||
.wb_clk (wb_clk_i),
|
||||
.rst (wb_rst_i | software_reset_reg_sd_clk[0]),
|
||||
.wbm_adr_o (m_wb_adr_o),
|
||||
.wbm_we_o (m_wb_we_o),
|
||||
.wbm_dat_o (m_wb_dat_o),
|
||||
.wbm_dat_i (m_wb_dat_i),
|
||||
.wbm_cyc_o (m_wb_cyc_o),
|
||||
.wbm_stb_o (m_wb_stb_o),
|
||||
.wbm_ack_i (m_wb_ack_i),
|
||||
.en_rx_i (start_rx_fifo),
|
||||
.en_tx_i (start_tx_fifo),
|
||||
.adr_i (dma_addr_reg_sd_clk),
|
||||
.sd_clk (sd_clk_o),
|
||||
.dat_i (data_in_rx_fifo),
|
||||
.dat_o (data_out_tx_fifo),
|
||||
.wr_i (we_fifo),
|
||||
.rd_i (rd_fifo),
|
||||
.sd_empty_o (tx_fifo_empty),
|
||||
.sd_full_o (rx_fifo_full),
|
||||
.wb_empty_o (),
|
||||
.wb_full_o (tx_fifo_full)
|
||||
);
|
||||
|
||||
sd_data_xfer_trig sd_data_xfer_trig0 (
|
||||
.sd_clk (sd_clk_o),
|
||||
.rst (wb_rst_i | software_reset_reg_sd_clk[0]),
|
||||
.cmd_with_data_start_i (cmd_start_sd_clk & (command_reg_sd_clk[`CMD_WITH_DATA] != 2'b00)),
|
||||
.r_w_i (command_reg_sd_clk[`CMD_WITH_DATA] == 2'b01),
|
||||
.cmd_int_status_i (cmd_int_status_reg_sd_clk),
|
||||
.start_tx_o (data_start_tx),
|
||||
.start_rx_o (data_start_rx)
|
||||
);
|
||||
|
||||
sd_controller_wb sd_controller_wb0(
|
||||
.wb_clk_i (wb_clk_i),
|
||||
.wb_rst_i (wb_rst_i),
|
||||
.wb_dat_i (wb_dat_i),
|
||||
.wb_dat_o (wb_dat_o),
|
||||
.wb_adr_i (wb_adr_i),
|
||||
.wb_sel_i (wb_sel_i),
|
||||
.wb_we_i (wb_we_i),
|
||||
.wb_stb_i (wb_stb_i),
|
||||
.wb_cyc_i (wb_cyc_i),
|
||||
.wb_ack_o (wb_ack_o),
|
||||
.cmd_start (cmd_start),
|
||||
.data_int_rst (data_int_rst),
|
||||
.cmd_int_rst (cmd_int_rst),
|
||||
.argument_reg (argument_reg_wb_clk),
|
||||
.command_reg (command_reg_wb_clk),
|
||||
.response_0_reg (response_0_reg_wb_clk),
|
||||
.response_1_reg (response_1_reg_wb_clk),
|
||||
.response_2_reg (response_2_reg_wb_clk),
|
||||
.response_3_reg (response_3_reg_wb_clk),
|
||||
.software_reset_reg (software_reset_reg_wb_clk),
|
||||
.timeout_reg (timeout_reg_wb_clk),
|
||||
.block_size_reg (block_size_reg_wb_clk),
|
||||
.controll_setting_reg (controll_setting_reg_wb_clk),
|
||||
.cmd_int_status_reg (cmd_int_status_reg_wb_clk),
|
||||
.cmd_int_enable_reg (cmd_int_enable_reg_wb_clk),
|
||||
.clock_divider_reg (clock_divider_reg_wb_clk),
|
||||
.block_count_reg (block_count_reg_wb_clk),
|
||||
.dma_addr_reg (dma_addr_reg_wb_clk),
|
||||
.data_int_status_reg (data_int_status_reg_wb_clk),
|
||||
.data_int_enable_reg (data_int_enable_reg_wb_clk)
|
||||
);
|
||||
|
||||
//clock domain crossing regiters
|
||||
//assign cmd_start_sd_clk = cmd_start_wb_clk;
|
||||
//assign data_int_rst_sd_clk = data_int_rst_wb_clk;
|
||||
//assign cmd_int_rst_sd_clk = cmd_int_rst_wb_clk;
|
||||
//assign argument_reg_sd_clk = argument_reg_wb_clk;
|
||||
//assign command_reg_sd_clk = command_reg_wb_clk;
|
||||
//assign response_0_reg_wb_clk = response_0_reg_sd_clk;
|
||||
//assign response_1_reg_wb_clk = response_1_reg_sd_clk;
|
||||
//assign response_2_reg_wb_clk = response_2_reg_sd_clk;
|
||||
//assign response_3_reg_wb_clk = response_3_reg_sd_clk;
|
||||
//assign software_reset_reg_sd_clk = software_reset_reg_wb_clk;
|
||||
//assign timeout_reg_sd_clk = timeout_reg_wb_clk;
|
||||
//assign block_size_reg_sd_clk = block_size_reg_wb_clk;
|
||||
//assign controll_setting_reg_sd_clk = controll_setting_reg_wb_clk;
|
||||
//assign cmd_int_status_reg_wb_clk = cmd_int_status_reg_sd_clk;
|
||||
//assign cmd_int_enable_reg_sd_clk = cmd_int_enable_reg_wb_clk;
|
||||
//assign clock_divider_reg_sd_clk = clock_divider_reg_wb_clk;
|
||||
//assign block_count_reg_sd_clk = block_count_reg_wb_clk;
|
||||
//assign dma_addr_reg_sd_clk = dma_addr_reg_wb_clk;
|
||||
//assign data_int_status_reg_wb_clk = data_int_status_reg_sd_clk;
|
||||
//assign data_int_enable_reg_sd_clk = data_int_enable_reg_wb_clk;
|
||||
|
||||
edge_detect cmd_start_edge(.rst(wb_rst_i), .clk(wb_clk_i), .sig(cmd_start), .rise(cmd_start_wb_clk), .fall());
|
||||
edge_detect data_int_rst_edge(.rst(wb_rst_i), .clk(wb_clk_i), .sig(data_int_rst), .rise(data_int_rst_wb_clk), .fall());
|
||||
edge_detect cmd_int_rst_edge(.rst(wb_rst_i), .clk(wb_clk_i), .sig(cmd_int_rst), .rise(cmd_int_rst_wb_clk), .fall());
|
||||
monostable_domain_cross cmd_start_cross(wb_rst_i, wb_clk_i, cmd_start_wb_clk, sd_clk_o, cmd_start_sd_clk);
|
||||
monostable_domain_cross data_int_rst_cross(wb_rst_i, wb_clk_i, data_int_rst_wb_clk, sd_clk_o, data_int_rst_sd_clk);
|
||||
monostable_domain_cross cmd_int_rst_cross(wb_rst_i, wb_clk_i, cmd_int_rst_wb_clk, sd_clk_o, cmd_int_rst_sd_clk);
|
||||
bistable_domain_cross #(32) argument_reg_cross(wb_rst_i, wb_clk_i, argument_reg_wb_clk, sd_clk_o, argument_reg_sd_clk);
|
||||
bistable_domain_cross #(`CMD_REG_SIZE) command_reg_cross(wb_rst_i, wb_clk_i, command_reg_wb_clk, sd_clk_o, command_reg_sd_clk);
|
||||
bistable_domain_cross #(32) response_0_reg_cross(wb_rst_i, sd_clk_o, response_0_reg_sd_clk, wb_clk_i, response_0_reg_wb_clk);
|
||||
bistable_domain_cross #(32) response_1_reg_cross(wb_rst_i, sd_clk_o, response_1_reg_sd_clk, wb_clk_i, response_1_reg_wb_clk);
|
||||
bistable_domain_cross #(32) response_2_reg_cross(wb_rst_i, sd_clk_o, response_2_reg_sd_clk, wb_clk_i, response_2_reg_wb_clk);
|
||||
bistable_domain_cross #(32) response_3_reg_cross(wb_rst_i, sd_clk_o, response_3_reg_sd_clk, wb_clk_i, response_3_reg_wb_clk);
|
||||
bistable_domain_cross software_reset_reg_cross(wb_rst_i, wb_clk_i, software_reset_reg_wb_clk, sd_clk_o, software_reset_reg_sd_clk);
|
||||
bistable_domain_cross #(16) timeout_reg_cross(wb_rst_i, wb_clk_i, timeout_reg_wb_clk, sd_clk_o, timeout_reg_sd_clk);
|
||||
bistable_domain_cross #(`BLKSIZE_W) block_size_reg_cross(wb_rst_i, wb_clk_i, block_size_reg_wb_clk, sd_clk_o, block_size_reg_sd_clk);
|
||||
bistable_domain_cross #(16) controll_setting_reg_cross(wb_rst_i, wb_clk_i, controll_setting_reg_wb_clk, sd_clk_o, controll_setting_reg_sd_clk);
|
||||
bistable_domain_cross #(`INT_CMD_SIZE) cmd_int_status_reg_cross(wb_rst_i, sd_clk_o, cmd_int_status_reg_sd_clk, wb_clk_i, cmd_int_status_reg_wb_clk);
|
||||
bistable_domain_cross #(`INT_CMD_SIZE) cmd_int_enable_reg_cross(wb_rst_i, wb_clk_i, cmd_int_enable_reg_wb_clk, sd_clk_o, cmd_int_enable_reg_sd_clk);
|
||||
bistable_domain_cross #(8) clock_divider_reg_cross(wb_rst_i, wb_clk_i, clock_divider_reg_wb_clk, sd_clk_i_pad, clock_divider_reg_sd_clk);
|
||||
bistable_domain_cross #(`BLKCNT_W) block_count_reg_cross(wb_rst_i, wb_clk_i, block_count_reg_wb_clk, sd_clk_o, block_count_reg_sd_clk);
|
||||
bistable_domain_cross #(32) dma_addr_reg_cross(wb_rst_i, wb_clk_i, dma_addr_reg_wb_clk, sd_clk_o, dma_addr_reg_sd_clk);
|
||||
bistable_domain_cross #(`INT_DATA_SIZE) data_int_status_reg_cross(wb_rst_i, sd_clk_o, data_int_status_reg_sd_clk, wb_clk_i, data_int_status_reg_wb_clk);
|
||||
bistable_domain_cross #(`INT_DATA_SIZE) data_int_enable_reg_cross(wb_rst_i, wb_clk_i, data_int_enable_reg_wb_clk, sd_clk_o, data_int_enable_reg_sd_clk);
|
||||
|
||||
assign m_wb_cti_o = 3'b000;
|
||||
assign m_wb_bte_o = 2'b00;
|
||||
|
||||
assign int_cmd = |(cmd_int_status_reg_wb_clk & cmd_int_enable_reg_wb_clk);
|
||||
assign int_data = |(data_int_status_reg_wb_clk & data_int_enable_reg_wb_clk);
|
||||
|
||||
assign m_wb_sel_o = 4'b1111;
|
||||
|
||||
endmodule
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,594 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// SHA-160 ////
|
||||
//// Secure Hash Algorithm (SHA-160) ////
|
||||
//// ////
|
||||
//// Author: marsgod ////
|
||||
//// marsgod@opencores.org ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/sha_core/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2002-2004 marsgod ////
|
||||
//// marsgod@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 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. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
`define SHA1_H0 32'h67452301
|
||||
`define SHA1_H1 32'hefcdab89
|
||||
`define SHA1_H2 32'h98badcfe
|
||||
`define SHA1_H3 32'h10325476
|
||||
`define SHA1_H4 32'hc3d2e1f0
|
||||
|
||||
`define SHA1_K0 32'h5a827999
|
||||
`define SHA1_K1 32'h6ed9eba1
|
||||
`define SHA1_K2 32'h8f1bbcdc
|
||||
`define SHA1_K3 32'hca62c1d6
|
||||
|
||||
module sha1 (clk_i, rst_i, text_i, text_o, cmd_i, cmd_w_i, cmd_o);
|
||||
|
||||
input clk_i; // global clock input
|
||||
input rst_i; // global reset input , active high
|
||||
|
||||
input [31:0] text_i; // text input 32bit
|
||||
output [31:0] text_o; // text output 32bit
|
||||
|
||||
input [2:0] cmd_i; // command input
|
||||
input cmd_w_i;// command input write enable
|
||||
output [3:0] cmd_o; // command output(status)
|
||||
|
||||
/*
|
||||
cmd
|
||||
Busy Round W R
|
||||
|
||||
bit3 bit2 bit1 bit0
|
||||
Busy Round W R
|
||||
|
||||
Busy:
|
||||
0 idle
|
||||
1 busy
|
||||
|
||||
Round:
|
||||
0 first round
|
||||
1 internal round
|
||||
|
||||
W:
|
||||
0 No-op
|
||||
1 write data
|
||||
|
||||
R:
|
||||
0 No-op
|
||||
1 read data
|
||||
|
||||
*/
|
||||
|
||||
|
||||
reg [3:0] cmd;
|
||||
wire [3:0] cmd_o;
|
||||
|
||||
reg [31:0] text_o;
|
||||
|
||||
reg [6:0] round;
|
||||
wire [6:0] round_plus_1;
|
||||
|
||||
reg [2:0] read_counter;
|
||||
|
||||
reg [31:0] H0,H1,H2,H3,H4;
|
||||
reg [31:0] W0,W1,W2,W3,W4,W5,W6,W7,W8,W9,W10,W11,W12,W13,W14;
|
||||
reg [31:0] Wt,Kt;
|
||||
reg [31:0] A,B,C,D,E;
|
||||
|
||||
reg busy;
|
||||
|
||||
assign cmd_o = cmd;
|
||||
always @ (posedge clk_i)
|
||||
begin
|
||||
if (rst_i)
|
||||
cmd <= 'b0;
|
||||
else
|
||||
if (cmd_w_i)
|
||||
cmd[2:0] <= cmd_i[2:0]; // busy bit can't write
|
||||
else
|
||||
begin
|
||||
cmd[3] <= busy; // update busy bit
|
||||
if (~busy)
|
||||
cmd[1:0] <= 2'b00; // hardware auto clean R/W bits
|
||||
end
|
||||
end
|
||||
|
||||
// Hash functions
|
||||
wire [31:0] SHA1_f1_BCD,SHA1_f2_BCD,SHA1_f3_BCD,SHA1_Wt_1;
|
||||
wire [31:0] SHA1_ft_BCD;
|
||||
wire [31:0] next_Wt,next_A,next_C;
|
||||
wire [159:0] SHA1_result;
|
||||
|
||||
assign SHA1_f1_BCD = (B & C) ^ (~B & D);
|
||||
assign SHA1_f2_BCD = B ^ C ^ D;
|
||||
assign SHA1_f3_BCD = (B & C) ^ (C & D) ^ (B & D);
|
||||
|
||||
assign SHA1_ft_BCD = (round < 'd21) ? SHA1_f1_BCD : (round < 'd41) ? SHA1_f2_BCD : (round < 'd61) ? SHA1_f3_BCD : SHA1_f2_BCD;
|
||||
|
||||
assign SHA1_Wt_1 = {W13 ^ W8 ^ W2 ^ W0};
|
||||
|
||||
assign next_Wt = {SHA1_Wt_1[30:0],SHA1_Wt_1[31]}; // NSA fix added
|
||||
assign next_A = {A[26:0],A[31:27]} + SHA1_ft_BCD + E + Kt + Wt;
|
||||
assign next_C = {B[1:0],B[31:2]};
|
||||
|
||||
assign SHA1_result = {A,B,C,D,E};
|
||||
|
||||
assign round_plus_1 = round + 1;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// SHA round
|
||||
//------------------------------------------------------------------
|
||||
always @(posedge clk_i)
|
||||
begin
|
||||
if (rst_i)
|
||||
begin
|
||||
round <= 'd0;
|
||||
busy <= 'b0;
|
||||
|
||||
W0 <= 'b0;
|
||||
W1 <= 'b0;
|
||||
W2 <= 'b0;
|
||||
W3 <= 'b0;
|
||||
W4 <= 'b0;
|
||||
W5 <= 'b0;
|
||||
W6 <= 'b0;
|
||||
W7 <= 'b0;
|
||||
W8 <= 'b0;
|
||||
W9 <= 'b0;
|
||||
W10 <= 'b0;
|
||||
W11 <= 'b0;
|
||||
W12 <= 'b0;
|
||||
W13 <= 'b0;
|
||||
W14 <= 'b0;
|
||||
Wt <= 'b0;
|
||||
|
||||
A <= 'b0;
|
||||
B <= 'b0;
|
||||
C <= 'b0;
|
||||
D <= 'b0;
|
||||
E <= 'b0;
|
||||
|
||||
H0 <= 'b0;
|
||||
H1 <= 'b0;
|
||||
H2 <= 'b0;
|
||||
H3 <= 'b0;
|
||||
H4 <= 'b0;
|
||||
|
||||
end
|
||||
else
|
||||
begin
|
||||
case (round)
|
||||
|
||||
'd0:
|
||||
begin
|
||||
if (cmd[1])
|
||||
begin
|
||||
W0 <= text_i;
|
||||
Wt <= text_i;
|
||||
busy <= 'b1;
|
||||
round <= round_plus_1;
|
||||
|
||||
case (cmd[2])
|
||||
1'b0: // sha-1 first message
|
||||
begin
|
||||
A <= `SHA1_H0;
|
||||
B <= `SHA1_H1;
|
||||
C <= `SHA1_H2;
|
||||
D <= `SHA1_H3;
|
||||
E <= `SHA1_H4;
|
||||
|
||||
H0 <= `SHA1_H0;
|
||||
H1 <= `SHA1_H1;
|
||||
H2 <= `SHA1_H2;
|
||||
H3 <= `SHA1_H3;
|
||||
H4 <= `SHA1_H4;
|
||||
end
|
||||
1'b1: // sha-1 internal message
|
||||
begin
|
||||
H0 <= A;
|
||||
H1 <= B;
|
||||
H2 <= C;
|
||||
H3 <= D;
|
||||
H4 <= E;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
else
|
||||
begin // IDLE
|
||||
round <= 'd0;
|
||||
end
|
||||
end
|
||||
'd1:
|
||||
begin
|
||||
W1 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
E <= D;
|
||||
D <= C;
|
||||
C <= next_C;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd2:
|
||||
begin
|
||||
W2 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
E <= D;
|
||||
D <= C;
|
||||
C <= next_C;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd3:
|
||||
begin
|
||||
W3 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
E <= D;
|
||||
D <= C;
|
||||
C <= next_C;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd4:
|
||||
begin
|
||||
W4 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
E <= D;
|
||||
D <= C;
|
||||
C <= next_C;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd5:
|
||||
begin
|
||||
W5 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
E <= D;
|
||||
D <= C;
|
||||
C <= next_C;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd6:
|
||||
begin
|
||||
W6 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
E <= D;
|
||||
D <= C;
|
||||
C <= next_C;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd7:
|
||||
begin
|
||||
W7 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
E <= D;
|
||||
D <= C;
|
||||
C <= next_C;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd8:
|
||||
begin
|
||||
W8 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
E <= D;
|
||||
D <= C;
|
||||
C <= next_C;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd9:
|
||||
begin
|
||||
W9 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
E <= D;
|
||||
D <= C;
|
||||
C <= next_C;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd10:
|
||||
begin
|
||||
W10 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
E <= D;
|
||||
D <= C;
|
||||
C <= next_C;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd11:
|
||||
begin
|
||||
W11 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
E <= D;
|
||||
D <= C;
|
||||
C <= next_C;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd12:
|
||||
begin
|
||||
W12 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
E <= D;
|
||||
D <= C;
|
||||
C <= next_C;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd13:
|
||||
begin
|
||||
W13 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
E <= D;
|
||||
D <= C;
|
||||
C <= next_C;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd14:
|
||||
begin
|
||||
W14 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
E <= D;
|
||||
D <= C;
|
||||
C <= next_C;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd15:
|
||||
begin
|
||||
Wt <= text_i;
|
||||
|
||||
E <= D;
|
||||
D <= C;
|
||||
C <= next_C;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd16,
|
||||
'd17,
|
||||
'd18,
|
||||
'd19,
|
||||
'd20,
|
||||
'd21,
|
||||
'd22,
|
||||
'd23,
|
||||
'd24,
|
||||
'd25,
|
||||
'd26,
|
||||
'd27,
|
||||
'd28,
|
||||
'd29,
|
||||
'd30,
|
||||
'd31,
|
||||
'd32,
|
||||
'd33,
|
||||
'd34,
|
||||
'd35,
|
||||
'd36,
|
||||
'd37,
|
||||
'd38,
|
||||
'd39,
|
||||
'd40,
|
||||
'd41,
|
||||
'd42,
|
||||
'd43,
|
||||
'd44,
|
||||
'd45,
|
||||
'd46,
|
||||
'd47,
|
||||
'd48,
|
||||
'd49,
|
||||
'd50,
|
||||
'd51,
|
||||
'd52,
|
||||
'd53,
|
||||
'd54,
|
||||
'd55,
|
||||
'd56,
|
||||
'd57,
|
||||
'd58,
|
||||
'd59,
|
||||
'd60,
|
||||
'd61,
|
||||
'd62,
|
||||
'd63,
|
||||
'd64,
|
||||
'd65,
|
||||
'd66,
|
||||
'd67,
|
||||
'd68,
|
||||
'd69,
|
||||
'd70,
|
||||
'd71,
|
||||
'd72,
|
||||
'd73,
|
||||
'd74,
|
||||
'd75,
|
||||
'd76,
|
||||
'd77,
|
||||
'd78,
|
||||
'd79:
|
||||
begin
|
||||
W0 <= W1;
|
||||
W1 <= W2;
|
||||
W2 <= W3;
|
||||
W3 <= W4;
|
||||
W4 <= W5;
|
||||
W5 <= W6;
|
||||
W6 <= W7;
|
||||
W7 <= W8;
|
||||
W8 <= W9;
|
||||
W9 <= W10;
|
||||
W10 <= W11;
|
||||
W11 <= W12;
|
||||
W12 <= W13;
|
||||
W13 <= W14;
|
||||
W14 <= Wt;
|
||||
Wt <= next_Wt;
|
||||
|
||||
E <= D;
|
||||
D <= C;
|
||||
C <= next_C;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd80:
|
||||
begin
|
||||
A <= next_A + H0;
|
||||
B <= A + H1;
|
||||
C <= next_C + H2;
|
||||
D <= C + H3;
|
||||
E <= D + H4;
|
||||
round <= 'd0;
|
||||
busy <= 'b0;
|
||||
end
|
||||
default:
|
||||
begin
|
||||
round <= 'd0;
|
||||
busy <= 'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Kt generator
|
||||
//------------------------------------------------------------------
|
||||
always @ (posedge clk_i)
|
||||
begin
|
||||
if (rst_i)
|
||||
begin
|
||||
Kt <= 'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (round < 'd20)
|
||||
Kt <= `SHA1_K0;
|
||||
else
|
||||
if (round < 'd40)
|
||||
Kt <= `SHA1_K1;
|
||||
else
|
||||
if (round < 'd60)
|
||||
Kt <= `SHA1_K2;
|
||||
else
|
||||
Kt <= `SHA1_K3;
|
||||
end
|
||||
end
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// read result
|
||||
//------------------------------------------------------------------
|
||||
always @ (posedge clk_i)
|
||||
begin
|
||||
if (rst_i)
|
||||
begin
|
||||
text_o <= 'b0;
|
||||
read_counter <= 'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (cmd[0])
|
||||
begin
|
||||
read_counter <= 'd4; // sha-1 160/32=5
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (~busy)
|
||||
begin
|
||||
case (read_counter)
|
||||
'd4: text_o <= SHA1_result[5*32-1:4*32];
|
||||
'd3: text_o <= SHA1_result[4*32-1:3*32];
|
||||
'd2: text_o <= SHA1_result[3*32-1:2*32];
|
||||
'd1: text_o <= SHA1_result[2*32-1:1*32];
|
||||
'd0: text_o <= SHA1_result[1*32-1:0*32];
|
||||
default:text_o <= 'b0;
|
||||
endcase
|
||||
if (|read_counter)
|
||||
read_counter <= read_counter - 'd1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
text_o <= 'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
@ -0,0 +1,774 @@
|
|||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// SHA-256 ////
|
||||
//// Secure Hash Algorithm (SHA-256) ////
|
||||
//// ////
|
||||
//// Author: marsgod ////
|
||||
//// marsgod@opencores.org ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// Downloaded from: http://www.opencores.org/cores/sha_core/ ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000-2002 marsgod ////
|
||||
//// marsgod@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 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. ////
|
||||
//// ////
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
`define SHA256_H0 32'h6a09e667
|
||||
`define SHA256_H1 32'hbb67ae85
|
||||
`define SHA256_H2 32'h00000000
|
||||
`define SHA256_H3 32'ha54ff53a
|
||||
`define SHA256_H4 32'h510e527f
|
||||
`define SHA256_H5 32'h00000000
|
||||
`define SHA256_H6 32'h1f83d9ab
|
||||
`define SHA256_H7 32'h00000000
|
||||
|
||||
`define K00 32'h00000000
|
||||
`define K01 32'h71374491
|
||||
`define K02 32'hb5c0fbcf
|
||||
`define K03 32'he9b5dba5
|
||||
`define K04 32'h3956c25b
|
||||
`define K05 32'h59f111f1
|
||||
`define K06 32'h923f82a4
|
||||
`define K07 32'hab1c5ed5
|
||||
`define K08 32'hd807aa98
|
||||
`define K09 32'h12835b01
|
||||
`define K10 32'h243185be
|
||||
`define K11 32'h00000000
|
||||
`define K12 32'h72be5d74
|
||||
`define K13 32'h80deb1fe
|
||||
`define K14 32'h9bdc06a7
|
||||
`define K15 32'hc19bf174
|
||||
`define K16 32'h00000000
|
||||
`define K17 32'hefbe4786
|
||||
`define K18 32'h0fc19dc6
|
||||
`define K19 32'h240ca1cc
|
||||
`define K20 32'h2de92c6f
|
||||
`define K21 32'h00000000
|
||||
`define K22 32'h5cb0a9dc
|
||||
`define K23 32'h5cb0a9dc //
|
||||
`define K24 32'h983e5152
|
||||
`define K25 32'ha831c66d
|
||||
`define K26 32'hb00327c8
|
||||
`define K27 32'hbf597fc7
|
||||
`define K28 32'hc6e00bf3
|
||||
`define K29 32'hd5a79147
|
||||
`define K30 32'h06ca6351
|
||||
`define K31 32'h14292967
|
||||
`define K32 32'h27b70a85
|
||||
`define K33 32'h2e1b2138
|
||||
`define K34 32'h4d2c6dfc
|
||||
`define K35 32'h53380d13
|
||||
`define K36 32'h650a7354
|
||||
`define K37 32'h766a0abb
|
||||
`define K38 32'h81c2c92e
|
||||
`define K39 32'h92722c85
|
||||
`define K40 32'ha2bfe8a1
|
||||
`define K41 32'ha81a664b
|
||||
`define K42 32'hc24b8b70
|
||||
`define K43 32'hc76c51a3
|
||||
`define K44 32'hd192e819
|
||||
`define K45 32'hd6990624
|
||||
`define K46 32'hf40e3585
|
||||
`define K47 32'h106aa070
|
||||
`define K48 32'h19a4c116
|
||||
`define K49 32'h1e376c08
|
||||
`define K50 32'h2748774c
|
||||
`define K51 32'h34b0bcb5
|
||||
`define K52 32'h391c0cb3
|
||||
`define K53 32'h4ed8aa4a
|
||||
`define K54 32'h5b9cca4f
|
||||
`define K55 32'h682e6ff3
|
||||
`define K56 32'h748f82ee
|
||||
`define K57 32'h78a5636f
|
||||
`define K58 32'h84c87814
|
||||
`define K59 32'h8cc70208
|
||||
`define K60 32'h90befffa
|
||||
`define K61 32'ha4506ceb
|
||||
`define K62 32'hbef9a3f7
|
||||
`define K63 32'hc67178f2
|
||||
|
||||
module sha256 (clk_i, rst_i, text_i, text_o, cmd_i, cmd_w_i, cmd_o);
|
||||
|
||||
input clk_i; // global clock input
|
||||
input rst_i; // global reset input , active high
|
||||
|
||||
input [9:0] text_i; // text input 32bit
|
||||
output [9:0] text_o; // text output 32bit
|
||||
|
||||
input [2:0] cmd_i; // command input
|
||||
input cmd_w_i;// command input write enable
|
||||
output [3:0] cmd_o; // command output(status)
|
||||
|
||||
/*
|
||||
cmd
|
||||
Busy Round W R
|
||||
|
||||
bit3 bit2 bit1 bit0
|
||||
Busy Round W R
|
||||
|
||||
Busy:
|
||||
0 idle
|
||||
1 busy
|
||||
|
||||
Round:
|
||||
0 first round
|
||||
1 internal round
|
||||
|
||||
W:
|
||||
0 No-op
|
||||
1 write data
|
||||
|
||||
R:
|
||||
0 No-op
|
||||
1 read data
|
||||
|
||||
*/
|
||||
|
||||
|
||||
reg [3:0] cmd;
|
||||
wire [3:0] cmd_o;
|
||||
|
||||
reg [9:0] text_o;
|
||||
|
||||
reg [6:0] round;
|
||||
wire [6:0] round_plus_1;
|
||||
|
||||
reg [2:0] read_counter;
|
||||
|
||||
reg [31:0] H0,H1,H2,H3,H4,H5,H6,H7;
|
||||
reg [31:0] W0,W1,W2,W3,W4,W5,W6,W7,W8,W9,W10,W11,W12,W13,W14;
|
||||
reg [31:0] Wt,Kt;
|
||||
reg [31:0] A,B,C,D,E,F,G,H;
|
||||
|
||||
reg busy;
|
||||
|
||||
assign cmd_o = cmd;
|
||||
always @ (posedge clk_i)
|
||||
begin
|
||||
if (rst_i)
|
||||
cmd <= 'b0;
|
||||
else
|
||||
if (cmd_w_i)
|
||||
cmd[2:0] <= cmd_i[2:0]; // busy bit can't write
|
||||
else
|
||||
begin
|
||||
cmd[3] <= busy; // update busy bit
|
||||
if (~busy)
|
||||
cmd[1:0] <= 2'b00; // hardware auto clean R/W bits
|
||||
end
|
||||
end
|
||||
|
||||
wire [31:0] f1_EFG_32,f2_ABC_32,f3_A_32,f4_E_32,f5_W1_32,f6_W14_32,T1_32,T2_32;
|
||||
wire [31:0] next_Wt,next_E,next_A;
|
||||
wire [255:0] SHA256_result;
|
||||
|
||||
assign f1_EFG_32 = (E & F);
|
||||
|
||||
assign f2_ABC_32 = (A & B);
|
||||
|
||||
assign f3_A_32 = {A[1:0],A[31:2]} ^ {A[12:0],A[31:13]} ^ {A[21:0],A[31:22]};
|
||||
|
||||
assign f4_E_32 = {E[5:0],E[31:6]} ^ {E[10:0],E[31:11]} ^ {E[24:0],E[31:25]};
|
||||
|
||||
assign f5_W1_32 = 0;// {W1[6:0],W1[31:7]} ^ {W1[17:0],W1[31:18]} ^ {3'b000,W1[31:3]};
|
||||
|
||||
assign f6_W14_32 = 0; //{W14[16:0],W14[31:17]} ^ {10'b00_0000_0000,W14[31:10]};
|
||||
|
||||
|
||||
assign T1_32 = f4_E_32 + f1_EFG_32 + Kt + Wt;
|
||||
|
||||
assign T2_32 = f3_A_32 + f2_ABC_32;
|
||||
|
||||
assign next_Wt = f6_W14_32 + f5_W1_32;
|
||||
assign next_E = D[31:0] + T1_32;
|
||||
assign next_A = T1_32 + T2_32;
|
||||
|
||||
|
||||
assign SHA256_result = {A,B,C,D,E,F,G,H};
|
||||
|
||||
assign round_plus_1 = round + 1;
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// SHA round
|
||||
//------------------------------------------------------------------
|
||||
always @(posedge clk_i)
|
||||
begin
|
||||
if (rst_i)
|
||||
begin
|
||||
round <= 'd0;
|
||||
busy <= 'b0;
|
||||
|
||||
W0 <= 'b0;
|
||||
W1 <= 'b0;
|
||||
W2 <= 'b0;
|
||||
W3 <= 'b0;
|
||||
W4 <= 'b0;
|
||||
W5 <= 'b0;
|
||||
W6 <= 'b0;
|
||||
W7 <= 'b0;
|
||||
W8 <= 'b0;
|
||||
W9 <= 'b0;
|
||||
W10 <= 'b0;
|
||||
W11 <= 'b0;
|
||||
W12 <= 'b0;
|
||||
W13 <= 'b0;
|
||||
W14 <= 'b0;
|
||||
Wt <= 'b0;
|
||||
|
||||
A <= 'b0;
|
||||
B <= 'b0;
|
||||
C <= 'b0;
|
||||
D <= 'b0;
|
||||
E <= 'b0;
|
||||
F <= 'b0;
|
||||
G <= 'b0;
|
||||
H <= 'b0;
|
||||
|
||||
H0 <= 'b0;
|
||||
H1 <= 'b0;
|
||||
H2 <= 'b0;
|
||||
H3 <= 'b0;
|
||||
H4 <= 'b0;
|
||||
H5 <= 'b0;
|
||||
H6 <= 'b0;
|
||||
H7 <= 'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
case (round)
|
||||
|
||||
'd0:
|
||||
begin
|
||||
if (cmd[1])
|
||||
begin
|
||||
W0 <= text_i;
|
||||
Wt <= text_i;
|
||||
busy <= 'b1;
|
||||
round <= round_plus_1;
|
||||
|
||||
case (cmd[2])
|
||||
1'b0: // sha-256 first message
|
||||
begin
|
||||
A <= `SHA256_H0;
|
||||
B <= `SHA256_H1;
|
||||
C <= `SHA256_H2;
|
||||
D <= `SHA256_H3;
|
||||
E <= `SHA256_H4;
|
||||
F <= `SHA256_H5;
|
||||
G <= `SHA256_H6;
|
||||
H <= `SHA256_H7;
|
||||
|
||||
H0 <= `SHA256_H0;
|
||||
H1 <= `SHA256_H1;
|
||||
H2 <= `SHA256_H2;
|
||||
H3 <= `SHA256_H3;
|
||||
H4 <= `SHA256_H4;
|
||||
H5 <= `SHA256_H5;
|
||||
H6 <= `SHA256_H6;
|
||||
H7 <= `SHA256_H7;
|
||||
end
|
||||
1'b1: // sha-256 internal message
|
||||
begin
|
||||
H0 <= A;
|
||||
H1 <= B;
|
||||
H2 <= C;
|
||||
H3 <= D;
|
||||
H4 <= E;
|
||||
H5 <= F;
|
||||
H6 <= G;
|
||||
H7 <= H;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
else
|
||||
begin // IDLE
|
||||
round <= 'd0;
|
||||
end
|
||||
end
|
||||
'd1:
|
||||
begin
|
||||
W1 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
H <= G;
|
||||
G <= F;
|
||||
F <= E;
|
||||
E <= next_E;
|
||||
D <= C;
|
||||
C <= B;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd2:
|
||||
begin
|
||||
W2 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
H <= G;
|
||||
G <= F;
|
||||
F <= E;
|
||||
E <= next_E;
|
||||
D <= C;
|
||||
C <= B;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd3:
|
||||
begin
|
||||
W3 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
H <= G;
|
||||
G <= F;
|
||||
F <= E;
|
||||
E <= next_E;
|
||||
D <= C;
|
||||
C <= B;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd4:
|
||||
begin
|
||||
W4 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
H <= G;
|
||||
G <= F;
|
||||
F <= E;
|
||||
E <= next_E;
|
||||
D <= C;
|
||||
C <= B;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd5:
|
||||
begin
|
||||
W5 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
H <= G;
|
||||
G <= F;
|
||||
F <= E;
|
||||
E <= next_E;
|
||||
D <= C;
|
||||
C <= B;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd6:
|
||||
begin
|
||||
W6 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
H <= G;
|
||||
G <= F;
|
||||
F <= E;
|
||||
E <= next_E;
|
||||
D <= C;
|
||||
C <= B;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd7:
|
||||
begin
|
||||
W7 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
H <= G;
|
||||
G <= F;
|
||||
F <= E;
|
||||
E <= next_E;
|
||||
D <= C;
|
||||
C <= B;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd8:
|
||||
begin
|
||||
W8 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
H <= G;
|
||||
G <= F;
|
||||
F <= E;
|
||||
E <= next_E;
|
||||
D <= C;
|
||||
C <= B;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd9:
|
||||
begin
|
||||
W9 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
H <= G;
|
||||
G <= F;
|
||||
F <= E;
|
||||
E <= next_E;
|
||||
D <= C;
|
||||
C <= B;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd10:
|
||||
begin
|
||||
W10 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
H <= G;
|
||||
G <= F;
|
||||
F <= E;
|
||||
E <= next_E;
|
||||
D <= C;
|
||||
C <= B;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd11:
|
||||
begin
|
||||
W11 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
H <= G;
|
||||
G <= F;
|
||||
F <= E;
|
||||
E <= next_E;
|
||||
D <= C;
|
||||
C <= B;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd12:
|
||||
begin
|
||||
W12 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
H <= G;
|
||||
G <= F;
|
||||
F <= E;
|
||||
E <= next_E;
|
||||
D <= C;
|
||||
C <= B;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd13:
|
||||
begin
|
||||
W13 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
H <= G;
|
||||
G <= F;
|
||||
F <= E;
|
||||
E <= next_E;
|
||||
D <= C;
|
||||
C <= B;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd14:
|
||||
begin
|
||||
W14 <= text_i;
|
||||
Wt <= text_i;
|
||||
|
||||
H <= G;
|
||||
G <= F;
|
||||
F <= E;
|
||||
E <= next_E;
|
||||
D <= C;
|
||||
C <= B;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd15:
|
||||
begin
|
||||
Wt <= text_i;
|
||||
|
||||
H <= G;
|
||||
G <= F;
|
||||
F <= E;
|
||||
E <= next_E;
|
||||
D <= C;
|
||||
C <= B;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd16,
|
||||
'd17,
|
||||
'd18,
|
||||
'd19,
|
||||
'd20,
|
||||
'd21,
|
||||
'd22,
|
||||
'd23,
|
||||
'd24,
|
||||
'd25,
|
||||
'd26,
|
||||
'd27,
|
||||
'd28,
|
||||
'd29,
|
||||
'd30,
|
||||
'd31,
|
||||
'd32,
|
||||
'd33,
|
||||
'd34,
|
||||
'd35,
|
||||
'd36,
|
||||
'd37,
|
||||
'd38,
|
||||
'd39,
|
||||
'd40,
|
||||
'd41,
|
||||
'd42,
|
||||
'd43,
|
||||
'd44,
|
||||
'd45,
|
||||
'd46,
|
||||
'd47,
|
||||
'd48,
|
||||
'd49,
|
||||
'd50,
|
||||
'd51,
|
||||
'd52,
|
||||
'd53,
|
||||
'd54,
|
||||
'd55,
|
||||
'd56,
|
||||
'd57,
|
||||
'd58,
|
||||
'd59,
|
||||
'd60,
|
||||
'd61,
|
||||
'd62,
|
||||
'd63:
|
||||
begin
|
||||
W0 <= W1;
|
||||
W1 <= W2;
|
||||
W2 <= W3;
|
||||
W3 <= W4;
|
||||
W4 <= W5;
|
||||
W5 <= W6;
|
||||
W6 <= W7;
|
||||
W7 <= W8;
|
||||
W8 <= W9;
|
||||
W9 <= W10;
|
||||
W10 <= W11;
|
||||
W11 <= W12;
|
||||
W12 <= W13;
|
||||
W13 <= W14;
|
||||
W14 <= Wt;
|
||||
Wt <= next_Wt;
|
||||
|
||||
H <= G;
|
||||
G <= F;
|
||||
F <= E;
|
||||
E <= next_E;
|
||||
D <= C;
|
||||
C <= B;
|
||||
B <= A;
|
||||
A <= next_A;
|
||||
|
||||
round <= round_plus_1;
|
||||
end
|
||||
'd64:
|
||||
begin
|
||||
A <= next_A + H0;
|
||||
B <= A + H1;
|
||||
C <= B + H2;
|
||||
D <= C + H3;
|
||||
E <= next_E + H4;
|
||||
F <= E + H5;
|
||||
G <= F + H6;
|
||||
H <= G + H7;
|
||||
round <= 'd0;
|
||||
busy <= 'b0;
|
||||
end
|
||||
default:
|
||||
begin
|
||||
round <= 'd0;
|
||||
busy <= 'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Kt generator
|
||||
//------------------------------------------------------------------
|
||||
always @ (posedge clk_i)
|
||||
begin
|
||||
if (rst_i)
|
||||
begin
|
||||
Kt <= 'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
case (round)
|
||||
'd00: Kt <= `K00;
|
||||
'd01: Kt <= `K01;
|
||||
'd02: Kt <= `K02;
|
||||
'd03: Kt <= `K03;
|
||||
'd04: Kt <= `K04;
|
||||
'd05: Kt <= `K05;
|
||||
'd06: Kt <= `K06;
|
||||
'd07: Kt <= `K07;
|
||||
'd08: Kt <= `K08;
|
||||
'd09: Kt <= `K09;
|
||||
'd10: Kt <= `K10;
|
||||
'd11: Kt <= `K11;
|
||||
'd12: Kt <= `K12;
|
||||
'd13: Kt <= `K13;
|
||||
'd14: Kt <= `K14;
|
||||
'd15: Kt <= `K15;
|
||||
'd16: Kt <= `K16;
|
||||
'd17: Kt <= `K17;
|
||||
'd18: Kt <= `K18;
|
||||
'd19: Kt <= `K19;
|
||||
'd20: Kt <= `K20;
|
||||
'd21: Kt <= `K21;
|
||||
'd22: Kt <= `K22;
|
||||
'd23: Kt <= `K23;
|
||||
'd24: Kt <= `K24;
|
||||
'd25: Kt <= `K25;
|
||||
'd26: Kt <= `K26;
|
||||
'd27: Kt <= `K27;
|
||||
'd28: Kt <= `K28;
|
||||
'd29: Kt <= `K29;
|
||||
'd30: Kt <= `K30;
|
||||
'd31: Kt <= `K31;
|
||||
'd32: Kt <= `K32;
|
||||
'd33: Kt <= `K33;
|
||||
'd34: Kt <= `K34;
|
||||
'd35: Kt <= `K35;
|
||||
'd36: Kt <= `K36;
|
||||
'd37: Kt <= `K37;
|
||||
'd38: Kt <= `K38;
|
||||
'd39: Kt <= `K39;
|
||||
'd40: Kt <= `K40;
|
||||
'd41: Kt <= `K41;
|
||||
'd42: Kt <= `K42;
|
||||
'd43: Kt <= `K43;
|
||||
'd44: Kt <= `K44;
|
||||
'd45: Kt <= `K45;
|
||||
'd46: Kt <= `K46;
|
||||
'd47: Kt <= `K47;
|
||||
'd48: Kt <= `K48;
|
||||
'd49: Kt <= `K49;
|
||||
'd50: Kt <= `K50;
|
||||
'd51: Kt <= `K51;
|
||||
'd52: Kt <= `K52;
|
||||
'd53: Kt <= `K53;
|
||||
'd54: Kt <= `K54;
|
||||
'd55: Kt <= `K55;
|
||||
'd56: Kt <= `K56;
|
||||
'd57: Kt <= `K57;
|
||||
'd58: Kt <= `K58;
|
||||
'd59: Kt <= `K59;
|
||||
'd60: Kt <= `K60;
|
||||
'd61: Kt <= `K61;
|
||||
'd62: Kt <= `K62;
|
||||
'd63: Kt <= `K63;
|
||||
default:Kt <= 'd0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// read result
|
||||
//------------------------------------------------------------------
|
||||
always @ (posedge clk_i)
|
||||
begin
|
||||
if (rst_i)
|
||||
begin
|
||||
text_o <= 'b0;
|
||||
read_counter <= 'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (cmd[0])
|
||||
begin
|
||||
read_counter <= 'd7; // sha-256 256/32=8
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (~busy)
|
||||
begin
|
||||
case (read_counter)
|
||||
'd7: text_o <= SHA256_result[8*32-1:7*32];
|
||||
'd6: text_o <= SHA256_result[7*32-1:6*32];
|
||||
'd5: text_o <= SHA256_result[6*32-1:5*32];
|
||||
'd4: text_o <= SHA256_result[5*32-1:4*32];
|
||||
'd3: text_o <= SHA256_result[4*32-1:3*32];
|
||||
'd2: text_o <= SHA256_result[3*32-1:2*32];
|
||||
'd1: text_o <= SHA256_result[2*32-1:1*32];
|
||||
'd0: text_o <= SHA256_result[1*32-1:0*32];
|
||||
default:text_o <= 'b0;
|
||||
endcase
|
||||
if (|read_counter)
|
||||
read_counter <= read_counter - 'd1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
text_o <= 'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,10 @@
|
|||
module unsigned_mult_80 (out, a, b);
|
||||
output [40:0] out;
|
||||
wire [80:0] mult_wire;
|
||||
input [40:0] a;
|
||||
input [40:0] b;
|
||||
|
||||
assign mult_wire = a * b;
|
||||
assign out = mult_wire[80:40] | mult_wire[39:0];
|
||||
|
||||
endmodule
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue