`include "main_mem.v"
`include "mmx_mem.v"
 
module top;
 
`define HIGH_COEF 6'b001001 // Size of both the Coef and data
`define ZERO 6'b000000
`define NO_OPERATION 18'b000000000000000000
 
// Macros for the instructions
`define PADDD 3'b110
`define PACKSSDW 3'b001
`define PSRAD 3'b010
`define PMADDWD 3'b011
`define PXOR 3'b100
`define MOVQ 3'b101
`define NOP 3'b000
`define MOVD 3'b111
 
// Define the MMX registers for source and dest
`define MMX0 6'b000000
`define MMX1 6'b000001
`define MMX2 6'b000010
`define MMX3 6'b000011
`define MMX4 6'b000100
`define MMX5 6'b000101
`define MMX6 6'b000110
`define MMX7 6'b000111
 
// Define the modes for the instructions
 
`define MMX2MMX 3'b001
`define MEM2MMX 3'b010
`define MMX2MEM 3'b011
`define MEM2MEM 3'b100
 
 
// Define various addresses
 
`define DATAADDR 6'd25
`define NUMBERSHIFT 6'd41
// This is the address of numbershift not the value see array
`define NUMBERSHIFT2 6'd42
`define SAMPLE 6'd43
`define COEFADDR 6'd00
`define TEMPADDR 6'd12
`define OUTPUT 6'd45
 
 
reg [17:0] instruction;
reg clk,reset;
 
reg [5:0] L,i;
 
wire [2:0] mmx_addr;
wire [63:0] mmx_data;
wire mmx_we;
 
wire [5:0] mem_addr;
wire [63:0] mem_data;
wire mem_we;
 
mmx mmx(.instruction(instruction),
.clk(clk),
.reset(reset),
.mem_addr(mem_addr),
.mem_data(mem_data),
.mem_we(mem_we),
.mmx_addr(mmx_addr),
.mmx_data(mmx_data),
.mmx_we(mmx_we) );
main_mem mem (.addr(mem_addr),
.data_wire(mem_data),
.clk(clk),
.we(mem_we));
mmx_mem mmx1(.addr(mmx_addr),
.data_wire(mmx_data),
.clk(clk),
.reset(reset),
.we(mmx_we));
initial
begin
clk = 1'b0;
forever begin
#5 clk = ~clk;
end
end
 
initial
begin
reset = 1'b1;
#17 reset = 1'b0;
end
 
initial
begin
L = 6'b0;
@(posedge clk)
instruction = `NO_OPERATION;
repeat (7) @(posedge clk);
while(L < 10) begin
@(posedge clk)
instruction = {`MOVQ,`MEM2MEM,`DATAADDR,`SAMPLE};
repeat (6) @(posedge clk);
@(posedge clk)
instruction = {`MOVQ,`MEM2MMX,`MMX0,`COEFADDR};
repeat (6) @(posedge clk);
@(posedge clk)
instruction = {`PXOR,`MMX2MMX,`MMX4,`MMX4};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PMADDWD,`MEM2MMX,`MMX0,`DATAADDR};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`MOVQ,`MEM2MMX,`MMX1,(`COEFADDR + `HIGH_COEF)};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PMADDWD,`MEM2MMX,`MMX1,(`DATAADDR + `HIGH_COEF)};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`MOVQ,`MEM2MEM,(`DATAADDR+`HIGH_COEF+6'b1),(`DATAADDR+`HIGH_COEF)};
repeat (6) @(posedge clk);
for (i= `HIGH_COEF - 6'b1; i>0; i=i-6'b100)
begin
@(posedge clk)
instruction={`MOVQ,`MEM2MMX,`MMX2,(`COEFADDR + i)};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PSRAD,`MEM2MMX,`MMX0,`NUMBERSHIFT};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PMADDWD,`MEM2MMX,`MMX2,(`DATAADDR + i)};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PADDD,`MMX2MMX,`MMX4,`MMX0};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`MOVQ,`MEM2MEM,(`DATAADDR + i + 6'b1),(`DATAADDR + i)};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`MOVQ,`MEM2MMX,`MMX3,(`COEFADDR + i -6'b1)};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PSRAD,`MEM2MMX,`MMX1,`NUMBERSHIFT};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PMADDWD,`MEM2MMX,`MMX3,(`DATAADDR + i- 6'b1)};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PADDD,`MMX2MMX,`MMX4,`MMX1};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`MOVQ,`MEM2MEM,(`DATAADDR + i ),(`DATAADDR + i- 6'b1 )};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`MOVQ,`MEM2MMX,`MMX0,(`COEFADDR + i -6'd2)};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PSRAD,`MEM2MMX,`MMX2,`NUMBERSHIFT};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PMADDWD,`MEM2MMX,`MMX0,(`DATAADDR + i-6'd2)};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PADDD,`MMX2MMX,`MMX4,`MMX2};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`MOVQ,`MEM2MEM,(`DATAADDR + i - 6'd1),(`DATAADDR + i-6'd2)};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`MOVQ,`MEM2MMX,`MMX1,(`COEFADDR + i -6'd3)};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PSRAD,`MEM2MMX,`MMX3,`NUMBERSHIFT};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PMADDWD,`MEM2MMX,`MMX1,(`DATAADDR + i-6'd3)};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PADDD,`MMX2MMX,`MMX4,`MMX3};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`MOVQ,`MEM2MEM,(`DATAADDR + i - 6'd2),(`DATAADDR + i-6'd3)};
repeat (6) @(posedge clk);
end/*end of the for loop*/
@(posedge clk)
instruction={`PSRAD,`MEM2MMX,`MMX0,`NUMBERSHIFT};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PADDD,`MMX2MMX,`MMX4,`MMX0};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`MOVQ,`MEM2MEM,(`DATAADDR + 6'd1),`DATAADDR };
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PSRAD,`MEM2MMX,`MMX1,`NUMBERSHIFT};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PADDD,`MMX2MMX,`MMX4,`MMX1};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PSRAD,`MEM2MMX,`MMX4,`NUMBERSHIFT2};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`PACKSSDW,`MMX2MMX,`MMX4,`MMX4};
repeat (6) @(posedge clk);
@(posedge clk)
instruction={`MOVQ,`MMX2MEM,(`OUTPUT + L),`MMX4};
repeat (6) @(posedge clk);
L = L + 6'b1;
end /* end of while loop */
end
initial begin
$cw_display(clk);
$cw_display(reset);
$cw_display(instruction);
#38700 $finish;
end
endmodule