Преглед изворни кода

Approach fixing the overlapped mailbox registers with code and bootloader.

Signed-off-by: Jakub Duchniewicz <j.duchniewicz@gmail.com>
Jakub Duchniewicz пре 2 недеља
родитељ
комит
03fbd5a395

+ 48 - 1
projects/riscv_usb/fw/fw_app.c

@@ -37,6 +37,11 @@
 
 extern const struct usb_stack_descriptors app_stack_desc;
 
+/*
+double dupa;
+float kupa;
+*/
+
 static void
 serial_no_init()
 {
@@ -52,6 +57,16 @@ serial_no_init()
 
     // Print Mailbox contents just to be sure */
     printf("Mailbox period1: %d\n", mailbox_regs->regs.period1);
+    printf("Mailbox delay1: %d\n", mailbox_regs->regs.delay1);
+
+    /* Testing floats TODO: test if calculation is correct
+    dupa = 3.1415;
+    kupa = 2.74f;
+
+    dupa *= kupa;
+
+    printf("Pi * e: %.3f\n", dupa);
+    */
 
 	/* Overwrite descriptor string */
 		/* In theory in rodata ... but nothing is ro here */
@@ -75,13 +90,36 @@ static void write_period1_2()
     printf("Done writing\n");
 }
 
+static void write_period1_4()
+{
+    printf("Writing period1 0x4\n");
+    mailbox_regs->regs.period1 = 0x3;
+    printf("Done writing\n");
+    printf("Reading now \n");
+    printf("value: %d\n", mailbox_regs->regs.period1);
+}
+
 static void clear_period1()
 {
-    printf("Clearing period1 current val: %d\n", mailbox_regs->regs.period1);
+    printf("Clearing period1 val: %d\n", mailbox_regs->regs.period1);
     mailbox_regs->regs.period1 = 0x0;
     printf("Done clearing\n");
 }
 
+static void write_delay1()
+{
+    printf("Writing delay1 0x1\n");
+    mailbox_regs->regs.delay1 = 0x1;
+    printf("Done writing\n");
+}
+
+static void clear_delay1()
+{
+    printf("Clearing delay1 val: %d\n", mailbox_regs->regs.delay1);
+    mailbox_regs->regs.delay1 = 0x0;
+    printf("Done clearing\n");
+}
+
 static void
 boot_dfu(void)
 {
@@ -162,6 +200,15 @@ void main()
             case 'a':
                 write_period1_2();
                 break;
+            case 's':
+                write_period1_4();
+                break;
+            //case 'o':
+            //    write_delay1();
+            //    break;
+            //case 'm':
+            //    clear_delay1();
+            //    break;
 			default:
 				break;
 			}

+ 10 - 10
projects/riscv_usb/fw/registers.h

@@ -7,21 +7,21 @@
 #include "config.h"
 
 typedef struct {
-    uint16_t period1;
-    uint16_t delay1;
-    uint16_t duty2;
-    uint16_t delay2;
-    uint16_t duty3;
-    uint16_t delay3;
-    uint16_t npuls3;
-    uint16_t odd_train_flag;
-    uint16_t ena_odd_out3;
+    uint32_t period1;
+    uint32_t delay1;
+    uint32_t duty2;
+    uint32_t delay2;
+    uint32_t duty3;
+    uint32_t delay3;
+    uint32_t npuls3;
+    uint32_t odd_train_flag;
+    uint32_t ena_odd_out3;
     uint64_t reserved;
 } three_signal_regs_t __attribute__((packed,aligned(4)));
 
 typedef struct {
     union {
-        uint16_t data[16];
+        uint32_t data[16];
         three_signal_regs_t regs;
     };
 } wb_mailbox_regs_t __attribute__((packed,aligned(4)));

+ 48 - 42
projects/riscv_usb/rtl/mailbox_wb.v

