aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md6
-rw-r--r--hdl/mips_system.v31
-rw-r--r--hdl/rot_ctrl.v126
-rw-r--r--hdl/testbench.v7
-rw-r--r--hdl/wb_rot_ctrl.v69
-rw-r--r--hdl/wb_rot_ctrl_testbench.v82
-rw-r--r--hdl/wb_slave_ctrl.v76
-rw-r--r--hdl/wb_slave_ctrl_testbench.v90
-rw-r--r--sw/test.asm18
9 files changed, 486 insertions, 19 deletions
diff --git a/README.md b/README.md
index e69de29..3c6bd88 100644
--- a/README.md
+++ b/README.md
@@ -0,0 +1,6 @@
+Форк https://github.com/sbikovsky/MIPSLabs.git
+-------------------------------------------------
+
+Лабораторная работа #1 по курсу `Схемотехника ЭВМ`
+
+
diff --git a/hdl/mips_system.v b/hdl/mips_system.v
index d9959b3..7a273dd 100644
--- a/hdl/mips_system.v
+++ b/hdl/mips_system.v
@@ -5,7 +5,8 @@
module mips_system (
input wire clk,
input wire rst,
-
+ input wire rot_a_i,
+ input wire rot_b_i,
output [7:0] led
);
localparam [31:0] instr_addr_high = 32'h000001ff,
@@ -54,8 +55,8 @@ module mips_system (
wire ram_stb_i;
wire ram_ack_o;
wire [2:0] ram_cti_i = 0; // classic cycle
-
- gpio_wb #(gpio_base_addr) gpio_inst(
+
+ wb_rot_ctrl #(gpio_base_addr) wb_rot_ctrl(
// system signals
.clk_i(clk),
@@ -70,10 +71,32 @@ module mips_system (
.cyc_i(gpio_cyc_i),
.stb_i(gpio_stb_i),
.ack_o(gpio_ack_o),
+ .rot_a_i(rot_a_i),
+ .rot_b_i(rot_b_i),
// func signals
- .gpio_o(led)
+ .led_o(led)
);
+
+ /*gpio_wb #(gpio_base_addr) gpio_inst(
+
+ // system signals
+ .clk_i(clk),
+ .rst_i(rst),
+
+ // wb signals
+ .dat_i(gpio_dat_i),
+ .dat_o(gpio_dat_o),
+ .adr_i(gpio_adr_i),
+ .we_i(gpio_we_i),
+ .sel_i(gpio_sel_i),
+ .cyc_i(gpio_cyc_i),
+ .stb_i(gpio_stb_i),
+ .ack_o(gpio_ack_o),
+
+ // func signals
+ .gpio_o(led)
+ );*/
data_ram_wb #(
.addr_high(data_addr_high),
diff --git a/hdl/rot_ctrl.v b/hdl/rot_ctrl.v
new file mode 100644
index 0000000..5bd8fc1
--- /dev/null
+++ b/hdl/rot_ctrl.v
@@ -0,0 +1,126 @@
+`timescale 1ns / 1ps
+
+module debouncer( reset, clk, noisy, clean );
+ input reset, clk, noisy;
+ output clean;
+
+ parameter NDELAY = 1000;
+ parameter NBITS = 20;
+
+ reg [NBITS-1:0] count;
+ reg xnew, clean;
+
+ always @(posedge clk)
+ if (reset) begin
+ xnew <= noisy;
+ clean <= noisy;
+ count <= 0;
+ end
+ else if(noisy != xnew)
+ begin
+ xnew <= noisy;
+ count <= 0;
+ end
+ else if(count == NDELAY)
+ clean <= xnew;
+ else
+ count <= count + 1;
+endmodule
+
+module diff( input clk_i, input rst_i, input sig_i, output reg val_o, output reg oneclk_o );
+ reg last_value;
+
+ always @(posedge clk_i)
+ if( rst_i )
+ begin
+ oneclk_o <= 0;
+ last_value <= 0;
+ val_o <= 0;
+ end
+ else if( last_value != sig_i )
+ begin
+ last_value <= sig_i;
+
+ oneclk_o <= sig_i;
+ val_o <= 1;
+ end
+ else
+ begin
+ oneclk_o <= 0;
+ val_o <= 0;
+ end
+
+endmodule
+
+module rot_ctrl(
+ input clk_i,
+ input rst_i,
+ input rot_a_i,
+ input rot_b_i,
+
+ input[7:0] data_i,
+ input data_val_i,
+
+ input[7:0] step_i,
+ input step_val_i,
+
+ output[7:0] led_o,
+
+ output [7:0] data_o,
+ output [7:0] step_o
+ );
+
+ reg[7:0] data;
+ reg[7:0] step;
+
+ reg stateA;
+ reg stateB;
+
+ assign led_o = data;
+ assign step_o = step;
+ assign data_o = data;
+
+ wire rot_a_clean;
+ wire rot_b_clean;
+
+ debouncer debounceA(rst_i, clk_i, rot_a_i, rot_a_clean);
+ debouncer debounceB(rst_i, clk_i, rot_b_i, rot_b_clean);
+
+ wire rot_a_diff;
+ wire rot_b_diff;
+ wire rot_a_diff_val;
+ wire rot_b_diff_val;
+ diff diffA(clk_i, rst_i, rot_a_clean, rot_a_diff_val, rot_a_diff);
+ diff diffB(clk_i, rst_i, rot_b_clean, rot_b_diff_val, rot_b_diff);
+
+ always @(posedge clk_i)
+ begin
+ if (rot_a_diff_val)
+ stateA <= rot_a_diff;
+ else if (rot_b_diff_val)
+ stateB <= rot_b_diff;
+ end
+
+ always @(posedge clk_i)
+ if( rst_i )
+ step <= 1;
+ else if( step_val_i )
+ step <= step_i;
+
+ always @(posedge clk_i)
+ begin
+ if( rst_i )
+ data <= 0;
+ else if( data_val_i )
+ data <= data_i;
+ else if( rot_a_diff == 1 && stateB == 0 )
+ data <= data + step;
+ if( rot_b_diff == 1 && stateA == 0 )
+ begin
+ if( data < step )
+ data <= 0;
+ else
+ data <= data - step;
+ end
+ end
+endmodule \ No newline at end of file
diff --git a/hdl/testbench.v b/hdl/testbench.v
index fc9d23e..bf0955d 100644
--- a/hdl/testbench.v
+++ b/hdl/testbench.v
@@ -9,12 +9,15 @@ module testbench;
//Outputs
wire [7:0] led;
-
+ wire rot_a_i;
+ wire rot_b_i;
+
//Instantiate the Unit Under Test (UUT)
mips_system uut (
.clk(mips_clk),
.rst(mips_rst),
-
+ .rot_a_i(rot_a_i),
+ .rot_b_i(rot_b_i),
.led(led)
);
diff --git a/hdl/wb_rot_ctrl.v b/hdl/wb_rot_ctrl.v
new file mode 100644
index 0000000..324f591
--- /dev/null
+++ b/hdl/wb_rot_ctrl.v
@@ -0,0 +1,69 @@
+`timescale 1ns / 1ps
+
+module wb_rot_ctrl #(parameter BASE_ADDR = 32'h00000400)(
+ input clk_i,
+ input rst_i,
+
+ // wb signals
+ input [31:0] dat_i,
+ output [31:0] dat_o,
+ input [31:0] adr_i,
+ input we_i,
+ input [3:0] sel_i,
+ input cyc_i,
+ input stb_i,
+ output ack_o,
+
+ input rot_a_i,
+ input rot_b_i,
+ output [7:0] led_o
+);
+
+wire[7:0] data;
+wire data_val;
+wire[7:0] step;
+wire step_val;
+
+wire[7:0] rot_data;
+wire[7:0] rot_step;
+
+wb_slave_ctrl #(BASE_ADDR) wb_slave_ctrl (
+ .wb_clk_i(clk_i),
+ .wb_rst_i(rst_i),
+ .wb_dat_i(dat_i),
+ .wb_adr_i(adr_i),
+ .wb_we_i(we_i),
+ .wb_sel_i(sel_i),
+ .wb_cyc_i(cyc_i),
+ .wb_stb_i(stb_i),
+
+ .wb_dat_o(dat_o),
+ .wb_ack_o(ack_o),
+
+ .data_o(data),
+ .data_val_o(data_val),
+ .step_o(step),
+ .step_val_o(step_val),
+
+ .data_i(rot_data),
+ .step_i(rot_step)
+);
+
+rot_ctrl rot_ctrl(
+ .clk_i(clk_i),
+ .rst_i(rst_i),
+ .rot_a_i(rot_a_i),
+ .rot_b_i(rot_b_i),
+
+ .data_i(data),
+ .data_val_i(data_val),
+ .step_i(step),
+ .step_val_i(step_val),
+
+ .data_o(rot_data),
+ .step_o(rot_step),
+
+ .led_o(led_o)
+);
+
+endmodule
diff --git a/hdl/wb_rot_ctrl_testbench.v b/hdl/wb_rot_ctrl_testbench.v
new file mode 100644
index 0000000..ec43a4b
--- /dev/null
+++ b/hdl/wb_rot_ctrl_testbench.v
@@ -0,0 +1,82 @@
+`timescale 1ns / 1ps
+
+module wb_rot_ctrl_testbench;
+
+ // Inputs
+ reg clk_i;
+ reg rst_i;
+ reg [31:0] dat_i;
+ reg [31:0] adr_i;
+ reg we_i;
+ reg [3:0] sel_i;
+ reg cyc_i;
+ reg stb_i;
+ reg rot_a_i;
+ reg rot_b_i;
+
+ // Outputs
+ wire [31:0] dat_o;
+ wire ack_o;
+ wire [7:0] led;
+
+ // Instantiate the Unit Under Test (UUT)
+ wb_rot_ctrl uut (
+ .clk_i(clk_i),
+ .rst_i(rst_i),
+ .dat_i(dat_i),
+ .dat_o(dat_o),
+ .adr_i(adr_i),
+ .we_i(we_i),
+ .sel_i(sel_i),
+ .cyc_i(cyc_i),
+ .stb_i(stb_i),
+ .ack_o(ack_o),
+ .rot_a_i(rot_a_i),
+ .rot_b_i(rot_b_i),
+ .led(led)
+ );
+
+ initial begin
+ forever begin
+ clk_i = ~clk_i;
+ #100;
+ end
+ end
+
+ initial begin
+ // Initialize Inputs
+ clk_i = 0;
+ rst_i = 0;
+ dat_i = 0;
+ adr_i = 0;
+ we_i = 0;
+ sel_i = 0;
+ cyc_i = 0;
+ stb_i = 0;
+ rot_a_i = 0;
+ rot_b_i = 0;
+
+ // Wait 100 ns for global reset to finish
+ #100;
+
+ rst_i = 1;
+ #100;
+ rst_i = 0;
+
+ #100;
+ cyc_i = 1;
+ stb_i = 1;
+ we_i = 1;
+ adr_i = 1;
+ dat_i = 8'b00001111;
+
+ #100;
+ #100;
+ #100;
+
+ cyc_i = 0;
+ stb_i = 0;
+ end
+
+endmodule
+
diff --git a/hdl/wb_slave_ctrl.v b/hdl/wb_slave_ctrl.v
new file mode 100644
index 0000000..95e5d18
--- /dev/null
+++ b/hdl/wb_slave_ctrl.v
@@ -0,0 +1,76 @@
+`timescale 1ns / 1ps
+
+module wb_slave_ctrl #(parameter BASE_ADDR = 32'h00000400)(
+ input wb_clk_i,
+ input wb_rst_i,
+ input [31:0] wb_dat_i,
+ input [31:0] wb_adr_i,
+ input wb_we_i,
+ input [3:0] wb_sel_i,
+ input wb_cyc_i,
+ input wb_stb_i,
+
+ output reg [31:0] wb_dat_o,
+ output wb_ack_o,
+
+ output reg[7:0] data_o,
+ output reg[7:0] step_o,
+ output reg data_val_o,
+ output reg step_val_o,
+
+ input [7:0] data_i,
+ input [7:0] step_i
+);
+
+ localparam REG_DATA = BASE_ADDR + 0;
+ localparam REG_STEP = BASE_ADDR + 1;
+
+ reg dat_ready = 0;
+
+ assign read_i = wb_cyc_i & wb_stb_i & !wb_we_i;
+ assign write_i = wb_cyc_i & wb_stb_i & wb_we_i;
+
+ assign wb_ack_o = (wb_cyc_i && wb_stb_i) && (data_val_o || step_val_o || dat_ready);
+
+ always @(posedge wb_clk_i)
+ if( write_i && wb_adr_i == REG_DATA )
+ begin
+ data_o <= wb_dat_i;
+ data_val_o <= 1;
+ end
+ else
+ begin
+ data_o <= 0;
+ data_val_o <= 0;
+ end
+
+ always @(posedge wb_clk_i)
+ if( write_i && wb_adr_i == REG_STEP )
+ begin
+ step_o <= wb_dat_i;
+ step_val_o <= 1;
+ end
+ else
+ begin
+ step_o <= 0;
+ step_val_o <= 0;
+ end
+
+ always @(posedge wb_clk_i)
+ if( read_i && wb_adr_i == REG_DATA )
+ begin
+ wb_dat_o <= data_i;
+ dat_ready <= 1;
+ end
+ else if( read_i && wb_adr_i == REG_STEP )
+ begin
+ wb_dat_o <= step_i;
+ dat_ready <= 1;
+ end
+ else
+ begin
+ wb_dat_o <= 0;
+ dat_ready <= 0;
+ end
+
+endmodule
diff --git a/hdl/wb_slave_ctrl_testbench.v b/hdl/wb_slave_ctrl_testbench.v
new file mode 100644
index 0000000..36640fd
--- /dev/null
+++ b/hdl/wb_slave_ctrl_testbench.v
@@ -0,0 +1,90 @@
+`timescale 1ns / 1ps
+
+module wb_slave_ctrl_testbench;
+
+ // Inputs
+ reg wb_clk_i;
+ reg wb_rst_i;
+ reg [31:0] wb_dat_i;
+ reg [4:0] wb_adr_i;
+ reg wb_we_i;
+ reg [3:0] wb_sel_i;
+ reg wb_cyc_i;
+ reg wb_stb_i;
+ reg [7:0] data_i;
+ reg [7:0] step_i;
+
+ // Outputs
+ wire [31:0] wb_dat_o;
+ wire wb_ack_o;
+ wire [7:0] data_o;
+ wire [7:0] step_o;
+ wire data_val_o;
+ wire step_val_o;
+
+ // Instantiate the Unit Under Test (UUT)
+ wb_slave_ctrl uut (
+ .wb_clk_i(wb_clk_i),
+ .wb_rst_i(wb_rst_i),
+ .wb_dat_i(wb_dat_i),
+ .wb_adr_i(wb_adr_i),
+ .wb_we_i(wb_we_i),
+ .wb_sel_i(wb_sel_i),
+ .wb_cyc_i(wb_cyc_i),
+ .wb_stb_i(wb_stb_i),
+ .wb_dat_o(wb_dat_o),
+ .wb_ack_o(wb_ack_o),
+ .data_o(data_o),
+ .step_o(step_o),
+ .data_val_o(data_val_o),
+ .step_val_o(step_val_o),
+ .data_i(data_i),
+ .step_i(step_i)
+ );
+
+ initial begin
+ forever begin
+ wb_clk_i = ~wb_clk_i;
+ #100;
+ end
+ end
+
+
+ initial begin
+ // Initialize Inputs
+ wb_clk_i = 0;
+ wb_rst_i = 0;
+ wb_dat_i = 0;
+ wb_adr_i = 0;
+ wb_we_i = 0;
+ wb_sel_i = 0;
+ wb_cyc_i = 0;
+ wb_stb_i = 0;
+ data_i = 0;
+ step_i = 0;
+
+ // Wait 100 ns for global reset to finish
+ #100;
+
+ wb_rst_i = 1;
+ #100;
+ wb_rst_i = 0;
+
+ #100;
+ data_i = 8'b00001111;
+ step_i = 8'b00001010;
+ wb_cyc_i = 1;
+ wb_stb_i = 1;
+ wb_we_i = 0;
+ wb_adr_i = 1;
+
+ #100;
+ #100;
+ #100;
+
+ wb_cyc_i = 0;
+ wb_stb_i = 0;
+ end
+
+endmodule
+
diff --git a/sw/test.asm b/sw/test.asm
index eac3c7e..a77f76e 100644
--- a/sw/test.asm
+++ b/sw/test.asm
@@ -1,20 +1,12 @@
.global entry
.data /* data section*/
- .word 0x0001
- .word 0x0002
- .word 0xFFFF
+ .word 0x00AF
+ .word 0x0400
.text /* code goes to text section*/
.ent entry
entry:
- lw $t0, 0x200 /* t0 = 1*/
- lw $t1, 0x201 /* t1 = 1*/
- add $t0, $t0, $t1 /* t0 = t0 + t1 = 2*/
- add $t0, $t0, 0xB /* t0 = t0 + 0xB == 0xD*/
- sub $t0, $t0, $t1 /* t0 = t0 - $t1 == 0xC*/
- or $t0, $t0, 0x10 /* t0 = t0 | 0x10 == 0x1C*/
- xor $t0, $t0, $t1 /* t0 = t0 ^ t1 == 0x1D*/
- slt $t0, $t0, $t1 /* t0 = t0 < t1 == 0*/
- add $t0, $t0, $t1 /* t0 = t0 + t1 == 1*/
- beq $t0, $t1, entry /* PC = entry if t0 == t1*/
+ lw $t2, 0x200
+ lw $t0, 0x201
+ sw $t2, ($t0)
.end entry