@@ -24,7 +24,7 @@ module mailbox_wb #(
     output reg              wb_ack,
 
     // Flattened custom hardware side (RTL)
-    output wire [16*DW-1:0]     registers_flat  // Flattened register array (16 registers of 16 bits each)
+    output wire [16*16-1:0]     registers_flat  // Flattened register array (16 registers of 16 bits each)
 );
 
     // Internal registers (16 registers, each 16 bits wide)
@@ -39,51 +39,57 @@ module mailbox_wb #(
                 registers_array[i] <= 16'h0; // Reset all registers to 0
             end
         end else begin
-            // Handle Wishbone communication
-            wb_ack <= wb_cyc;
+            // Default no ack
+            wb_ack <= 1'b0;
+
+            if (wb_cyc) begin
+                // Write operation (if write enable is active) // wb_stb would
+                // help here
+                if (wb_we) begin
+                    case (wb_addr)
+                        4'b0000: registers_array[0] <= wb_wdata[15:0]; // Only use lower 16 bits
+                        4'b0001: registers_array[1] <= wb_wdata[15:0];
+                        4'b0010: registers_array[2] <= wb_wdata[15:0];
+                        4'b0011: registers_array[3] <= wb_wdata[15:0];
+                        4'b0100: registers_array[4] <= wb_wdata[15:0];
+                        4'b0101: registers_array[5] <= wb_wdata[15:0];
+                        4'b0110: registers_array[6] <= wb_wdata[15:0];
+                        4'b0111: registers_array[7] <= wb_wdata[15:0];
+                        4'b1000: registers_array[8] <= wb_wdata[15:0];
+                        4'b1001: registers_array[9] <= wb_wdata[15:0];
+                        4'b1010: registers_array[10] <= wb_wdata[15:0];
+                        4'b1011: registers_array[11] <= wb_wdata[15:0];
+                        4'b1100: registers_array[12] <= wb_wdata[15:0];
+                        4'b1101: registers_array[13] <= wb_wdata[15:0];
+                        4'b1110: registers_array[14] <= wb_wdata[15:0];
+                        4'b1111: registers_array[15] <= wb_wdata[15:0];
+                    endcase
+                end
 
-            // Write operation (if write enable is active)
-            if (wb_we && wb_cyc) begin
+                // Read operation (read the correct register based on address)
                 case (wb_addr)
-                    4'b0000: registers_array[0] <= wb_wdata[15:0]; // Only use lower 16 bits
-                    4'b0001: registers_array[1] <= wb_wdata[15:0];
-                    4'b0010: registers_array[2] <= wb_wdata[15:0];
-                    4'b0011: registers_array[3] <= wb_wdata[15:0];
-                    4'b0100: registers_array[4] <= wb_wdata[15:0];
-                    4'b0101: registers_array[5] <= wb_wdata[15:0];
-                    4'b0110: registers_array[6] <= wb_wdata[15:0];
-                    4'b0111: registers_array[7] <= wb_wdata[15:0];
-                    4'b1000: registers_array[8] <= wb_wdata[15:0];
-                    4'b1001: registers_array[9] <= wb_wdata[15:0];
-                    4'b1010: registers_array[10] <= wb_wdata[15:0];
-                    4'b1011: registers_array[11] <= wb_wdata[15:0];
-                    4'b1100: registers_array[12] <= wb_wdata[15:0];
-                    4'b1101: registers_array[13] <= wb_wdata[15:0];
-                    4'b1110: registers_array[14] <= wb_wdata[15:0];
-                    4'b1111: registers_array[15] <= wb_wdata[15:0];
+                    4'b0000: wb_rdata <= {16'h0, registers_array[0]}; // Place 16-bit value in lower half of 32-bit bus
+                    4'b0001: wb_rdata <= {16'h0, registers_array[1]};
+                    4'b0010: wb_rdata <= {16'h0, registers_array[2]};
+                    4'b0011: wb_rdata <= {16'h0, registers_array[3]};
+                    4'b0100: wb_rdata <= {16'h0, registers_array[4]};
+                    4'b0101: wb_rdata <= {16'h0, registers_array[5]};
+                    4'b0110: wb_rdata <= {16'h0, registers_array[6]};
+                    4'b0111: wb_rdata <= {16'h0, registers_array[7]};
+                    4'b1000: wb_rdata <= {16'h0, registers_array[8]};
+                    4'b1001: wb_rdata <= {16'h0, registers_array[9]};
+                    4'b1010: wb_rdata <= {16'h0, registers_array[10]};
+                    4'b1011: wb_rdata <= {16'h0, registers_array[11]};
+                    4'b1100: wb_rdata <= {16'h0, registers_array[12]};
+                    4'b1101: wb_rdata <= {16'h0, registers_array[13]};
+                    4'b1110: wb_rdata <= {16'h0, registers_array[14]};
+                    4'b1111: wb_rdata <= {16'h0, registers_array[15]};
+                    default: wb_rdata <= 32'hDEAD_BEEF; // Default error value
                 endcase
-            end
 
-            // Read operation (read the correct register based on address)
-            case (wb_addr)
-                4'b0000: wb_rdata <= {16'h0, registers_array[0]}; // Place 16-bit value in lower half of 32-bit bus
-                4'b0001: wb_rdata <= {16'h0, registers_array[1]};
-                4'b0010: wb_rdata <= {16'h0, registers_array[2]};
-                4'b0011: wb_rdata <= {16'h0, registers_array[3]};
-                4'b0100: wb_rdata <= {16'h0, registers_array[4]};
-                4'b0101: wb_rdata <= {16'h0, registers_array[5]};
-                4'b0110: wb_rdata <= {16'h0, registers_array[6]};
-                4'b0111: wb_rdata <= {16'h0, registers_array[7]};
-                4'b1000: wb_rdata <= {16'h0, registers_array[8]};
-                4'b1001: wb_rdata <= {16'h0, registers_array[9]};
-                4'b1010: wb_rdata <= {16'h0, registers_array[10]};
-                4'b1011: wb_rdata <= {16'h0, registers_array[11]};
-                4'b1100: wb_rdata <= {16'h0, registers_array[12]};
-                4'b1101: wb_rdata <= {16'h0, registers_array[13]};
-                4'b1110: wb_rdata <= {16'h0, registers_array[14]};
-                4'b1111: wb_rdata <= {16'h0, registers_array[15]};
-                default: wb_rdata <= 32'hDEAD_BEEF; // Default error value
-            endcase
+                // Acknowledge for exactly 1 cycle
+                wb_ack <= 1'b1;
+            end
         end
     end
 

+ 47 - 17
projects/riscv_usb/rtl/top.v

@@ -99,7 +99,7 @@ module top (
     wire ena_odd_out3;
 
 	// Mailbox signal wires
-    wire [16*WB_DW-1:0] mailbox_regs_flat;  // Flattened register array (16 registers of 16 bits each)
+    wire [16*16-1:0] mailbox_regs_flat;  // Flattened register array (16 registers of 16 bits each)
 
 	// SoC
 	// ---
@@ -223,11 +223,11 @@ module top (
 	// ----------
 	mailbox_wb #(
 		.AW(4),
-		.DW(32)
+		.DW(WB_DW)
 	) mailbox_I (
-		.clk(clk_48m),
+		.clk(clk_24m),
 		.rst(rst),
-		.wb_addr(wb_addr[4-1:0]),
+		.wb_addr(wb_addr[5:2]), // use word instead of byte addressing
 		.wb_wdata(wb_wdata),
 		.wb_rdata(wb_rdata[6]),
 		.wb_we(wb_we),
@@ -238,17 +238,16 @@ module top (
 
     // 3 Signal
     // --------
-    assign period1 = mailbox_regs_flat[15:0];
-	// TODO: rest of assignments
-    //wire [SLOW_PWM_WIDTH-1:0] delay1;
-    //wire [SLOW_PWM_WIDTH-1:0] duty2;
-    //wire [SLOW_PWM_WIDTH-1:0] delay2;
-    //wire [FAST_PWM_WIDTH-1:0] period3;
-    //wire [FAST_PWM_WIDTH-1:0] duty3;
-    //wire [SLOW_PWM_WIDTH-1:0] delay3;
-    //wire [PULSE_COUNTER_WIDTH-1:0] npuls3;
-    //wire [1:0] odd_train_flag;
-    //wire ena_odd_out3;
+    assign period1 = mailbox_regs_flat[15:0];        // First 16 bits for period1
+    assign delay1 = mailbox_regs_flat[31:16];        // Next 16 bits for delay1
+    assign duty2 = mailbox_regs_flat[47:32];         // Next 16 bits for duty2
+    assign delay2 = mailbox_regs_flat[63:48];        // Next 16 bits for delay2
+    assign period3 = mailbox_regs_flat[79:64];       // Next 16 bits for period3
+    assign duty3 = mailbox_regs_flat[95:80];         // Next 16 bits for duty3
+    assign delay3 = mailbox_regs_flat[111:96];       // Next 16 bits for delay3
+    assign npuls3 = mailbox_regs_flat[127:112];      // Next 16 bits for npuls3
+    assign odd_train_flag = mailbox_regs_flat[143:128]; // Next 16 bits for odd_train_flag
+    assign ena_odd_out3 = mailbox_regs_flat[159:144]; // Next 16 bits for ena_odd_out3
 
     three_signal #(
         .FAST_PWM_WIDTH(FAST_PWM_WIDTH),
@@ -256,7 +255,7 @@ module top (
         .SLOW_PWM_WIDTH(SLOW_PWM_WIDTH)
     ) three_signal_I(
         .nrst(~rst),
-        .clk(clk_48m),
+        .clk(clk_24m), // TODO: fix later we have CDC problem here
         .period1(period1),
         .delay1(delay1),
         .duty2(duty2),
@@ -273,21 +272,52 @@ module top (
     );
 
     // TODO: dummy led onoff when value has been written
-    always @(posedge clk_48m or posedge rst)
+    always @(posedge clk_24m or posedge rst)
         if (rst) begin
             led[0] = 1'b0;
             led[1] = 1'b0;
+            led[2] = 1'b0;
         end else if (period1 == 1) begin
             led[0] = 1'b1;
             led[1] = 1'b0;
+            led[2] = 1'b0;
         end else if (period1 == 2) begin
             led[0] = 1'b0;
             led[1] = 1'b1;
+            led[2] = 1'b0;
+        //end else if (period1 == 3) begin
+        //    led[0] = 1'b0;
+        //    led[1] = 1'b0;
+        //    led[2] = 1'b1;
+        //end else if (period1 != 0) begin
+        //    led[0] = 1'b1;
+        //    led[1] = 1'b1;
+        //    led[2] = 1'b0;
         end else begin
             led[0] = 1'b0;
             led[1] = 1'b0;
+            led[2] = 1'b0;
         end
 
+    //// TODO: dummy driving from delay1
+    //always @(posedge clk_48m or posedge rst)
+    //    if (rst) begin
+    //        led[2] = 1'b0;
+    //    end else if (delay1 != 0) begin
+    //        led[2] = 1'b1;
+    //    end else begin
+    //        led[2] = 1'b0;
+    //    end
+
+    //always @(posedge clk_48m or posedge rst)
+    //    if (rst) begin
+    //        led[3] = 1'b0;
+    //    end else if (delay2 != 0) begin
+    //        led[3] = 1'b1;
+    //    end else begin
+    //        led[3] = 1'b0;
+    //    end
+
 	// Warm Boot
 	// ---------